python+pygame实现五子棋人机对战之三

python+pygame实现五子棋人机对战之三python pygame 实现五子棋人机对战 讲解五子棋的基本知识和电脑应手的逻辑

大家好,欢迎来到IT知识分享网。

上回讲过:

python+pygame实现五子棋人机对战之一

python+pygame实现五子棋人机对战之二

界面已经有了,并且可以支持鼠标操作选择菜单和人机对战开始下棋了,那电脑是如何应手落子呢?以下内容是通用的类,全部放在utils.py中

四、

最常见的基本棋型大体有以下几种:连五,活四,冲四,活三,眠三,活二,眠二了,下面简要讲解一下:

4.1 连五:五颗同色棋子连在一起python+pygame实现五子棋人机对战之三

4.2 活四:由4枚同色棋子形成的两端没有对方棋子的四枚棋子python+pygame实现五子棋人机对战之三

4.3 冲四一(连四):由4枚同色棋子形成的一端有对方棋子的四枚棋子python+pygame实现五子棋人机对战之三

4.4 冲四二(跳四):由4枚同色棋子形成的中间没有对方棋子的四枚棋子。

python+pygame实现五子棋人机对战之三python+pygame实现五子棋人机对战之三

4.5 眠四:由4枚同色棋子形成的两端有对方棋子的4枚棋子。  不能成五的四连。

相对比活四来说,冲四的威胁性就小了很多,此时,防守方只要跟着防守在那个唯一的连五点上,冲四就没法形成连五。

4.6 活三一(连三):由3枚同色棋子形成连三、跳三。  再走一着可以形成活四的三。 两端都是威胁的活三。简称“连三”。python+pygame实现五子棋人机对战之三

4.7 活三二(跳三):由3枚同色棋子形成的中间没有对方棋子的三枚棋子。中间夹有一个威胁的活三。简称“跳三”。python+pygame实现五子棋人机对战之三

4.8 眠三:由3枚同色棋子形成的两端有对方棋子的3枚棋子。  即再走一着可以形成冲四的三。眠三的形状是很丰富的。眠三的棋型与活三的棋型相比,危险系数下降不少,因为眠三棋型即使不去防守,下一手它也只能形成冲四,而对于单纯的冲四棋型,我们是可以防守住的。

python+pygame实现五子棋人机对战之三python+pygame实现五子棋人机对战之三python+pygame实现五子棋人机对战之三

python+pygame实现五子棋人机对战之三python+pygame实现五子棋人机对战之三python+pygame实现五子棋人机对战之三

活三可以形成眠三,但也能够形成活四。眠三只能够形成冲四。

4.9 活二 :由2枚同色棋子形成的连二(由2枚同色棋子连在一起形成的两头没有对方棋子的2枚棋子。)、跳二(由2枚同色棋子形成的中间没有对方棋子的2枚棋子。)、大跳二(中间有两个空白位置的跳二)。

python+pygame实现五子棋人机对战之三python+pygame实现五子棋人机对战之三python+pygame实现五子棋人机对战之三

4.10 眠二 :由2枚同色棋子形成的两端有对方棋子的2枚棋子。是能够形成眠三的二。

python+pygame实现五子棋人机对战之三     python+pygame实现五子棋人机对战之三       python+pygame实现五子棋人机对战之三    python+pygame实现五子棋人机对战之三

对于棋盘上每一个交叉点,会有8个方向连成五子的可能性,那么我们就利用算法算出所有的可能性,并根据它成五的概率给它打分,这样,得分最高的就是最好的落子点。

如何去实现呢?首先我们在8个方向上将其抽象成坐标的加减,例如水平向右,那么x+1,y不变,向右上,则x+1,y+1 .按正下方开始,逆时针8个方向就形成下面的数据结构:

directions = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]

 获取当前坐标的各个方向上棋子属性,返回1代表白棋,返回2代表黑棋,返回0代表没有棋,返回5表示在棋盘外。

from params import Params rows = int(Params.get('ROWS')) blocksize = int(Params.get('blockSize')) width = int(Params.get('WIDTH')) height = int(Params.get('HEIGHT')) # 获取当前坐标的各个方向上棋子属性,返回1代表白棋,返回2代表黑棋,返回0代表没有棋,返回5表示在棋盘外 def getpointpiece(_mapchess,pos, src, offset): # 8个方向 directions = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]] x1, y1 = pos x1 = x1 + directions[src - 1][0] * offset * blocksize y1 = y1 + directions[src - 1][1] * offset * blocksize if x1 > 588 or y1 > 588 or x1 < 28 or y1 < 28: return 5 else: return _mapchess[str(x1) + ',' + str(y1)]

再加上刚才分析的五子棋的基本棋型,可以设计出一个打分算法:

from params import Params rows = int(Params.get('ROWS')) blocksize = int(Params.get('blockSize')) width = int(Params.get('WIDTH')) height = int(Params.get('HEIGHT')) # 判断每个点的value,用来排序该点下棋的可行性 def pointvalue(_mapchess, pos, flag1, flag2): value = 0 #加权值 for i in range(1, 9): #8个方向 # 11111 连五 if getpointpiece(_mapchess,pos, i, 1) == flag1 and \ getpointpiece(_mapchess,pos, i, 2) == flag1 and \ getpointpiece(_mapchess,pos, i, 3) == flag1 and \ getpointpiece(_mapchess,pos, i, 4) == flag1 and \ getpointpiece(_mapchess,pos, i, 5) == flag1: value +=  # *1111_ 活四 if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == flag1 and \ getpointpiece(_mapchess, pos, i, 3) == flag1 and \ getpointpiece(_mapchess, pos, i, 4) == flag1 and \ getpointpiece(_mapchess, pos, i, 5) == 0: value += 50000 # *11112 冲四1,冲四指加一个点就是连五,比活四威力小得多 if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == flag1 and \ getpointpiece(_mapchess, pos, i, 3) == flag1 and \ getpointpiece(_mapchess, pos, i, 4) == flag1 and \ getpointpiece(_mapchess, pos, i, 5) == flag2: value += 30000 # 1*111 冲四2 if getpointpiece(_mapchess, pos, i, -1) == flag1 and \ getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == flag1 and \ getpointpiece(_mapchess, pos, i, 3) == flag1: value += 30000 # 11*11 冲四3 if getpointpiece(_mapchess, pos, i, -2) == flag1 and \ getpointpiece(_mapchess, pos, i, -1) == flag1 and \ getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == flag1: value += 30000 # *111_ 活三1,活三可以形成活四的三 if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == flag1 and \ getpointpiece(_mapchess, pos, i, 3) == flag1 and \ getpointpiece(_mapchess, pos, i, 4) == 0: value += 20000 # *1_11_ 活三2 if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == 0 and \ getpointpiece(_mapchess, pos, i, 3) == flag1 and \ getpointpiece(_mapchess, pos, i, 4) == flag1 and \ getpointpiece(_mapchess, pos, i, 5) == 0: value += 20000 # *1112 眠三1 眠三是只能形成冲四的三 if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == flag1 and \ getpointpiece(_mapchess, pos, i, 3) == flag1 and \ getpointpiece(_mapchess, pos, i, 4) == flag2: value += 15000 # _1_112 眠三2 if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == 0 and \ getpointpiece(_mapchess, pos, i, 3) == flag1 and \ getpointpiece(_mapchess, pos, i, 4) == flag1 and \ getpointpiece(_mapchess, pos, i, 5) == flag2: value += 15000 # _11_12 眠三3 if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == flag1 and \ getpointpiece(_mapchess, pos, i, 3) == 0 and \ getpointpiece(_mapchess, pos, i, 4) == flag1 and \ getpointpiece(_mapchess, pos, i, 5) == flag2: value += 15000 # 1__11 眠三4 if getpointpiece(_mapchess, pos, i, -1) == flag1 and \ getpointpiece(_mapchess, pos, i, 1) == 0 and \ getpointpiece(_mapchess, pos, i, 2) == flag1 and \ getpointpiece(_mapchess, pos, i, 3) == flag1: value += 15000 # 1_1_1 眠三5 if getpointpiece(_mapchess, pos, i, -1) == flag1 and \ getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == 0 and \ getpointpiece(_mapchess, pos, i, 3) == flag1: value += 15000 # 2_111_2 眠三6 if getpointpiece(_mapchess, pos, i, -1) == flag2 and \ getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == flag1 and \ getpointpiece(_mapchess, pos, i, 3) == flag1 and \ getpointpiece(_mapchess, pos, i, 4) == 0 and \ getpointpiece(_mapchess, pos, i, 5) == flag2: value += 15000 # __11__ 活二1 活二能够形成活三的二 if getpointpiece(_mapchess, pos, i, -1) == 0 and \ getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == flag1 and \ getpointpiece(_mapchess, pos, i, 3) == 0 and \ getpointpiece(_mapchess, pos, i, 4) == 0: value += 10000 # _1_1_ 活二2 if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == 0 and \ getpointpiece(_mapchess, pos, i, 3) == flag1 and \ getpointpiece(_mapchess, pos, i, 4) == 0: value += 10000 # 211__ 眠二1 ,能够形成眠三的二 if getpointpiece(_mapchess, pos, i, -1) == flag2 and \ getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == flag1 and \ getpointpiece(_mapchess, pos, i, 3) == 0 and \ getpointpiece(_mapchess, pos, i, 4) == 0 and \ getpointpiece(_mapchess, pos, i, 5) == 0: value += 1000 #21_1__ 眠二2 if getpointpiece(_mapchess, pos, i, -1) == flag2 and \ getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == 0 and \ getpointpiece(_mapchess, pos, i, 3) == flag1 and \ getpointpiece(_mapchess, pos, i, 4) == 0 and \ getpointpiece(_mapchess, pos, i, 5) == 0: value += 1000 #21__1_ 眠二3 if getpointpiece(_mapchess, pos, i, -1) == flag2 and \ getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == 0 and \ getpointpiece(_mapchess, pos, i, 3) == 0 and \ getpointpiece(_mapchess, pos, i, 4) == flag1 and \ getpointpiece(_mapchess, pos, i, 5) == 0: value += 1000 #*1___1 眠二4 if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == 0 and \ getpointpiece(_mapchess, pos, i, 3) == 0 and \ getpointpiece(_mapchess, pos, i, 4) == 0 and \ getpointpiece(_mapchess, pos, i, 5) == flag1: value += 1000 # *1__ if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == 0 and \ getpointpiece(_mapchess, pos, i, 3) == 0: value += 30 # *1_ if getpointpiece(_mapchess, pos, i, 1) == flag1 and \ getpointpiece(_mapchess, pos, i, 2) == 0: value += 20 # *1 if getpointpiece(_mapchess, pos, i, 1) == flag1: value += 10 return value # 获取当前坐标的各个方向上棋子属性,返回1代表白棋,返回2代表黑棋,返回0代表没有棋,返回5表示在棋盘外 def getpointpiece(_mapchess,pos, src, offset): # 8个方向 directions = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]] x1, y1 = pos x1 = x1 + directions[src - 1][0] * offset * blocksize y1 = y1 + directions[src - 1][1] * offset * blocksize if x1 > 588 or y1 > 588 or x1 < 28 or y1 < 28: return 5 else: return _mapchess[str(x1) + ',' + str(y1)]

这样就可以实现:当人下了棋后,电脑通过这个算法找出最有利的落子点,然后就在那里下棋。

注:本程序只是提供一个思路而已,并不是最优解。代码中value值可以自行修改,算法可以自己再设计,例如可以假如双活三之类的必须防御的应手。

如何判断胜负呢?待续。。。

python+pygame实现五子棋人机对战之四

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/129695.html

(0)
上一篇 2025-08-22 16:26
下一篇 2025-08-22 16:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信