摘要:
本文主要是针对之前写过的
五子棋一文中的人机进行补充和说明。
补充和说明为两个点
标记位
由于AI下棋实在太快了,当棋子数目增多,就不知道AI到底是下的哪了,所以对AI每次下棋时都增加如下图所示的标记号。
思路
最开始想的是画两种棋子,
- 第一颗棋子,标记,并记录
- 第二颗棋子,重新画第一颗棋子,第二颗棋子标记
依次重复以上过程,后面是实现起来也不知道是哪不对,然后就没继续了。
其实上一种思路也对,只不过没弄清楚pygame刷新以及物体移动的原理,over. 之后无意看到Pygame的图像移动这篇博客,有所启发。
position = position.move(1,0)
screen.fill(bg)
screen.blit(img1, [0,100])
pygame.display.flip()
以上这段代码,关键一句为填充背景 screen.fill(bg),当这句注释掉后,按左右键进行移动图片时会发现,能够看到移动轨迹。 所以能让一张图片动起来,其实是不断的背景覆盖,让我们看不到之前的运动轨迹,感觉始终都是一张图片在动。
五子棋下棋也是同一个原理。所以只需要当AI下棋时记录此时的位置,当重新绘制棋子的时候,如果是当前下的棋子,就把标记位加上即可。同时只是针对AI下棋才标记,人下棋就不需要标记了,令flag=0,当遇到AI下棋则标记为1.
代码
- 在人机对战处195行之后定义flag.
AI_x = 0
AI_y = 0
flag = 0
- 在207行,213行后进行标记。
if click_point is not None:
if checkerboard.can_drop(click_point):
flag = 0
winner = checkerboard.drop(cur_runner, click_point)
if winner is None:
cur_runner = _get_next(cur_runner)
computer.get_opponent_drop(click_point)
AI_point = computer.AI_drop()
flag = 1
AI_x, AI_y = AI_point[0], AI_point[1]
winner = checkerboard.drop(cur_runner, AI_point)
if winner is not None:
white_win_count += 1
cur_runner = _get_next(cur_runner)
- 在绘制棋子部分,加上判断
for i, row in enumerate(checkerboard.checkerboard):
for j, cell in enumerate(row):
if cell == BLACK_CHESSMAN.Value:
if j == AI_x and i == AI_y:
flag = 1
else:
flag = 0
_draw_chessman(screen, Point(j, i), BLACK_CHESSMAN.Color, flag)
elif cell == WHITE_CHESSMAN.Value:
_draw_chessman(screen, Point(j, i), WHITE_CHESSMAN.Color, 0)
- 绘制标记位
image = pygame.image.load("timg.png")
def _draw_chessman(screen, point, stone_color,flag):
pygame.gfxdraw.aacircle(screen, 26 + 30 * point.X, 26 + 30 * point.Y, Stone_Radius, stone_color)
pygame.gfxdraw.filled_circle(screen, 26 + 30 * point.X, 26 + 30 * point.Y, Stone_Radius, stone_color)
if flag:
screen.blit(image, [16 + 30 * point.X, 10 + 30 * point.Y])
效果图
AI策略
AI策略,依据主要是一个评分表,这个评分表是根据前人经验所总结,基本上网上都能找到。
一点修正
在修改的同时,发现在实现主界面模块部分的第30句代码多了一个人人对战,这句应该删除的,应该是因为这段代码本身就先执行了人机对战,所以影响不是很大,但还是应该删除第30句代码。
总结
此段代码对于AI默认是黑棋,所以增加标记位也就只是黑棋标记。 同时,这个五子棋游戏,人机对战只能电脑后手,因为AI策略需要根据人下棋的位置通过评分表进行判断下一步走哪,这个地方还有待优化。
|