Python实现五子棋

  • 标记位
  • 思路
  • 代码
  • 效果图
  • AI策略
  • 一点修正
  • 总结



摘要:


本文主要是针对之前写过的

五子棋一文中的人机进行补充和说明。


补充和说明为两个点

  • 标记位
  • AI策略

标记位

由于AI下棋实在太快了,当棋子数目增多,就不知道AI到底是下的哪了,所以对AI每次下棋时都增加如下图所示的标记号。

python 五子棋界面 python五子棋ai_python 五子棋界面

思路

最开始想的是画两种棋子,

  1. 第一颗棋子,标记,并记录
  2. 第二颗棋子,重新画第一颗棋子,第二颗棋子标记
    依次重复以上过程,后面是实现起来也不知道是哪不对,然后就没继续了。

其实上一种思路也对,只不过没弄清楚pygame刷新以及物体移动的原理,over.
之后无意看到Pygame的图像移动这篇博客,有所启发。

# 移动图像,根据上下左右的按键,改变speed,然后移动
    position = position.move(1,0)
    # 填充背景
    screen.fill(bg)
    # 放置图片在移动后的位置,如果没有移动,就在初始位置。
    screen.blit(img1, [0,100])
    # 更新界面
    pygame.display.flip()

以上这段代码,关键一句为填充背景 screen.fill(bg),当这句注释掉后,按左右键进行移动图片时会发现,能够看到移动轨迹。

python 五子棋界面 python五子棋ai_pygame_02


所以能让一张图片动起来,其实是不断的背景覆盖,让我们看不到之前的运动轨迹,感觉始终都是一张图片在动。

五子棋下棋也是同一个原理。所以只需要当AI下棋时记录此时的位置,当重新绘制棋子的时候,如果是当前下的棋子,就把标记位加上即可。同时只是针对AI下棋才标记,人下棋就不需要标记了,令flag=0,当遇到AI下棋则标记为1.

代码

  1. 在人机对战处195行之后定义flag.
AI_x = 0 #记录当前AI的x,y
AI_y = 0
flag = 0
  1. 在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)
  1. 在绘制棋子部分,加上判断
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)
  1. 绘制标记位
# 加载标记位图片
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])

效果图

python 五子棋界面 python五子棋ai_加载_03

python 五子棋界面 python五子棋ai_ci_04

AI策略

AI策略,依据主要是一个评分表,这个评分表是根据前人经验所总结,基本上网上都能找到。

一点修正

python 五子棋界面 python五子棋ai_ci_05

在修改的同时,发现在实现主界面模块部分的第30句代码多了一个人人对战,这句应该删除的,应该是因为这段代码本身就先执行了人机对战,所以影响不是很大,但还是应该删除第30句代码。

总结

此段代码对于AI默认是黑棋,所以增加标记位也就只是黑棋标记。
同时,这个五子棋游戏,人机对战只能电脑后手,因为AI策略需要根据人下棋的位置通过评分表进行判断下一步走哪,这个地方还有待优化。