Python实现五子棋
- 标记位
- 思路
- 代码
- 效果图
- AI策略
- 一点修正
- 总结
摘要:
本文主要是针对之前写过的
五子棋一文中的人机进行补充和说明。
补充和说明为两个点
- 标记位
- AI策略
标记位
由于AI下棋实在太快了,当棋子数目增多,就不知道AI到底是下的哪了,所以对AI每次下棋时都增加如下图所示的标记号。
思路
最开始想的是画两种棋子,
- 第一颗棋子,标记,并记录
- 第二颗棋子,重新画第一颗棋子,第二颗棋子标记
依次重复以上过程,后面是实现起来也不知道是哪不对,然后就没继续了。
其实上一种思路也对,只不过没弄清楚pygame刷新以及物体移动的原理,over.
之后无意看到Pygame的图像移动这篇博客,有所启发。
# 移动图像,根据上下左右的按键,改变speed,然后移动
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的x,y
AI_y = 0
flag = 0
- 在207行,213行后进行标记。
if click_point is not None: # 检测鼠标是否在棋盘内点击
if checkerboard.can_drop(click_point): #玩家落子
flag = 0
#mouse_x,mouse_y = mouse_pos[0],mouse_pos[1]
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
# print(j,AI_x,i,AI_y,flag)
_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策略需要根据人下棋的位置通过评分表进行判断下一步走哪,这个地方还有待优化。