IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Tkinter模块GUI界面化编程实战(七)——人机对战五子棋(含超详解及完整源码、完整程序免费下载链接) -> 正文阅读

[Python知识库]Tkinter模块GUI界面化编程实战(七)——人机对战五子棋(含超详解及完整源码、完整程序免费下载链接)

上期回顾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编写欢乐斗地主】【下期链接:更新中...】

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-04-14 23:50:39  更:2022-04-14 23:51:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 22:40:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计