300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Python实现五子棋人机对战 | CSDN博文精选

Python实现五子棋人机对战 | CSDN博文精选

时间:2022-12-18 07:55:12

相关推荐

Python实现五子棋人机对战 | CSDN博文精选

作者 | 吴小鹏

来源 | 数据札记倌(ID:Data_Groom)

五子棋是常见的一款小游戏,五子棋问题是人工智能中的一个经典问题。这篇文章主要介绍了Python版本五子棋的实现代码,大家可以做个参考,与我的傻儿子对弈一下。

简 述

虽然计算机已经几乎破解了五子棋的取胜秘籍,甚至给出了取胜的具体方案,然而,对人来说,五子棋还是非常有玩头的。

我们往往有五子棋的技巧性和全局观远远比不上象棋,围棋之类的感觉:

这个真不一定,先说技巧性:五子棋、象棋、围棋的最初级技巧都是死活题。围棋那高难度的生死题我就不多说了。而象棋如果只是说铁门栓天地炮等等杀法,其实还是很好掌握的;如果加上各种基础的残局估计差不多。五子棋的话,坂田三手胜与天狗道场,或者是贴吧里边各种变态杀法题,也不敢说简单。

扯远啦~,这篇文章主要是要用python来实现五子棋的人机对战,可以趣味性地玩一下,远没有到不可战胜的程度。

问题描述

人机对弈算法属于策略型人工智能算法,本游戏中设置了人机对弈的游戏模式,整个程序我们有几个大的问题需要解决:

1)、计算机需要判断胜负

2)、计算机落子的逻辑

第一个问题的核心思想是要设置对局结束的判断逻辑,在这部分我们只需要写出五子相连的判断条件;

第二个问题的核心思想是要比较不同落子的优劣势,需要评估每一步的胜算。

其算法如下:

写出获胜逻辑或者设置所有获胜组合

获胜逻辑:一个二维坐标上,判断上下、左右、两个45度直线,是否有五个相同的直连棋子。

评估棋格获胜分数

在计算机下棋之前,会计算空白棋格上的获胜分数,根据分数高低获取最佳位置。计算机会将棋子下在获胜分数最高的地方。

当已放置4颗棋子时,必须在第五个空棋格上设置绝对高的分值。

当获胜组合上有部分位置已被对手的棋格占据而无法连成五子时,获胜组合上空棋格的获胜分数会直接设置为0。

当有两组及其以上的获胜组合位置交叉时,对该位置的分数进行叠加,形成分数比周围位置明显高。

计算机的攻击与防守

计算机计算获胜分值越高的棋格,就能确定能让自己的棋子最有可能达成联机的位置,也就是最佳进攻位置,而一旦计算机能确定自己的最高分值的位置,计算机就具备了进攻能力。同理,计算机能计算出玩家的最大分值位置,并抢先玩家获得该位置,这样计算机就具有了防御的能力。

代码实现

棋盘

棋盘是我们整个游戏的落子范围,需要提前定义好大小:

#画棋盘

defGobangWin():

gw=GraphWin('AIGobang',GRID_WIDTH*COLUMN,GRID_WIDTH*ROW)

gw.setBackground('gray')

forjinrange(0,GRID_WIDTH*COLUMN+1,GRID_WIDTH):

l=Line(Point(j,0),Point(j,GRID_WIDTH*COLUMN))

l.draw(gw)

foriinrange(0,GRID_WIDTH*ROW+1,GRID_WIDTH):

l=Line(Point(0,i),Point(GRID_WIDTH*ROW,i))

l.draw(gw)

returngw

棋子

在棋盘上画一个棋子:

col=(255,0,0)

surf.fill((255,255,255))

pygame.gfxdraw.aacircle(surf,x,y,30,col)

pygame.gfxdraw.filled_circle(surf,x,y,30,col)

落子

通过鼠标点击的位置记录落子,这里核心是要实现的点击鼠标获取坐标,可以使用Graphics。

fromgraphicsimport*

#设置画布窗口名和尺寸

win=GraphWin('hehe',666,666)

#关闭画布窗口

win.getMouse()

win.close()

#画点

pt=Point(100,100)

pt.draw(win)

#画圆

cir=Circle(Point(200,200),75)

cir.draw(win)

cir.setOutline('red')#外围轮廓颜色

cir.setFill('yellow')#填充颜色

#画线

line=Line(Point(650,100),Point(250,100))

line.draw(win)

#画矩形

rect=Rectangle(Point(300,300),Point(400,400))

rect.setFill('red')#填充颜色

rect.draw(win)

#画椭圆

oval=Oval(Point(450,450),Point(600,600))

oval.setFill('red')#填充颜色

oval.draw(win)

#显示文字

message=Text(Point(win.getWidth()/2,20),'Clickanywheretoquit.')

message.draw(win)

判断输赢

一个二维坐标上,判断上下、左右、两个45度直线,是否有五个相同的直连棋子,只要五子相连则游戏结束。或者遍历每一种获胜情况都可以做出判断:

#四种情况

defis_GameOver(list_now):

forcinrange(COLUMN):

forrinrange(ROW):

ifr<ROW-4and(r,c)inlist_nowand(r+1,c)inlist_nowand(r+2,c)inlist_nowand(r+3,c)inlist_nowand(r+4,c)inlist_now:

returnTrue

elifc<COLUMN-4and(r,c)inlist_nowand(r,c+1)inlist_nowand(r,c+2)inlist_nowand(r,c+3)inlist_nowand(r,c+4)inlist_now:

returnTrue

elifr<ROW-4andc<COLUMN-4and(r,c)inlist_nowand(r+1,c+1)inlist_nowand(r+2,c+2)inlist_nowand(r+3,c+3)inlist_nowand(r+4,c+4)inlist_now:

returnTrue

elifr>3andc<COLUMN-4and(r,c)inlist_nowand(r-1,c+1)inlist_nowand(r-2,c+2)inlist_nowand(r-3,c+3)inlist_nowand(r-4,c+4)inlist_now:

returnTrue

returnFalse

演示操作

下面直接看一下实际操作结果吧~

这里执行起来还是挺慢的,在执行逻辑的判断方面还有很多可以优化的地方。

呼~,傻儿子玩得还不错,还好赢了~

代码下载地址:

/s/16aSLqCKXNX1XVAt_cTcV4Q

密码:u7ao

另外这个不是深度学习的实现办法,如果想尝试深度学习方法戳这里:

AlphaZero实战:从零学下五子棋(附代码)

/junxiaosong/AlphaZero_Gomoku

如果你喜欢的话点个再看,让更多人看到~

扫码查看原文▼▼▼

(*本文为AI科技大本营转载文章,转载请联系作者)

精彩推荐

中国大数据技术大会(BDTC)再度来袭!豪华主席阵容及百位技术专家齐聚,15 场精选专题技术和行业论坛,超强干货+技术剖析+行业实践立体解读,深入解析热门技术在行业中的实践落地。6.6 折票限时特惠(立减1400元),学生票仅 599 元!

推荐阅读

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。