【上期回顾:Tkinter模块GUI界面化编程实战(六)——超级游戏盒子】
这篇博客介绍了如何用Python Tkinter模块编写一个界面化的人机对战五子棋,在博客下面有完整的源码,源码中有详细的注释,帮助大家理解代码(最后还有附件可以免费下载)
【注:下载文件100%可以运行,因为下载文件中包含打包了的Python程序(exe文件)!】
用Tkinter模块和极大值-极小值搜索算法编写人机对战五子棋
【话不多说,视频如下】
因为录屏的画音不同步哈,看着就有点卡,但其实是不卡的哈
各位观众老爷,怎么样?若觉得可以,请在评论区发一个“666”,若不行请发一个“就这”
【注:本人大一学生一个,初学Python而已[doge],能力有限】
下面就让我来手把手教你如何写一个这样的玩意儿!(完整源码在底下)?
?【废话少说,直接教学】
【预期目标】
我们的预期目标是要做一个有棋盘界面,有一定功能的GUI界面化程序,模式设有三种,分别是
【人机模式】这个比较难,主要在于人机的实现和人机与界面化的对接(人机下棋动画)
【对弈模式】这个最简单了,编出界面后随便加几个函数,制定一下游戏规则即可
【机机模式】这个也简单,前提是人机模式要先编出来😅
【功能设置】
功能设有【退出】、【重置】、【悔棋】
退出简单,重置还好、但是悔棋就要一点点技术了(真不太好弄)
界面的优化就是加入了每一步下棋的记录,是谁下的棋,下在了哪个位置,这个也要点技术
还有一个细节,就是鼠标移到棋盘哪个地方,都会有一个亮绿色的显示框
用一个图来展示我的基本编写步骤(我应该没记错)
【棋盘界面】
利用Canvas画布控件添加图片,并按照五子棋棋盘规则(15×15),用循环优化代码,重复画直线,棋盘加一个边框会更好看(如下图),注意细节:不要忘记棋盘里有五个黑点(用实心黑色小圆形实现)
【按钮放置】
这个按钮可不是简单的按钮,它经过了细节优化,同时还用bind函数关联的了鼠标的点击、经过、离开它的事件信息,使得我们把鼠标悬停在它上面时它会改变状态(背景变成白色,如下图),这样就使得它更具有游戏性。
特别说明,点击重置按钮,弹出来的不是一个新的对话框什么的,而是我画的一个模式选择框,为什么要画一个,而不直接引用模块呢?(有模块可以直接用的)我说过,我不喜欢引用很多别人写好的模块(比如:内置模块),此外,引入模块的对话框我不好去修改它的样式,而我自己画的,我可以任意改(方便美化)
【步骤显示板】
这个还好,就是放一个Label标签控件,控制它的大小和位置,加上一些信息显示(模式信息)
【鼠标位置显示框】
这个就比较妙了,我的方法是对整个窗口用bind函数进行关联,关联鼠标每时每刻的位置,当它在我想要的地方时,对其像素坐标(相对于整个窗口,左上角为(0,0)位置)信息进行处理,转化成棋盘坐标,同时画八条直线(如下图),构成我们的鼠标位置显示框,当其棋盘坐标更新的时候,我们就把原来画的的删掉,然后重新定位,再画。当然,也可以移动其位置,但是重画的方法的代码简单(我偷懒了,没有优化代码😅)
【下棋(对弈模式)】
这个其实很简单的,白方定义为先下棋的一方,下白子,黑子也是,但是注意一下,我没有棋子图片的资源文件,所以我自己画一个,很简单,就是一个边框宽度设置为零,定义好内部颜色的,由当前画布控件产生的圆形。
至于游戏规则的制定,简单简单,就是设个变量去存储当前下棋方是谁的信息,每走一步棋就修改它一次,然后由这个变量决定,下一次下的棋子的颜色。下棋的动画(棋子出现在棋盘上)就是通过上面讲到的鼠标位置显示框的棋盘坐标决定的。每次下棋就放置画好的圆形,同时修改棋盘信息存储列表。
这里弄完后就是对弈模式的最后一步了,编写一个函数,分析棋盘数据,判断是否有输赢产生。
我在下面的代码呢,是通过得到棋盘数据并暴力枚举的方法判断输赢的,其实呢,还有一个更简单的判断方法,其实我们并不需要整个棋盘的信息,不然每下一步棋就分析这么多数据,占用时间较多,真正的解决办法是:找到最后一步(这个很容易做到),在以它为中心向八个方向辐射的区域进行判断,因为如果有五子连线,必定在这其中(下图展示的很清楚)
这必定是最简单且快速的判断方法了!
但这是我在写完这个程序后才发现可以这样的,所以下面的源码中我就没有去修改(偷懒了😅)
【下棋步骤记录】
通过记录下棋瞬时鼠标位置的数据,不难得到每次下棋的坐标是哪里,由存储当前下棋方的变量,易知刚刚是谁走了一步棋,最后将信息以字符串形式添加在一个变量里,使它换行的关键在于每次添加的时候顺便加了一个换行符
【编写AI算法】
不用我说,这一步非常难!
说明一下,我写出来之前是不知道有这个什么五子棋人工智能,什么极大值极小值搜索算法的......我当时的想法就是,遍历五子棋所有的可能性,用我提前写好的评估列表数据去匹配,找到最好的走法(用于进攻)和最坏的走法(用于防御),然后让电脑去走就是了。没想到还真有这么个算法,对,就叫极大值-极小值搜索算法!
基本想法就是,把棋盘信息列表中的信息进行提取,分别从横、竖、左斜和右斜四个方向上考虑,提取出所有的五个位置连在一起的小列表(不要求五子相同),去和我已经写好的评估列表匹配,(评估列表中含有这种小列表的局部分数),把所有的分数加起来就是当前棋盘的总得分。好走法要计分,坏走法也要,两者都记为正数,最后作差即可得到当前棋盘的局部分数总和,棋盘的好坏就取决于这个分数!
那么AI要做什么呢?
当我下了一步之后,电脑开始模拟在所有为空子(没有棋子)的地方下一个黑子,下完一次就评估棋盘得分并记录下该黑子的棋盘坐标和棋盘得分,循环操作,直到把225个位置全部遍历,然后找出记录列表中得分的最高的下子位置,即为当前最佳走法!
那么问题来了,这个评估函数怎么搞出来的呢?
评估、评估嘛,它为什么叫评估列表?因为它是用来评估的,它本身的值还是我自己评估的啊🤣,然后再在后面的实践中进行修改(尤其是特殊值!)
其实还可以搜索第二层(电脑模拟人类下白子),这个二就是搜索深度(但是我放弃了),当时我尝试了的,结果AI走一步要计算二十多秒!!!第三层再模拟下黑子就更不用说了,这还玩个毛的游戏啊!所以,在这个速度要改进,推荐用alpha-beta剪枝算法(如下图),可以提高AI的智能性,加快计算速度(准确说叫减少不必要的计算量),感兴趣的小伙伴们自己去了解哈
最后,再加上一点随机数,以处理多种走法但分数相同的情况(如第一步),这样游戏的人机看起来就更加AI了(这也就导致了机机模式下每局电脑与电脑下棋结果大为不同)
【机机模式】
本来是用来给我自己来看人机AI的评估函数还可以怎么改进的,结果倒发现,看两个电脑下棋格外地有意思🤡,有时候真是不知道该说些什么,尤其是刚开始的时候,评估函数分析的评估列表不够完整,那个人工智能走的那个棋啊,简直不堪入目!!!这怕不是人工智障吧!!!🤣随着我一点一点地修改,这种情况的出现少了很多
其实还有个很妙的想法,暂时还没有实现,就是让修改评估列表的事也交给电脑程序去完成,也就是说,让程序自己运行,自己发现问题,自己去适当地修改评估列表,再将新的评估列表直接使用,依次类推... ...,那么我只需要把电脑打开,让它运行个十天八天的,大量的数据面前,评估列表的修改必然会符合统计学数学规律,类似于高中的求回归方程,最后的评估列表就相当于那个回归方程,会非常的精准,不知道这种方法叫什么名字呢?
【音乐添加】
这里不做过多解释,主要用Pygame实现,(主要是我也不是很了解Pygame😅)
【多说无益,且看源码】?
from tkinter import *
from random import *
import pygame
pygame.mixer.init()
game = Tk()
game.geometry('960x480+150+100')
game.title('五子棋')
game.resizable(0,0)
background = PhotoImage(file='resources\\fivechess2.png')
pygame.mixer.music.load('resources\\fivechessbgm.mp3')
pygame.mixer.music.set_volume(0.1)
class fivechess:
def __init__(self):#定义必要变量
self.game7 = Frame(game)
self.canvas = Canvas(self.game7)
self.px,self.py = 960,480
self.text = ''#下棋记录
self.lists = []#棋盘存储列表
self.cold = 0#冷却值,0白方回合,1黑方回合
self.mode = 0#0默认为人机对战
self.color = 'white'#默认白子先走
self.value = 1#0为空子;1为白子;2为黑子
self.Count = 0#步数
self.over = 0#决定游戏是否结束
self.buttontext = '人机模式'
self.regretlis = []#可悔棋列表
self.regretlisxy = []#可悔棋坐标列表
self.T = StringVar()
self.t = 15#初始剩余时间数
self.ty = 150#时间标签初始纵坐标
self.Mode = StringVar()
self.Mode.set('人机模式')
self.function()
def function(self):#启动功能
self.lists = [[0]*15 for _ in range(15)]
self.game7.place(width=960,height=480)
self.canvas.place(width=960,height=480)
self.canvas.create_image(500,250,image=background)
self.canvas.bind('<Button-1>',lambda event:self.player())
self.canvas.bind('<Motion>',lambda event:self.position(event))
self.modeset()
self.initialization1()
self.initialization2()
self.AI_initialization()
def initialization1(self,color='black'):#棋盘初始化
for i in range(256,705,32):#棋盘网 (256,16)~(704,464)
self.canvas.create_line(i,16,i,464)
self.canvas.create_line(256,i-240,704,i-240)
self.canvas.create_rectangle(250,10,710,470,width=3)#棋盘框
self.canvas.create_oval(349,109,355,115,fill=color)#棋盘点
self.canvas.create_oval(349,365,355,371,fill=color)
self.canvas.create_oval(605,109,611,115,fill=color)
self.canvas.create_oval(605,365,611,371,fill=color)
self.canvas.create_oval(477,237,483,243,fill=color)
def position(self,event,color='springgreen'):#鼠标位置
if 240< event.x <720:
self.px,self.py = 32*int((event.x-240)/32)+256,32*int(event.y/32)+16
try:
for i in [self.l1,self.l2,self.l3,self.l4,self.l5,self.l6,self.l7,self.l8]:self.canvas.delete(i)
except:pass
self.l1 = self.canvas.create_line(self.px-15,self.py-15,self.px-15,self.py-5,width=1,fill=color)
self.l2 = self.canvas.create_line(self.px-15,self.py-15,self.px-5,self.py-15,width=1,fill=color)
self.l3 = self.canvas.create_line(self.px-15,self.py+15,self.px-15,self.py+5,width=1,fill=color)
self.l4 = self.canvas.create_line(self.px-15,self.py+15,self.px-5,self.py+15,width=1,fill=color)
self.l5 = self.canvas.create_line(self.px+15,self.py-15,self.px+15,self.py-5,width=1,fill=color)
self.l6 = self.canvas.create_line(self.px+15,self.py-15,self.px+5,self.py-15,width=1,fill=color)
self.l7 = self.canvas.create_line(self.px+15,self.py+15,self.px+5,self.py+15,width=1,fill=color)
self.l8 = self.canvas.create_line(self.px+15,self.py+15,self.px+15,self.py+5,width=1,fill=color)
def initialization2(self):
Label(self.game7,bg='grey',font=('consolas',30),text='白方',fg='white').place(width=200,height=200,x=20,y=20)
Label(self.game7,bg='grey',font=('consolas',30),text='黑方',fg='white').place(width=200,height=200,x=20,y=260)
self.f1 = Label(self.game7,bg='black')
self.f2 = Label(self.game7,bg='black')
self.f3 = Label(self.game7,bg='black')
self.f4 = Label(self.game7,bg='black')
self.f(10)
Label(self.game7,bg='black').place(width=220,height=280,y=10,x=730)
Label(self.game7,bg='grey').place(width=216,height=276,y=12,x=732)
Label(self.game7,bg='grey',textvariable=self.Mode,font=('consolas',15),fg='white').place(width=216,height=26,y=12,x=732)
countframe = Frame(self.game7,bg='grey')
countframe.place(width=216,height=250,x=732,y=38)
self.countlabel = Label(countframe,bg='grey',fg='white',text=self.text,font=('consolas',12),anchor='sw')
self.timelabel = Label(self.game7,bg='grey',textvariable=self.T,fg='white',font=('consolas',30))
self.B1 = Button(self.game7,bg='grey',bd=0,font=('consolas',20),fg='white',text='退出',command=self.game7.quit)
self.B1.place(width=220,x=730,height=50,y=300)
self.B2 = Button(self.game7,bg='grey',bd=0,font=('consolas',20),fg='white',text='重置',command=lambda:gameagain())
self.B2.place(width=220,x=730,height=50,y=360)
self.B3 = Button(self.game7,bg='grey',bd=0,font=('consolas',20),fg='white',text='悔棋',command=lambda:self.regret(),state='disabled')
self.B3.place(width=220,x=730,height=50,y=420)
for i in [self.B1,self.B2,self.B3]:
i.bind('<Enter>',lambda event:enter(event))
i.bind('<Leave>',lambda event:leave(event))
def enter(event):event.widget['bg']='#F0F0F0';event.widget['fg']='black'
def leave(event):event.widget['bg']='grey';event.widget['fg']='white'
def gameagain():
self.game7.destroy()
fivechess()
def f(self,fy):
self.f1.place(width=5,height=220,x=10,y=fy)
self.f2.place(width=220,height=5,x=10,y=fy)
self.f3.place(width=220,height=5,x=10,y=fy+215)
self.f4.place(width=5,height=220,x=225,y=fy)
def AI_initialization(self):
self.defense_case =[[0,0,0,0,0],#0
[0,0,1,0,0],
[0,1,0,0,0],
[1,0,0,0,0],
[1,0,0,1,0],
[0,0,1,1,0],#5
[0,1,0,1,0],
[1,0,1,0,0],
[1,0,0,0,1],
[0,0,0,1,1],
[1,1,0,0,1],#10
[0,1,1,0,1],
[0,1,0,1,1],
[1,0,1,0,1],
[1,1,1,0,0],
[0,1,1,1,0],]#15
self.attack_case = [[0,0,0,0,0],#0
[0,0,2,0,0],
[0,2,0,0,0],
[2,0,0,0,0],
[2,0,0,2,0],
[0,0,2,2,0],#5
[0,0,2,2,0],
[2,0,2,0,0],
[0,2,0,2,0],
[0,0,0,2,2],
[2,2,0,0,2],#10
[0,2,0,2,2],
[0,2,2,0,2],
[2,0,2,0,2],
[2,2,2,0,0],
[0,2,2,2,0],]#15
def defense(self,lis,value=0):
if 0 in lis and lis.count(1) == 4:value = 9999999999
elif 2 in lis and lis.count(1) == 4:value = 5000
elif lis == [0,1,1,1,0]:value = 9999999
elif lis in [[1,1,0,1,0],[0,1,1,0,1]] or reversed(lis) in [[1,1,0,1,0],[0,1,1,0,1]]:value = 10000
else:
try:value = self.defense_case.index(lis)**3
except:
try:value = self.defense_case.index(reversed(lis))**3
except:pass
return value
def defense2(self,lis,value=0):
if lis == [0,0,1,1,1,0] or lis == [0,1,1,1,0,0]:value = 999999999
elif lis in [[0,1,1,1,1,2],[1,0,1,1,1,2],[1,1,0,1,1,2],[1,1,1,0,1,2],[2,1,0,1,1,1,],[2,1,1,0,1,1],[2,1,1,1,0,1],[2,1,1,1,1,0]]:value = 99999999
elif lis in [[1,1,1,1,0,1],[1,0,1,1,1,1]]:value = 9999999
return value
def attack2(self,lis,value=0):
if lis == [1,2,2,2,2,1]:value = -99999
elif lis == [0,2,2,2,2,1] or lis == [1,2,2,2,2,1]:value = 9999
elif lis == [0,2,2,2,2,0]:value = 9999999999
elif lis == [0,2,2,0,2,0] or lis == [0,2,0,2,2,0]:value = 999999
return value
def attack(self,lis,value=0):
if lis == [2]*5:value=9999999999
elif 0 in lis and lis.count(2) == 4:value = 9999999
elif 1 in lis and lis.count(2) == 4:value = -1000
elif lis == [0,1,1,1,0]:value = -10000
elif lis in [[2,1,1,0,2],[2,0,1,1,1],[2,1,1,1,0],[2,1,0,1,2],[2,1,1,1,2]] or reversed(lis) in [[2,1,1,0,2],[2,0,1,1,1],[2,1,1,1,0],[2,1,1,1,2]]:value = -300000
elif lis in [[2,1,2,2,0],[2,1,2,2,2]] or reversed(lis) in [[2,1,2,2,0],[2,1,2,2,2]]:value = -30000
elif lis in [[2,2,0,2,0],[0,2,2,0,2],[0,2,2,2,0]] or reversed(lis) in [[2,2,0,2,0],[0,2,2,0,2]]:value = 4000
else:
try:value = self.attack_case.index(lis)**3
except:
try:value = self.attack_case.index(reversed(lis))**3
except:pass
return value
def regret(self):
self.B3.config(state='disabled')
if self.Count%2 == 0:
self.Count -= 2
self.text = self.text[:-40]
self.countlabel.config(text=self.text)
self.countlabel.place(width=216,height=20*self.Count,y=250-20*self.Count)
for i in self.regretlis:self.canvas.delete(i)
for i in self.regretlisxy:self.lists[i[0]][i[1]] = 0
try:
self.winlabel.destroy()
pygame.mixer.music.unpause()
self.over = 0
self.mode = 1 if self.buttontext == '对弈' else 0
except:pass
def Time(self,updata=0):
if updata == 1:
self.timelabel.config(fg='white')
self.t = 15
self.ty = 150 if self.ty == 390 else 390
self.T.set('- %s -'%self.t)
self.timelabel.place(width=200,height=30,x=20,y=self.ty)
if self.t == 2 and self.mode != 2:
self.timelabel.config(fg='red')
pygame.mixer.Sound('resources\\ring.wav').play()
if self.t != 0 and updata == 0:
self.t -= 1
self.game7.after(1000,self.Time)
def modeset(self):
self.MS = Frame(self.game7)
self.MS.place(width=300,height=200,y=140,x=330)
Label(self.MS,bg='black').place(width=280,height=90,x=10,y=70)
textlabel = Label(self.MS,bg='grey',font=('consolas',15),fg='white',text='人类与电脑之间的战斗!\n不怕死就来挑战吧!')
textlabel.place(width=276,height=86,x=12,y=72)
b1 = Button(self.MS,text=self.buttontext,font=('consolas',20),bd=0,command=lambda:button())
b1.place(width=200,height=30,y=35,x=50)
Label(self.MS,bg='grey',text='设置',font=('consolas',15)).place(width=300,height=30)
Label(self.MS,bg='grey').place(width=300,height=30,y=170)
Button(self.MS,text='确定',font=('consolas',15),bd=0,command=lambda:okget()).place(width=100,height=20,y=175,x=195)
def okget():
pygame.mixer.music.play(loops=10)
self.MS.destroy()
self.Time()
if self.mode == 2:
self.cold = 1
self.f(500)
self.ty = 500
self.AI_AI()
def button():
if self.buttontext=='机机模式':
self.buttontext = '人机模式'
self.mode = 0
self.Mode.set('人机模式')
textlabel.config(text='人类与电脑之间的战斗!\n不怕死就来挑战吧!')
elif self.buttontext=='人机模式':
self.buttontext = '对弈模式'
self.mode = 1
self.Mode.set('对弈模式')
textlabel.config(text='人类与人类之间的对决!\n到底谁才是王中王呢!')
elif self.buttontext == '对弈模式':
self.buttontext = '机机模式'
self.mode = 2
self.Mode.set('机机模式')
textlabel.config(text='电脑与电脑之间的交流!\n一种神秘而牛逼的设定!')
b1.config(text=self.buttontext)
def enter(event):event.widget['bg']='grey';event.widget['fg']='white'
def leave(event):event.widget['bg']='#F0F0F0';event.widget['fg']='black'
b1.bind('<Enter>',enter)
b1.bind('<Leave>',leave)
def referee(self,lists,M=1):#判断输赢M为1就非AI
AIlist = []
#竖
for i in range(15):
temp_list = []
for lis in lists:temp_list.append(lis[i])
if M == 1:self.judgement(temp_list)
else:AIlist.append(temp_list)
#横
for lis in lists:
if M == 1:self.judgement(lis)
else:AIlist.append(lis)
#斜
for i in [1,-1]:#右斜;左斜
for x in range(15):
y = 0
temp_list1 = []
temp_list2 = []
try:
while x >= 0:
temp_list1.append(lists[x][y])
temp_list2.append(lists[i*(y-7)+7][i*(x-7)+7])
x += i
y += 1
except:pass
if M == 1:
self.judgement(temp_list1)
self.judgement(temp_list2)
else:
AIlist.append(temp_list1)
AIlist.append(temp_list2)
return AIlist
def judgement(self,lis):
try:
for i in range(11):
if lis[i:i+5] == [1]*5:self.gameover(1);return None
if lis[i:i+5] == [2]*5:self.gameover(2);return None
except:pass
def gameover(self,winner):#winner=1则白方胜,2则黑方胜
pygame.mixer.music.pause()
if winner == 1:
if self.mode == 0:pygame.mixer.Sound('resources\\victory.wav').play()
self.winlabel = Label(self.game7,bg='grey',font=('consolas',30),fg='springgreen',text='-白方胜-')
self.winlabel.place(width=200,height=50,x=20,y=40)
else:
if self.mode == 0:pygame.mixer.Sound('resources\\defeat.wav').play()
self.winlabel = Label(self.game7,bg='grey',font=('consolas',30),fg='springgreen',text='-黑方胜-')
self.winlabel.place(width=200,height=50,x=20,y=280)
if self.mode == 1:pygame.mixer.Sound('resources\\victory.wav').play()
self.over = 1#锁定玩家
self.mode = 2#锁定AI
def countadd(self,n,x,y):
self.Count += 1
player = '[白方]' if n == 1 else '[黑方]'
self.text += '\n%s(%02d,%02d)\t [%03d]'%(player,x+1,15-y,self.Count)
self.countlabel.config(text=self.text)
self.countlabel.place(width=216,height=20*self.Count,y=250-20*self.Count)
def regretadd(self,i,x,y):
self.regretlis.append(i)
self.regretlisxy.append((x,y))
if len(self.regretlis) >= 2:self.B3.config(state='active')
if len(self.regretlis) == 3:
del self.regretlis[0]
del self.regretlisxy[0]
def player(self):
if self.cold+self.over == 0:
x,y = (self.px-256)//32,(self.py-16)//32
if self.lists[x][y] == 0:self.lists[x][y] = self.value
else:return None
self.countadd(self.value,x,y)
i = self.canvas.create_oval(self.px-15,self.py-15,self.px+15,self.py+15,fill=self.color,width=0)
self.regretadd(i,x,y)
pygame.mixer.Sound('resources\\%s.mp3'%randint(1,4)).play()
self.referee(self.lists)
self.cold = 1
if self.mode == 0:
self.f(250)
self.ai_execute()
self.Time(updata=1)
elif self.mode == 1:
if self.color == 'black':
self.color = 'white'
self.value = 1
self.f(10)
else:
self.color = 'black'
self.value = 2
self.f(250)
self.cold = 0
self.Time(updata=1)
def ai_execute(self,color='black'):
ai_x,ai_y = self.AI()
if color == 'black':
self.lists[ai_x][ai_y] = 2
self.countadd(2,ai_x,ai_y)
else:
self.lists[ai_x][ai_y] = 1
self.countadd(1,ai_x,ai_y)
ai_x,ai_y = 32*ai_x+256,ai_y*32+16
i = self.canvas.create_oval(ai_x-15,ai_y-15,ai_x+15,ai_y+15,fill=color,width=0)
self.regretadd(i,(ai_x-256)//32,(ai_y-16)//32)
pygame.mixer.Sound('resources\\%s.mp3'%randint(1,4)).play()
if self.mode == 0:
self.cold = 0
self.f(10)
self.Time(updata=1)
self.referee(self.lists)
def AI(self):
xlis,ylis = [],[]
AIdata,AIvalue = [],[]
try:
for lis in self.lists:
for i in lis:
if i != 0:
xlis.append(self.lists.index(lis))
ylis.append(lis.index(i))
xmax,ymax,xmin,ymin = max(xlis)+4,max(ylis)+4,min(xlis)-4,min(ylis)-4
except:xmax,ymax,xmin,ymin = 20,20,-5,-5
for x in range(15):
for y in range(15):
if self.lists[x][y] == 0 and xmin<x<xmax and ymin<y<ymax:
a_value,d_value = 0,0
self.lists[x][y] = 2
for lis in self.referee(self.lists,M=0):
for i in range(11):
try:
d_value += self.defense(lis[i:i+5])
d_value += self.defense2(lis[i:i+6])#强化
except:pass
try:
a_value += self.attack(lis[i:i+5])
a_value += self.attack2(lis[i:i+6])#强化
except:pass
AIdata.append([x,y])
AIvalue.append(a_value-d_value)
self.lists[x][y] = 0
keyvalue = max(AIvalue)
N = AIvalue.count(keyvalue)
if N == 1:return AIdata[AIvalue.index(keyvalue)]
else:
for i in range(len(AIvalue)):
try:
value = AIvalue[i]
if value != keyvalue:AIdata.remove(AIdata[i])
except:pass
return choice(AIdata)
def AI_AI(self):
if self.over == 0:
color = 'white' if self.Count%2 == 0 else 'black'
self.ai_execute(color)
self.referee(self.lists)
self.game7.after(1000,self.AI_AI)
fivechess()
game.mainloop()
【?兄弟们!这个真的不简单呐!原创不易,不妨动动你的小指头,点个赞嘛!】?
完整程序及源码下载链接【蓝奏云】:Gobang.zip【密码:8noo】
【下期预告:Python Tkinter编写欢乐斗地主】【下期链接:更新中...】
|