Tkinter模块GUI图形化编程实战(八)——中国象棋(含超详解及完整源码、完整程序免费下载链接)

简介: Tkinter模块GUI图形化编程实战(八)——中国象棋(含超详解及完整源码、完整程序免费下载链接)

【效果展示】

完整程序下载链接在文章末尾!

主界面 下棋时 帮助界面 制作人员界面 模式设置 棋局设置 主题设置 窗口设置

还有一部分功能没做好就不展示了(嘻嘻)


【功能详细说明】


①主界面有六个“透明”按钮,两个信息展示框,按钮可以用相应的键盘按键触发(帮助界面里有说明)


②下棋记录中会显示每一步的走法,可以上下滑动(非固定)


③界面的切换类似于手机的滑屏,十分流畅无卡顿


④制作人员的界面中,一些信息会滑动


⑤悔棋嘛,字面意思,只不过每次悔棋都是双方各撤销一步


⑥设置界面有很多东西可以设置,不过有一部分功能还未实现(重置按键、闯关设置和音效设置)


⑦模式的话,我是打算做五个模式的,但是由于一些原因我只做了双人对弈模式,人机模式也只是做了一点点(人机很傻)


⑧设置里,可以更改先手方,可以让子(最多支持双车双炮双马,左右区分),可以更改游戏模式(目前只有对弈模式与人机模式的部分功能有效)

【教学教程】

【特别说明】


       这是该程序的第一代版本,由于还有一部分功能未完善,后续我将继续更新v2.0版本,2.0版本会完善人机对战模式,新增网络对战(局域网),电脑对战和闯关模式,同时会加入音乐,修复少许BUG!希望大家多多支持我!


基本思路就是将多个功能变成多个python文件,以一个启动文件去调用它们。


这里各个文件和功能我列在下面:

image.png

每一个python文件中的内容我都把它以一个类的形式写出来,然后相关函数就作为这个类的方法,目的是为了方便其他引用python文件(类)引用。


界面的初始化文件我就不说了,可以到下面找源代码看看,每一部分是什么功能在源代码里面已经说的很清楚了。


看源代码的时候要穿插着看看value.py的内容,因为我大部分的值和常量都是放在这个文件里面的,就类似一个大容器,程序运行需要的东西都放在里面,而其他文件相当于执行各个功能的程序,时不时的从value.py文件里取或存放东西,各个文件之间的联系也是通过value.py实现的。


这里我不会介绍那个人机是怎么做到的(确切的说,那不能算是人机,只是一个半成品)。


下面我将着重说明一些特殊的操作是怎么做到的。

【透明的按钮】

这个透明是真真确确的透明,但这个按钮是假的,它并非tkinter模块中自带的那个Button类,也不是我重写继承于它的类,这个里面的按钮和tkinter里面自带的按钮完全不是一个品种!


我们知道,在tkinter模块里面只有少数的几种控件可以插入图片,如Label控件、Button控件和Canvas控件等等。一般我们都是用Canvas控件来插入图片的,毕竟Canvas控件叫画布控件,专门就是来搞这个事的。


这里,我们有两种方法使得按钮透明


第一种,给按钮插入图片,只不过这个图片就是背景的一部分(背景一般由Canvas控件插入),这样就看起来按钮透明,但是!这样就要裁剪背景图片来产生那些插入按钮的图片,过于复杂和繁琐。如果我要10000个透明的按钮,每一个位置都不一样,那岂不是要裁剪出10000个图片?不仅占用内存,而且也不现实。


第二种,也是我这里采用的方法,用Canvas控件,结合bind函数进行事件绑定,我们就能做到“以假乱真”,简单说,我这里的按钮是在Canvas控件上画出来的,只不过在我们鼠标经过它的位置范围和点击的时候会呈现出不同的效果,看起来就像是一个按钮了。以我这里的按钮为例,它实际就是俩矩形框加上一个文字罢了!


后面的操作,想必大家都知道了,就不用我说了,强烈建议大家用第二种方法。

【流畅的画面切换】

画面的切换

屏幕录像时有点卡,导致动图看起来卡,实际上是很流畅的。


其实这个有很多方法都可以实现的,比如每个页面可以用Frame控件“框”起来,然后就写一个时间函数,让当前的页面与你要切换的页面一起按照一个速度平移就行,我的速度函数是三角函数的一部分(并非半个周期,而是偏移了一点,这样就会有一个回弹的效果),这样就能让它先慢后快再慢,看起来就有内味儿了。


对了,棋盘上棋子移动的动画效果也是这个原理。

棋子的移动动画

【主题设置的实现】

梦幻蓝主题色 和谐绿主题色 典雅粉主题色

其实在同一目录下的资源文件夹resources里面,有一个cache.txt的文件,里面只写了一个数字(1~5),代表下次打开程序时的主题号,所以每次更换主题要重启(其实可以不用这样,但要实现随点随改的话,代码里面有很多很多部分要修改,没有必要)。主题颜色是由很多部分组成的,value.py源代码里面有,我就不详说了。


【文本滚动效果】

还记得那个“制作人员”的界面吗?切换后会有一个滚动的文本效果(【效果展示】里面有)


那个背景是一个Canvas控件实现的,而那个滚动的文本其实也是一个Canvas控件,只是小一点,两个Canvas控件的图片是同一张,小控件的图片并非由第一张裁剪得到,它只是展示原图片的一部分(适当的部分),导致我们看不出来罢了!


修改一下展示的部分(value.py中修改),效果就是这样的(如下图):

修改后的界面

滚动的文本也只是在小Canvas控件里面,所以不会滚动到外面去。


关于文本会动这件事,实际上就是反复修改文本显示的位置的纵坐标,按时间以一定的速度向上移动。


对了,鼠标放在小Canvas控件上时,文本会停止滚动哦!


同样的道理,在主界面右上角的那个“下棋记录”显示框里显示的文本也是滚动的,只不过这里的滚动由玩家控制(鼠标中键滚动),也是一样,不会滚出那个框(看起来好像没有框,实际上有的)


【小插曲】


其实本来还有一个我想实现的操作,就是在进行人机对战的时候,我们走了一步,人机需要运算一会儿(大概0.5秒)才会走一步,这短暂的时间里程序会“卡”(未响应),为了解决这个问题,(个人认为)应该要用多线程模块,将人机的运算与界面的显示分成两个线程。


只可惜,不知道是什么BUG,我实在是没能实现(容我以后再研究研究吧!)

【其他】

关于其他一些是怎么实现的,实际上看源代码就很容易的了解了(有注释的)


整个程序除了AI.py文件中引入了deepcopy模块以外,其他的文件都只引入了tkinter模块,没有其他的内置模块了。


可能比较难懂的地方就是play.py中的“路径计算”部分了,那一部分是在解决判定哪个地方能不能走的问题,以方便显示出选中子可以走(黄色框显示)和可以吃子的位置(红色框显示)。对于每一类子都有不同的走法,大部分都比较容易实现,除了两个恶心玩意儿 —— 炮(隔子吃)和将与帅的“白脸将”(将帅碰面)情形。


棋盘上的子在程序运行时,实际上只是一个二维列表罢了(如下):

[[ 7, 5, 3, 1, 0, 2, 4, 6, 8],
 [-1,-1,-1,-1,-1,-1,-1,-1,-1],
 [-1, 9,-1,-1,-1,-1,-1,10,-1],
 [11,-1,12,-1,13,-1,14,-1,15],
 [-1,-1,-1,-1,-1,-1,-1,-1,-1],
 #        楚河 · 汉界        #
 [-1,-1,-1,-1,-1,-1,-1,-1,-1],
 [27,-1,28,-1,29,-1,30,-1,31],
 [-1,25,-1,-1,-1,-1,-1,26,-1],
 [-1,-1,-1,-1,-1,-1,-1,-1,-1],
 [23,21,19,17,16,18,20,22,24]]

其中,0~31分别代表黑方16个棋子和红方16个棋子,而-1则代表“空”,棋子的移动也只是该列表的值发生相应变化,而棋盘上棋子的变化只是对该列表的变化做出相应的反应而已。


至于为什么要用-1代表空,而不用0这件事,是为了方便后续对其他棋子的操控(它们的代号为0到31,恰好是一个32长度的列表的元素索引)

【源代码展示】

【注:源代码由多个文件构成,启动文件为:Luncher.py】

【Luncher.py】

# 启动程序 #
from tkinter import *
from initialization import initialization
from buttonbind import buttonbind
from mouse import mouse
from value import value
from play import play
from rule import rule
initialization()        #界面初始化
buttonbind()            #关联处理
mouse()                 #实时显示鼠标位置
play()                  #玩家走子
rule()                  #执行规则
value.game.mainloop()   #启动窗口

【initialization.py】

# 界面初始化 #
from tkinter import *
from value import value
class initialization:
  def __init__(self):
    self.board_initialization()#棋盘初始化
    self.peice_initialization()#棋子初始化
    self.face_initialization()#图像初始化
  def board_initialization(self,w=3,l=12):#棋盘初始化
    value.canvas.place(width=960,height=500)
    value.canvas.create_image(480,250,image=value.background)#背景
    value.canvas.create_rectangle(275,20,685,480,width=3,outline=value.colorlis[0])#外框
    value.canvas.create_rectangle(280,25,680,475,outline=value.colorlis[0])#内框
    value.canvas.create_line(430,25,530,125,fill=value.colorlis[0])#两个“×”
    value.canvas.create_line(430,375,530,475,fill=value.colorlis[0])
    value.canvas.create_line(430,125,530,25,fill=value.colorlis[0])
    value.canvas.create_line(430,475,530,375,fill=value.colorlis[0])
    for y in [175,325]:#“十”字形
      for i in [(280,y),(380,y),(480,y),(580,y),(680,y),(330,y+50*(-1)**(y//150)),(630,y+50*(-1)**(y//150))]:
        if i[0] != 280:
          value.canvas.create_line(i[0]-w,i[1]-w,i[0]-w-l,i[1]-w,width=2,fill=value.colorlis[0])#左上
          value.canvas.create_line(i[0]-w,i[1]-w,i[0]-w,i[1]-w-l,width=2,fill=value.colorlis[0])
          value.canvas.create_line(i[0]-w,i[1]+w+1,i[0]-w-l,i[1]+w+1,width=2,fill=value.colorlis[0])#左下
          value.canvas.create_line(i[0]-w,i[1]+w+1,i[0]-w,i[1]+w+l+1,width=2,fill=value.colorlis[0])
        if i[0] != 680:
          value.canvas.create_line(i[0]+w+1,i[1]-w,i[0]+w+l+1,i[1]-w,width=2,fill=value.colorlis[0])#右上
          value.canvas.create_line(i[0]+w+1,i[1]-w,i[0]+w+1,i[1]-w-l,width=2,fill=value.colorlis[0])
          value.canvas.create_line(i[0]+w+1,i[1]+w+1,i[0]+w+l+1,i[1]+w+1,width=2,fill=value.colorlis[0])#右下
          value.canvas.create_line(i[0]+w+1,i[1]+w+1,i[0]+w+1,i[1]+w+l+1,width=2,fill=value.colorlis[0])
    for i in range(75,425+1,50):
      value.canvas.create_line(280,i,680,i,fill=value.colorlis[0])#横线
    for i in range(330,630+1,50):#竖线
      value.canvas.create_line(i,25,i,225,fill=value.colorlis[0])
      value.canvas.create_line(i,275,i,475,fill=value.colorlis[0])
    value.canvas.create_text(480,250,text='楚河 · 汉界',font=('华文新魏',35),fill=value.colorlis[0])#“楚河 · 汉界”
  def peice_initialization(self,count=-1):#棋子初始化
    for ylis in value.board_lists:#摆子
      count += 1
      for i in ylis:
        if i != -1:
          x,y = count,ylis.index(i)
          s_x,s_y = x*50+25,y*50+280
          value.peice_lists[i] = value.canvas.create_image(s_y,s_x,image=value.resourcelists[i])
  def button_initialization(self):#按钮初始化 (allbind.py中进行)
    self.bo1 = value.canvas.create_rectangle(720,315,940,360,width=3,outline=value.colorlis[1])#“设置”按钮
    self.bi1 = value.canvas.create_rectangle(725,320,935,355,outline=value.colorlis[1])
    self.bt1 = value.canvas.create_text(830,338,text='设        置',font=('华文新魏',20),fill=value.colorlis[0])
    self.bo2 = value.canvas.create_rectangle(720,375,940,420,width=3,outline=value.colorlis[1])#“悔棋”按钮
    self.bi2 = value.canvas.create_rectangle(725,380,935,415,outline=value.colorlis[1])
    self.bt2 = value.canvas.create_text(830,398,text='悔        棋',font=('华文新魏',20),fill=value.colorlis[0])
    self.bo3 = value.canvas.create_rectangle(720,435,940,480,width=3,outline=value.colorlis[1])#“退出”按钮
    self.bi3 = value.canvas.create_rectangle(725,440,935,475,outline=value.colorlis[1])
    self.bt3 = value.canvas.create_text(830,458,text='退        出',font=('华文新魏',20),fill=value.colorlis[0])
    self.bo4 = value.canvas.create_rectangle(20,315,240,360,width=3,outline=value.colorlis[1])#“帮助”按钮
    self.bi4 = value.canvas.create_rectangle(25,320,235,355,outline=value.colorlis[1])
    self.bt4 = value.canvas.create_text(130,338,text='帮        助',font=('华文新魏',20),fill=value.colorlis[0])
    self.bo5 = value.canvas.create_rectangle(20,375,240,420,width=3,outline=value.colorlis[1])#“重新开始”按钮
    self.bi5 = value.canvas.create_rectangle(25,380,235,415,outline=value.colorlis[1])
    self.bt5 = value.canvas.create_text(130,398,text='重新开始',font=('华文新魏',20),fill=value.colorlis[0])
    self.bo6 = value.canvas.create_rectangle(20,435,240,480,width=3,outline=value.colorlis[1])#“制作人员”按钮
    self.bi6 = value.canvas.create_rectangle(25,440,235,475,outline=value.colorlis[1])
    self.bt6 = value.canvas.create_text(130,458,text='制作人员',font=('华文新魏',20),fill=value.colorlis[0])
    self.button_lists =[self.bo1,self.bi1,self.bt1,self.bo2,self.bi2,self.bt2,self.bo3,self.bi3,self.bt3,
              self.bo4,self.bi4,self.bt4,self.bo5,self.bi5,self.bt5,self.bo6,self.bi6,self.bt6]
  def face_initialization(self):#图像初始化
    value.canvas.create_rectangle(720,20,940,300,width=3,outline=value.colorlis[1])#步骤显示板
    value.canvas.create_rectangle(725,25,935,295,outline=value.colorlis[1])
    value.canvas.create_text(830,40,text='下棋记录',font=('华文新魏',20),fill=value.colorlis[0])
    value.canvas2.place(width=205,height=240,x=728,y=52)
    value.canvas2.create_image(480-728,240-52,image=value.background)
    value.canvas2.create_image(100,100,image=value.face)
    def back(event):
      if len(value.steptextlis) > 12:
        if event.delta < 0 and value.firststep > 250-len(value.steptextlis)*20:
          for i in value.steptextlis:
            value.canvas2.move(i,0,-20)
          value.firststep -= 20
        elif event.delta > 0 and value.firststep <= -10:
          for i in value.steptextlis:
            value.canvas2.move(i,0,20)
          value.firststep += 20
    value.canvas2.bind('<MouseWheel>',back)
    value.canvas.create_rectangle(20,20,240,300,width=3,outline=value.colorlis[1])#信息显示板
    value.canvas.create_rectangle(25,25,235,295,outline=value.colorlis[1])
    value.canvas.create_image(130,160,image=value.face)
    value.canvas.create_text(130,40,text='游戏信息',font=('华文新魏',20),fill=value.colorlis[0])
  def buttonchange(self,n,mode):#按钮皮肤
    if mode == 'change1':#模式一:经过
      for i in self.button_lists:
        if (n-1)*3<=self.button_lists.index(i)<n*3:
          try:
            value.canvas.itemconfig(i,outline=value.colorlis[5])
          except:
            value.canvas.itemconfig(i,fill=value.colorlis[5])
    elif mode=='change2':#模式二:按下
      for i in self.button_lists:
        if (n-1)*3<=self.button_lists.index(i)<n*3:
          try:
            value.canvas.itemconfig(i,outline=value.colorlis[2])
          except:
            value.canvas.itemconfig(i,fill=value.colorlis[2])
    else:#模式三:离开
      for i in self.button_lists:
        try:
          value.canvas.itemconfig(i,outline=value.colorlis[1])
        except:
          value.canvas.itemconfig(i,fill=value.colorlis[0])

【mouse.py】

# 鼠标位置显示 #
from tkinter import *
from value import value
class mouse:
  def __init__(self):
    self.tempx,self.tempy = 0,0#初始化鼠标位置
    value.game.bind('<Motion>',self.callback)#关联鼠标移动事件
  def callback(self,event,color=value.colorlis[-1],dv1=25,dv2=10,w=2):
    if 250< event.x <705:#判断是否越界
      event.x,event.y = 50*int((event.x-255)/50)+280,50*int(event.y/50)+25#处理鼠标位置
      if (event.x,event.y) != (self.tempx,self.tempy):#显示框
        self.tempx,self.tempy = event.x,event.y
        try:#删除之前的位置
          for i in [self.l1,self.l2,self.l3,self.l4,self.l5,self.l6,self.l7,self.l8]:
            value.canvas.delete(i)
        except:pass
        self.l1 = value.canvas.create_line(event.x-dv1,event.y-dv1,event.x-dv1,event.y-dv2,width=w,fill=color)#左上
        self.l2 = value.canvas.create_line(event.x-dv1,event.y-dv1,event.x-dv2,event.y-dv1,width=w,fill=color)
        self.l3 = value.canvas.create_line(event.x-dv1,event.y+dv1,event.x-dv1,event.y+dv2,width=w,fill=color)#左下
        self.l4 = value.canvas.create_line(event.x-dv1,event.y+dv1,event.x-dv2,event.y+dv1,width=w,fill=color)
        self.l5 = value.canvas.create_line(event.x+dv1,event.y-dv1,event.x+dv1,event.y-dv2,width=w,fill=color)#右上
        self.l6 = value.canvas.create_line(event.x+dv1,event.y-dv1,event.x+dv2,event.y-dv1,width=w,fill=color)
        self.l7 = value.canvas.create_line(event.x+dv1,event.y+dv1,event.x+dv2,event.y+dv1,width=w,fill=color)#右下
        self.l8 = value.canvas.create_line(event.x+dv1,event.y+dv1,event.x+dv1,event.y+dv2,width=w,fill=color)

【play.py】

# 玩家移动模块 #
from tkinter import *
from value import value
from rule import rule
class play():
    def __init__(self):
        value.canvas.bind('<Button-1>',self.move)
    def move(self,event):#移动操作
        if 250< event.x <705:
            value.play_count = 1 if value.play_count == 0 else 0
            x,y = int((event.x-255)/50),int(event.y/50)
            if value.play_count == 1 and value.board_lists[y][x] in value.team and value.DEAD == 0:#选中棋子
                self.peice_info(x,y,1)
                value.play_tampvalue = value.board_lists[y][x]
                value.play_tamp_x,value.play_tamp_y = x,y
                value.board_lists[y][x] = -1
            elif value.play_count == 0 and value.info_lists[y][x] != 0:#移动棋子
                self.peice_info(x,y,0)
                if value.board_lists[y][x] != -1:
                    value.canvas.move(value.peice_lists[value.board_lists[y][x]],0,600)
                value.board_lists[y][x] = value.play_tampvalue
                if [value.play_tamp_x,value.play_tamp_y] != [x,y]:
                    dx,dy = (x-value.play_tamp_x)*50,(y-value.play_tamp_y)*50
                    self.fluent(dx,dy)
                    rule.Dead(self)
                    value.step += 1
                    rule.stepinfo(self,dy,x)
                    rule.Modes(self)
                    rule.gameinfo(self)
                    value.regretuselis.append(eval(str(value.board_lists)))
                    rule.AIprocess(self)
            elif value.play_count == 0 and value.info_lists[y][x] == 0:#换选棋子
                value.board_lists[value.play_tamp_y][value.play_tamp_x] = value.play_tampvalue
                self.peice_info(x,y,0)
                if value.board_lists[y][x] in value.team and [value.play_tamp_x,value.play_tamp_y] != [x,y]:
                    self.peice_info(x,y,1)
                    value.play_tampvalue = value.board_lists[y][x]
                    value.play_tamp_x,value.play_tamp_y = x,y
                    value.board_lists[y][x] = -1
                    value.play_count = 1
            else:
                value.play_count = 1 if value.play_count == 0 else 0#清除操作
    def fluent(self,dx,dy,flu=0,lis=[0.02,0.02,0.06,0.1,0.18,0.3,0.18,0.1,0.06,0.02,0.02,-0.06]):#移动流畅函数
        value.canvas.move(value.peice_lists[value.play_tampvalue],lis[flu]*dx,lis[flu]*dy)
        if flu < 11:
            value.canvas.after(10,self.fluent,dx,dy,flu+1)
    def peice_info(self,x,y,count):#路径计算
        if count == 1:
            i = value.board_lists[y][x]
            if i in [0,16]:#将帅
                self.info(x,y,M=2)
                for sx,sy in zip([x+1,x-1,x,x],[y,y,y+1,y-1]):
                    if 0+7*(i//16)<=sy<=2+7*(i//16) and 3<=sx<=5:
                        try:
                            if value.board_lists[sy][sx] == -1:
                                self.info(sx,sy)
                            else:
                                self.info(sx,sy,M=1,i=i)
                        except:
                            pass
                start_y = y+(-1)**(i//16)# “白脸将” #
                key_y = 7*(1-(i//16))
                for sy in range(start_y,start_y+9*(-1)**(i//16),(-1)**(i//16)):
                    if key_y<=sy<=key_y+2:
                        if value.board_lists[sy][x] in [0,16]:
                            self.info(x,sy,M=1,i=i)
                    else:
                        try:
                            if value.board_lists[sy][x] != -1:
                                break
                        except:
                            break
            if i in [1,2,17,18]:#士仕
                self.info(x,y,M=2)
                for sx,sy in zip([x+1,x-1,x+1,x-1],[y+1,y-1,y-1,y+1]):
                    if  0+7*(i//17)<=sy<=2+7*(i//17) and 3<=sx<=5:
                        try:
                            if value.board_lists[sy][sx] == -1:
                                self.info(sx,sy)
                            else:
                                self.info(sx,sy,M=1,i=i)
                        except:
                            pass
            elif i in [3,4,19,20]:#象相(撇腿)
                self.info(x,y,M=2)
                for sx,sy in zip([x+2,x-2,x+2,x-2],[y+2,y-2,y-2,y+2]):
                    if  0+5*(i//19)<=sy<=4+5*(i//19) and 0<=sx<=8 and value.board_lists[(sy+y)//2][(sx+x)//2] == -1:
                        try:
                            if value.board_lists[sy][sx] == -1:
                                self.info(sx,sy)
                            else:
                                self.info(sx,sy,M=1,i=i)
                        except:
                            pass
            elif i in [5,6,21,22]:#马(撇腿)
                self.info(x,y,M=2)
                for sx,sy in zip([x+2,x+2,x-2,x-2,x+1,x+1,x-1,x-1],[y+1,y-1,y+1,y-1,y+2,y-2,y+2,y-2]):
                    if  0<=sy<=9 and 0<=sx<=8 and value.board_lists[round((sy+2*y)/3)][round((sx+2*x)/3)] == -1:
                        try:
                            if value.board_lists[sy][sx] == -1:
                                self.info(sx,sy)
                            else:
                                self.info(sx,sy,M=1,i=i)
                        except:
                            pass
            elif i in [7,8,23,24]:#车
                self.info(x,y,M=2)
                for lis in [range(1,10),range(-1,-10,-1)]:
                        for d in lis:
                            try:
                                if x+d>=0:
                                    if value.board_lists[y][x+d] == -1:
                                        self.info(x+d,y)
                                    else:
                                        self.info(x+d,y,M=1,i=i);break
                                else:
                                    break
                            except:
                                pass
                        for d in lis:
                            try:
                                if y+d>=0:
                                    if value.board_lists[y+d][x] == -1:
                                        self.info(x,y+d)
                                    else:
                                        self.info(x,y+d,M=1,i=i);break
                                else:
                                    break
                            except:
                                pass
            elif i in [9,10,25,26]:#炮
                self.info(x,y,M=2)
                for lis in [range(1,10),range(-1,-10,-1)]:
                    self.pao_c = 0
                    for d in lis:
                        try:
                            if x+d>=0:
                                if value.board_lists[y][x+d] == -1 and self.pao_c == 0:
                                    self.info(x+d,y)
                                elif value.board_lists[y][x+d] != -1:
                                    self.pao_c += 1
                                if self.pao_c == 2:
                                    self.info(x+d,y,M=1,i=i)
                                    break
                            else:
                                break
                        except:
                            pass
                    self.pao_c = 0
                    for d in lis:
                        try:
                            if y+d>=0:
                                if value.board_lists[y+d][x] == -1 and self.pao_c == 0:
                                    self.info(x,y+d)
                                elif value.board_lists[y+d][x] != -1:
                                    self.pao_c += 1
                                if self.pao_c == 2:
                                    self.info(x,y+d,M=1,i=i)
                                    break
                            else:
                                break
                        except:
                            pass
            elif i in [11,12,13,14,15,27,28,29,30,31]:#卒兵
                self.info(x,y,M=2)
                if (y<5 and i//27==0)or(4<y and i//27==1):
                    sy = y+(-1)**(i//27)
                    try:
                        if value.board_lists[sy][x] == -1:
                            self.info(x,sy)
                        else:
                            self.info(x,sy,M=1,i=i)
                    except:
                        pass
                elif ((5<=y<=9 and i//27==0)or(0<=y<=4 and i//27==1))and 0<=x<=8:
                    dy = y+(-1)**(i//27)
                    for sx,sy in zip([x-1,x,x+1],[y,dy,y]):
                        try:
                            if value.board_lists[sy][sx] == -1:
                                self.info(sx,sy)
                            else:
                                self.info(sx,sy,M=1,i=i)
                        except:
                            pass
        else:#删除显示
            for i in value.templists:
                value.canvas.delete(i)
            value.info_lists = [[0,0,0,0,0,0,0,0,0],
                                [0,0,0,0,0,0,0,0,0],
                                [0,0,0,0,0,0,0,0,0],
                                [0,0,0,0,0,0,0,0,0],
                                [0,0,0,0,0,0,0,0,0],
                                [0,0,0,0,0,0,0,0,0],
                                [0,0,0,0,0,0,0,0,0],
                                [0,0,0,0,0,0,0,0,0],
                                [0,0,0,0,0,0,0,0,0],
                                [0,0,0,0,0,0,0,0,0]]
    def info(self,sx,sy,M=0,i=None):#路径显示
        if M == 0:#路径
            value.info_lists[sy][sx] = 1
            s_x,s_y = sx*50+280,sy*50+25
            value.play_tampvalue = value.canvas.create_rectangle(s_x-10,s_y-10,s_x+10,s_y+10,outline=value.colorlis[7],width=2)
        elif M == 1:#敌人
            if (0<=i<=15 and value.board_lists[sy][sx]>15)or(i>15 and 0<=value.board_lists[sy][sx]<=15):
                value.info_lists[sy][sx] = 2
                s_x,s_y = sx*50+280,sy*50+25
                value.play_tampvalue = value.canvas.create_rectangle(s_x-25,s_y-25,s_x+25,s_y+25,outline=value.colorlis[8],width=2)
        elif M == 2:#自己
            s_x,s_y = sx*50+280,sy*50+25
            value.play_tampvalue = value.canvas.create_rectangle(s_x-25,s_y-25,s_x+25,s_y+25,outline=value.colorlis[9],width=2)
        value.templists.append(value.play_tampvalue)

【buttonbind.py】

# 关联处理 #
from tkinter import *
from value import value
from buttonfunction import function
from initialization import initialization
class buttonbind:
  def __init__(self):
    self.changelis = ['change1','change2','change3']
    value.game.bind('<Button-1>',lambda event:self.buttonchange(event,1,mode=2))#按下
    value.canvas.bind('<Motion>',lambda event:self.buttonchange(event,0,mode=1))#经过及离开
    value.canvas.bind('<B1-Motion>',lambda event:self.buttonchange(event,1,mode=2))#按下
    value.canvas.bind('<ButtonRelease-1>',lambda event:self.buttonchange(event,0,0,0))#松开
    value.game.bind('<Any-KeyPress>',self.keypress_bind)#键盘响应
    self.setbind()
    initialization.button_initialization(self)#按钮初始化
  def buttonchange(self,event,change,mode=0,m=''):
    x,y = event.x,event.y
    change = self.changelis[change]
    if  (720<=x<=935 and 320<=y<=355)or m=='s':#关联“设置”按钮
      initialization.buttonchange(self,1,change)
      if m in ['s',0]:
        function.b1_func(self)
    elif(720<=x<=935 and 380<=y<=415)or m=='r':#关联“悔棋”按钮
      initialization.buttonchange(self,2,change)
      if m in ['r',0]:
        function.b2_func(self)
    elif(720<=x<=935 and 440<=y<=475)or m=='q':#关联“退出”按钮
      initialization.buttonchange(self,3,change)
      if m in ['q',0]:
        function.b3_func(self)
    elif (20<=x<=235 and 320<=y<=355)or m=='h':#关联“帮助”按钮
      initialization.buttonchange(self,4,change)
      if m in ['h',0]:
        function.b4_func(self)
    elif (20<=x<=235 and 380<=y<=415)or m=='a':#关联“重新开始”按钮
      initialization.buttonchange(self,5,change)
      if m in ['a',0]:
        function.b5_func(self)
    elif (20<=x<=235 and 440<=y<=475)or m=='m':#关联“制作人员”按钮
      initialization.buttonchange(self,6,change)
      if m in ['m',0]:
        function.b6_func(self)
    elif mode == 1:
      initialization.buttonchange(self,0,'change3')#关联离开按钮
    elif mode == 2:
      self.buttonchange(event,0,mode=1)#按下
  def keypress_bind(self,event,count=0):#键盘响应
    m = event.char
    if count == 0:
      if m == 's':
        initialization.buttonchange(self,1,'change1')
      elif m == 'r':
        initialization.buttonchange(self,2,'change1')
      elif m == 'q':
        initialization.buttonchange(self,3,'change1')
      elif m == 'h':
        initialization.buttonchange(self,4,'change1')
      elif m == 'i':
        initialization.buttonchange(self,5,'change1')
      elif m == 'm':
        initialization.buttonchange(self,6,'change1')
      value.game.after(1,self.keypress_bind,event,1)
    elif count == 1:
      self.buttonchange(event,0,0,m)
      value.game.after(80,self.keypress_bind,event,2)
    else:
      self.buttonchange(event,0,mode=1)
  def setbind(self):
    for i in value.slis+[value.sbt1,value.sbt2]:
      i.bind('<Enter>',lambda event,i=i:enter(i))
      i.bind('<Leave>',lambda event,i=i:leave(i))
    def enter(i):
      i.config(bg=value.colorlis[4])
    def leave(i):
      i.config(bg=value.colorlis[3])

【buttonfunction.py】

# 按钮功能 #
from tkinter import *
from rule import rule
from value import value
from setpage import setpage
from initialization import initialization
class function:
  def b1_func(self):#“设置”按钮
    for i in value.slis:
      i.place(width=200,height=50,x=30,y=value.slis.index(i)*50+70)
    for i in value.slis:
      i.config(command=lambda i=i:setpage.set_button(self,value.slis.index(i)+1))
    value.sbt1.config(command=lambda:func(2))
    value.sbt2.config(command=lambda:reset())
    def func(m,c=0,flulis=value.flulis):#页面切换
      if m == 1:
        x1,x2 = -960*flulis[c],960*(1-flulis[c])
      elif m==2:
        x1,x2 = 960*(flulis[c]-1),960*flulis[c]
      value.canvas.place(width=960,height=500,x=x1)
      value.set_canvas.place(width=960,height=500,x=x2)
      if c == 7 and value.step == 0:
        rule.pleaseprocess(self)
        rule.gameinfo(self)
      if c<14:
        value.game.after(30,func,m,c+1)
    def reset():pass########################
    func(1)
  def b2_func(self):#“悔棋”按钮
    if len(value.steptextlis) > 1:
      try:
        if len(value.steptextlis) > 12:
          for i in value.steptextlis:
            value.canvas2.move(i,0,250-len(value.steptextlis)*20-value.firststep)
          value.firststep = 250-len(value.steptextlis)*20
      except:
        pass
      for i in value.steptextlis:
        value.canvas2.move(i,0,40)
      value.canvas2.delete(value.steptextlis[-1])
      value.canvas2.delete(value.steptextlis[-2])
      value.steptextlis = value.steptextlis[:-2]
      value.firststep += 40
      value.step -= 2
      for i in value.peice_lists:
        value.canvas.delete(i)
      value.board_lists = eval(str(value.regretuselis[-3]))
      initialization.peice_initialization(self)
      value.regretuselis = value.regretuselis[:-2]
      value.info_lists = [[0]*9 for _ in range(10)]
      for i in value.templists:
        value.canvas.delete(i)
      value.templists = []
      value.play_count = 0
      value.play_temp_x,value.play_temp_y = -2,-2
      value.play_tempvalue = -2
      value.DEAD = 0
      value.regret += 1
      rule.gameinfo(self)
  def b3_func(self):#“退出”按钮
    value.game.quit()
  def b4_func(self):#“帮助”按钮
    value.help_canvas.bind('<Button-1>',lambda event:func(2))
    def func(m,c=0,flulis=value.flulis):#页面切换
      if m == 1:
        x1,x2 = 960*flulis[c],960*(flulis[c]-1)
      elif m==2:
        x1,x2 = 960*(1-flulis[c]),-960*flulis[c]
      value.canvas.place(width=960,height=500,x=x1)
      value.help_canvas.place(width=960,height=500,x=x2)
      if c<14:
        value.game.after(30,func,m,c+1)
    func(1)
  def b5_func(self):#“重新开始”按钮
    value.board_lists =[[ 7, 5, 3, 1, 0, 2, 4, 6, 8],
              [-1,-1,-1,-1,-1,-1,-1,-1,-1],
              [-1, 9,-1,-1,-1,-1,-1,10,-1],
              [11,-1,12,-1,13,-1,14,-1,15],
              [-1,-1,-1,-1,-1,-1,-1,-1,-1],
              [-1,-1,-1,-1,-1,-1,-1,-1,-1],
              [27,-1,28,-1,29,-1,30,-1,31],
              [-1,25,-1,-1,-1,-1,-1,26,-1],
              [-1,-1,-1,-1,-1,-1,-1,-1,-1],
              [23,21,19,17,16,18,20,22,24]]
    value.info_lists = [[0]*9 for _ in range(10)]
    for i in value.peice_lists:
      value.canvas.delete(i)
    for i in value.templists:
      value.canvas.delete(i)
    initialization.peice_initialization(self)
    value.templists = []
    value.play_count = 0
    value.play_temp_x,value.play_temp_y = -2,-2
    value.play_tempvalue = -2
    value.DEAD = 0
    for i in value.steptextlis:
      value.canvas2.delete(i)
    value.steptextlis = []
    value.firststep = 250
    value.step = 0
    value.r_please,value.b_please = '无','无'
    for i in range(6):
      value.p_r[i] == 0
      value.p_b[i] == 0
    value.regret = 0
    value.regretuselis = [eval(str(value.board_lists))]
    value.player = '红方' if value.first == '黑方' else '黑方'
    rule.Modes(self)
    rule.gameinfo(self)
  def b6_func(self):#“制作人员”按钮
    text = value.make_canvas2.create_text(150,580,text=value.maketext,font=('华文新魏',20),fill='yellow',justify='center')
    value.make_canvas.bind('<Button-1>',lambda event:func(2))
    value.make_canvas2.bind('<Button-1>',lambda event:func(2))
    value.make_canvas2.bind('<Enter>',lambda event:speed(0))
    value.make_canvas2.bind('<Leave>',lambda event:speed(1))
    def speed(n):
      value.textspeed = 0 if n == 0 else -1
    def makefunc(i=580):
      value.make_canvas2.move(text,0,value.textspeed)
      if i>-360:
        value.make_canvas2.after(60,makefunc,i-1)
    def func(m,c=0,flulis=value.flulis):#页面切换
      if m == 1:
        x1,x2 = 960*flulis[c],960*(flulis[c]-1)
      elif m == 2:
        x1,x2 = 960*(1-flulis[c]),-960*flulis[c]
        if c == 14:
          value.make_canvas2.delete(text)
      value.canvas.place(width=960,height=500,x=x1)
      value.make_canvas.place(width=960,height=500,x=x2)
      if c<14:
        value.game.after(30,func,m,c+1)
      else:
        makefunc()
    func(1)

【setpage.py】

# 设置页面 #
from tkinter import *
from value import value
class setpage:
  def set_button(self,n):
    try:#切换时删除之前的
      value.text_canvas.unbind('<Button-1>')
      value.text_canvas.unbind('<B1-Motion>')
      value.text_canvas.unbind('<Motion>')
      value.text_canvas.unbind('<ButtonRelease-1>')
      for i in value.s1_+value.s2_+value.s3_+value.s4_+value.s5_+value.s6_+value.s7_+value.s8_:
        value.text_canvas.delete(i)
    except:pass
    if n == 1:#模式设置
      a = value.text_canvas.create_text(100,25,text='模式设置',font=('华文新魏',25))
      b = value.text_canvas.create_line(30,50,680,50,fill=value.colorlis[0])
      c = value.text_canvas.create_rectangle(30,60,130,90,outline=value.colorlis[1])
      d = value.text_canvas.create_text(80,75,text='人机模式',font=('华文新魏',15))
      e = value.text_canvas.create_rectangle(150,60,250,90,outline=value.colorlis[1])
      f = value.text_canvas.create_text(200,75,text='对弈模式',font=('华文新魏',15))
      g = value.text_canvas.create_rectangle(270,60,370,90,outline=value.colorlis[1])
      h = value.text_canvas.create_text(320,75,text='机机模式',font=('华文新魏',15))
      i = value.text_canvas.create_rectangle(390,60,490,90,outline=value.colorlis[1])
      j = value.text_canvas.create_text(440,75,text='网络模式',font=('华文新魏',15))
      k = value.text_canvas.create_rectangle(510,60,610,90,outline=value.colorlis[1])
      l = value.text_canvas.create_text(560,75,text='闯关模式',font=('华文新魏',15))
      m = value.text_canvas.create_rectangle(30,100,680,200,outline=value.colorlis[1])#描述框
      n = value.text_canvas.create_text(180,220,text='(只有未下棋时才可设置该选项!)',font=('华文新魏',15))
      text1 = '人类与电脑之间的决斗!\n你以为你能战胜电脑吗?不!你错了!\n真正的答案是:我也不知道!'
      text2 = '人与人之间的对决!\n不会吧,不会吧,居然有人认为有和棋?\n这只是场你死我活的战斗!'
      text3 = '电脑和电脑战斗!\n有些人啊,就喜欢坐在那儿看戏!\n这明明不关你的事,这只是个烧电脑的实验罢了!'
      text4 = '想和网上的朋友玩,那就来这里吧!\n通过局域网的方式,你将和对面的那个傻子对局!\n啊对对对,对面也在和傻子(你)对局!'
      text5 = '接手残局,勇闯鬼门关!\n你今天要是走不出鬼门关,就别回来了!\n因为你回不来了!'
      text = [text1,text2,text3,text4,text5]
      value.text_canvas.itemconfig([d,f,h,j,l][value.modelis.index(value.mode)],fill=value.colorlis[6])
      txt = value.text_canvas.create_text(355,150,text=text[value.modelis.index(value.mode)],font=('华文新魏',15),justify='center')
      value.s1_ = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,txt]
      def callback11(event):
        for s,t in zip(range(30,511,120),[d,f,h,j,l]):
          if s<=event.x<=s+100 and 60<=event.y<=90 and value.step == 0:
            for z in [d,f,h,j,l]:
              value.text_canvas.itemconfig(z,fill='black')
            value.text_canvas.itemconfig(t,fill=value.colorlis[6])
            value.text_canvas.itemconfig(txt,text=text[(s-30)//120])
            value.mode = value.modelis[(s-30)//120]
      def callback12(event):
        if 30<=event.x<130 and 60<=event.y<=90:
          value.text_canvas.itemconfig(c,fill=value.colorlis[4])
        elif 150<=event.x<250 and 60<=event.y<=90:
          value.text_canvas.itemconfig(e,fill=value.colorlis[4])
        elif 270<=event.x<370 and 60<=event.y<=90:
          value.text_canvas.itemconfig(g,fill=value.colorlis[4])
        elif 390<=event.x<490 and 60<=event.y<=90:
          value.text_canvas.itemconfig(i,fill=value.colorlis[4])
        elif 510<=event.x<610 and 60<=event.y<=90:
          value.text_canvas.itemconfig(k,fill=value.colorlis[4])
        else:
          for z in [c,e,g,i,k]:
            value.text_canvas.itemconfig(z,fill=value.colorlis[3])
      value.text_canvas.bind('<ButtonRelease-1>',callback11)
      value.text_canvas.bind('<Motion>',callback12)
    elif n == 2:#棋局设置
      a = value.text_canvas.create_text(100,25,text='棋局设置',font=('华文新魏',25))
      b = value.text_canvas.create_line(30,50,680,50,fill=value.colorlis[0])
      c = value.text_canvas.create_text(70,75,text='先下棋方',font=('华文新魏',15))
      d = value.text_canvas.create_rectangle(30,100,130,130,outline=value.colorlis[0])
      e = value.text_canvas.create_text(80,115,text='红方',font=('华文新魏',15))
      f = value.text_canvas.create_rectangle(150,100,250,130,outline=value.colorlis[0])
      g = value.text_canvas.create_text(200,115,text='黑方',font=('华文新魏',15))
      h = value.text_canvas.create_text(180,360,text='(只有未下棋时才可设置该选项!)',font=('华文新魏',15))
      i = value.text_canvas.create_text(70,160,text='让子设置',font=('华文新魏',15))
      j = value.text_canvas.create_text(50,200,text='黑方',font=('华文新魏',15))
      k = value.text_canvas.create_text(50,270,text='红方',font=('华文新魏',15))
      j1= value.text_canvas.create_rectangle(30,220,130,250,outline=value.colorlis[0])
      j2= value.text_canvas.create_rectangle(140,220,240,250,outline=value.colorlis[0])
      j3= value.text_canvas.create_rectangle(250,220,350,250,outline=value.colorlis[0])
      j4= value.text_canvas.create_rectangle(360,220,460,250,outline=value.colorlis[0])
      j5= value.text_canvas.create_rectangle(470,220,570,250,outline=value.colorlis[0])
      j6= value.text_canvas.create_rectangle(580,220,680,250,outline=value.colorlis[0])
      k1= value.text_canvas.create_rectangle(30,290,130,320,outline=value.colorlis[0])
      k2= value.text_canvas.create_rectangle(140,290,240,320,outline=value.colorlis[0])
      k3= value.text_canvas.create_rectangle(250,290,350,320,outline=value.colorlis[0])
      k4= value.text_canvas.create_rectangle(360,290,460,320,outline=value.colorlis[0])
      k5= value.text_canvas.create_rectangle(470,290,570,320,outline=value.colorlis[0])
      k6= value.text_canvas.create_rectangle(580,290,680,320,outline=value.colorlis[0])
      l1= value.text_canvas.create_text(80,235,text='左车',font=('华文新魏',15))
      l2= value.text_canvas.create_text(190,235,text='右车',font=('华文新魏',15))
      l3= value.text_canvas.create_text(300,235,text='左炮',font=('华文新魏',15))
      l4= value.text_canvas.create_text(410,235,text='右炮',font=('华文新魏',15))
      l5= value.text_canvas.create_text(520,235,text='左马',font=('华文新魏',15))
      l6= value.text_canvas.create_text(630,235,text='右马',font=('华文新魏',15))
      m1= value.text_canvas.create_text(80,305,text='左车',font=('华文新魏',15))
      m2= value.text_canvas.create_text(190,305,text='右车',font=('华文新魏',15))
      m3= value.text_canvas.create_text(300,305,text='左炮',font=('华文新魏',15))
      m4= value.text_canvas.create_text(410,305,text='右炮',font=('华文新魏',15))
      m5= value.text_canvas.create_text(520,305,text='左马',font=('华文新魏',15))
      m6= value.text_canvas.create_text(630,305,text='右马',font=('华文新魏',15))
      value.s2_ = [a,b,c,d,e,f,g,h,i,j,k,j1,j2,j3,j4,j5,j6,k1,k2,k3,k4,k5,k6,l1,l2,l3,l4,l5,l6,m1,m2,m3,m4,m5,m6]
      value.text_canvas.itemconfig([e,g][value.playerlis.index(value.first)//1],fill=value.colorlis[6])
      for x,y,k in zip(value.p_r,value.p_b,range(6)):
        if x == 1:
          value.text_canvas.itemconfig([m1,m2,m3,m4,m5,m6][k],fill=value.colorlis[6])
        if y == 1:
          value.text_canvas.itemconfig([l1,l2,l3,l4,l5,l6][k],fill=value.colorlis[6])
      def please(w,n,m):#w哪一方;n第几个;m修改值
        if w == 'r':
          value.p_r[n] = m
        if w == 'b':
          value.p_b[n] = m
      def callback21(event):
        if value.step == 0 and value.mode not in ['网络','闯关']:
          for s,t in zip([30,150],[e,g]):
            if s<=event.x<=s+100 and 100<=event.y<=130:
              for z in [e,g]:
                value.text_canvas.itemconfig(z,fill='black')
              value.text_canvas.itemconfig(t,fill=value.colorlis[6])
              value.first = value.playerlis[(s-30)//120]
              value.player = value.first
              if value.mode in ['对弈','网络']:
                if value.player == '红方':
                  value.team = value.r_team
                else:
                  value.team = value.b_team
              elif value.mode == '机机':value.team = []
              else:
                if value.player == '红方':
                  value.team = value.r_team
                else:
                  value.team = []
          for s,t1,t2 in zip(range(30,581,110),[l1,l2,l3,l4,l5,l6],[m1,m2,m3,m4,m5,m6]):
            if s<=event.x<=s+100 and 220<=event.y<=250:
              if value.text_canvas.itemcget(t1,'fill') == 'black':
                value.text_canvas.itemconfig(t1,fill=value.colorlis[6])
                please('b',(s-30)//110,1)
              else:
                value.text_canvas.itemconfig(t1,fill='black')
                please('b',(s-30)//110,0)
            if s<=event.x<=s+100 and 290<=event.y<=320:
              if value.text_canvas.itemcget(t2,'fill') == 'black':
                value.text_canvas.itemconfig(t2,fill=value.colorlis[6])
                please('r',(s-30)//110,1)
              else:
                value.text_canvas.itemconfig(t2,fill='black')
                please('r',(s-30)//110,0)
      def callback22(event):
        if 30<=event.x<=130 and 100<=event.y<=130:
          value.text_canvas.itemconfig(d,fill=value.colorlis[4])
        elif 150<=event.x<=250 and 100<=event.y<=130:
          value.text_canvas.itemconfig(f,fill=value.colorlis[4])
        elif 30<=event.x<=130 and 220<=event.y<=250:
          value.text_canvas.itemconfig(j1,fill=value.colorlis[4])
        elif 140<=event.x<=240 and 220<=event.y<=250:
          value.text_canvas.itemconfig(j2,fill=value.colorlis[4])
        elif 250<=event.x<=350 and 220<=event.y<=250:
          value.text_canvas.itemconfig(j3,fill=value.colorlis[4])
        elif 360<=event.x<=460 and 220<=event.y<=250:
          value.text_canvas.itemconfig(j4,fill=value.colorlis[4])
        elif 470<=event.x<=570 and 220<=event.y<=250:
          value.text_canvas.itemconfig(j5,fill=value.colorlis[4])
        elif 580<=event.x<=680 and 220<=event.y<=250:
          value.text_canvas.itemconfig(j6,fill=value.colorlis[4])
        elif 30<=event.x<=130 and 290<=event.y<=320:
          value.text_canvas.itemconfig(k1,fill=value.colorlis[4])
        elif 140<=event.x<=240 and 290<=event.y<=320:
          value.text_canvas.itemconfig(k2,fill=value.colorlis[4])
        elif 250<=event.x<=350 and 290<=event.y<=320:
          value.text_canvas.itemconfig(k3,fill=value.colorlis[4])
        elif 360<=event.x<=460 and 290<=event.y<=320:
          value.text_canvas.itemconfig(k4,fill=value.colorlis[4])
        elif 470<=event.x<=570 and 290<=event.y<=320:
          value.text_canvas.itemconfig(k5,fill=value.colorlis[4])
        elif 580<=event.x<=680 and 290<=event.y<=320:
          value.text_canvas.itemconfig(k6,fill=value.colorlis[4])
        else:
          for z in [d,f,j1,j2,j3,j4,j5,j6,k1,k2,k3,k4,k5,k6]:
            value.text_canvas.itemconfig(z,fill=value.colorlis[3])
      value.text_canvas.bind('<ButtonRelease-1>',callback21)
      value.text_canvas.bind('<Motion>',callback22)
    elif n == 3:#闯关设置
      a = value.text_canvas.create_text(100,25,text='闯关设置',font=('华文新魏',25))
      b = value.text_canvas.create_line(30,50,680,50)
      value.s3_ = [a,b]
    elif n == 4:#主题设置
      a = value.text_canvas.create_text(100,25,text='主题设置',font=('华文新魏',25))
      b = value.text_canvas.create_line(30,50,680,50,fill=value.colorlis[0])
      c = value.text_canvas.create_text(70,75,text='颜色主题',font=('华文新魏',15))
      d= value.text_canvas.create_rectangle(30,100,130,130,outline=value.colorlis[0])
      e= value.text_canvas.create_rectangle(140,100,240,130,outline=value.colorlis[0])
      f= value.text_canvas.create_rectangle(250,100,350,130,outline=value.colorlis[0])
      g= value.text_canvas.create_rectangle(360,100,460,130,outline=value.colorlis[0])
      h= value.text_canvas.create_rectangle(470,100,570,130,outline=value.colorlis[0])
      i = value.text_canvas.create_text(80,115,text='系统默认',font=('华文新魏',15))
      j = value.text_canvas.create_text(190,115,text='黑白灰',font=('华文新魏',15))
      k = value.text_canvas.create_text(300,115,text='梦幻蓝',font=('华文新魏',15))
      l = value.text_canvas.create_text(410,115,text='和谐绿',font=('华文新魏',15))
      m = value.text_canvas.create_text(520,115,text='典雅粉',font=('华文新魏',15))
      n = value.text_canvas.create_text(120,155,text='效果展示(一部分)',font=('华文新魏',15))
      o = value.text_canvas.create_text(170,330,text='(该设置项将在游戏重启后生效)',font=('华文新魏',15))
      p = value.text_canvas.create_rectangle(30,180,680,300,fill=value.colorlis[3],outline=value.colorlis[1])
      q = value.text_canvas.create_rectangle(280,210,430,270,outline=value.colorlis[5],fill=value.colorlis[4],width=3)
      r = value.text_canvas.create_text(335,240,text='中国',font=('华文新魏',15))
      s = value.text_canvas.create_text(375,240,text='象棋',font=('华文新魏',15),fill=value.colorlis[6])
      value.s4_ = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s]
      value.text_canvas.itemconfig([i,j,k,l,m][value.theme-1],fill=value.colorlis[6])
      def callback41(event):
        if 30<=event.x<=130 and 100<=event.y<=130:
          value.text_canvas.itemconfig(d,fill=value.colorlis[4])
        elif 140<=event.x<=240 and 100<=event.y<=130:
          value.text_canvas.itemconfig(e,fill=value.colorlis[4])
        elif 250<=event.x<=350 and 100<=event.y<=130:
          value.text_canvas.itemconfig(f,fill=value.colorlis[4])
        elif 360<=event.x<=460 and 100<=event.y<=130:
          value.text_canvas.itemconfig(g,fill=value.colorlis[4])
        elif 470<=event.x<=570 and 100<=event.y<=130:
          value.text_canvas.itemconfig(h,fill=value.colorlis[4])
        else:
          for z in [d,e,f,g,h]:
            value.text_canvas.itemconfig(z,fill=value.colorlis[3])
      def callback42(event):
        for x in range(30,471,110):
          if x<=event.x<=x+100 and 100<=event.y<=130:
            for z in [i,j,k,l,m]:
              value.text_canvas.itemconfig(z,fill='black')
            value.text_canvas.itemconfig([i,j,k,l,m][(x-30)//110],fill=value.colorlis[6])
            value.theme = (x-30)//110+1
            with open('resources\\cache.txt','w') as infile:
              infile.write(str(value.theme))
            themeprocess(value.theme)
      def themeprocess(n):
        value.text_canvas.itemconfig(p,fill=value.colorlists[n-1][3],outline=value.colorlists[n-1][1])
        value.text_canvas.itemconfig(q,fill=value.colorlists[n-1][4],outline=value.colorlists[n-1][5])
        value.text_canvas.itemconfig(s,fill=value.colorlists[n-1][6])
      value.text_canvas.bind('<Motion>',callback41)
      value.text_canvas.bind('<ButtonRelease-1>',callback42)
    elif n == 5:#音效设置
      a = value.text_canvas.create_text(100,25,text='音效设置',font=('华文新魏',25))
      b = value.text_canvas.create_line(30,50,680,50)
      value.s5_ = [a,b]
    elif n == 6:#窗口设置
      self.x = int((1-value.alpha)*500+59)
      text1 = '设置范围为0~100,0为不透明,100为完全透明,默认为0(不透明)'
      a = value.text_canvas.create_text(100,25,text='窗口设置',font=('华文新魏',25))
      b = value.text_canvas.create_line(30,50,680,50,fill=value.colorlis[0])
      c = value.text_canvas.create_text(100,75,text='设置窗口透明度',font=('华文新魏',15))
      d = value.text_canvas.create_rectangle(30,100,680,150,outline=value.colorlis[0])
      e = value.text_canvas.create_line(60,125,590,125,fill=value.colorlis[0])
      f = value.text_canvas.create_rectangle(self.x,115,self.x+30,135,fill=value.colorlis[6])
      g = value.text_canvas.create_text(340,180,text=text1,font=('华文新魏',15))
      h = value.text_canvas.create_text(45,125,text='0',font=('华文新魏',15))
      i = value.text_canvas.create_text(610,125,text='100',font=('华文新魏',15))
      j = value.text_canvas.create_line(630,110,630,140,fill=value.colorlis[0])
      k = value.text_canvas.create_text(655,125,text=str((self.x-59)//5),font=('华文新魏',15),fill=value.colorlis[6])
      value.s7_ = [a,b,c,d,e,f,g,h,i,j,k]
      value.text_canvas.bind('<Button-1>',lambda event:callback61(event))
      value.text_canvas.bind('<B1-Motion>',lambda event:callback62(event))
      def callback61(event):
        self.temp_x = event.x
      def callback62(event):
        if 100<=event.y<=150 and 60<=event.x<=590:
          if (event.x-self.temp_x > 0 and self.x <=560)or(event.x-self.temp_x < 0 and self.x >=60):
            value.text_canvas.move(f,event.x-self.temp_x,0)
            self.x += event.x-self.temp_x
            self.temp_x = event.x
            v = (self.x-59)//5
            value.text_canvas.itemconfig(k,text=str(v))
            value.alpha = 1-v/100
            value.game.wm_attributes('-alpha',value.alpha)
    elif n == 7:#系统说明
      text1 = '游戏名称:中国象棋\n游戏版本:1.0\n人机内核:垃圾测试内核\n发布日期:2022/07/14\n运行内存:30MB左右\n占用空间:暂无数据'
      text2 = '更多详细信息:\n\nhttps://blog.csdn.net/weixin_62651706'
      text3 = '版权声明:\n\n        本游戏完全由小康独立开发,为该游戏的版权所有者,\n如盗窃程序内部资源,必究哦!'
      a = value.text_canvas.create_text(100,25,text='系统说明',font=('华文新魏',25))
      b = value.text_canvas.create_line(30,50,680,50,fill=value.colorlis[0])
      c = value.text_canvas.create_text(125,125,text=text1,font=('华文新魏',15))
      d = value.text_canvas.create_text(200,250,text=text2,font=('华文新魏',15))
      e = value.text_canvas.create_text(300,350,text=text3,font=('华文新魏',15))
      value.s7_ = [a,b,c,d,e]
    elif n == 8:#暂无设置
      a = value.text_canvas.create_text(100,25,text='暂无设置',font=('华文新魏',25))
      b = value.text_canvas.create_line(30,50,680,50,fill=value.colorlis[0])
      value.s8_ = [a,b]

【value.py】

# 初始化变量 #
from tkinter import *
class value:
    # 窗口变量 #
    game = Tk()#创建窗口
    game.title('中国象棋')#窗口标题
    game.geometry('960x500+150+100')#窗口大小及位置
    game.resizable(0,0)#窗口大小固定
    game.iconbitmap('resources\\icon.ico')#窗口图标
    canvas = Canvas(game,highlightthickness=0)#创建画布
    canvas2 = Canvas(canvas,highlightthickness=0)
    # 基本变量 #
    modelis   = ['人机','对弈','机机','网络','闯关']  #游戏模式
    mode      = modelis[1]              #默认模式
    levellis  = ['暂无数据','简单','普通','困难']   #人机难度
    level     = levellis[0]             #默认难度
    playerlis = ['红方','黑方']           #玩家列表
    player    = '红方'                #当前玩家
    first     = playerlis[0]            #先下棋方
    challenge = '暂无数据'              #闯关关数
    r_please  = '无'                 #红方让子
    b_please  = '无'                 #黑方让子
    regret    = 0                 #悔棋次数
    alpha     = 1                 #窗口透明
    max_depth = 3                 #搜索深度
    colorlis1  = ['black','black','white','lightyellow','lightgreen','springgreen','orange','yellow','red','white','springgreen']
    colorlis2  = ['black','black','white','white','grey','black','grey','grey','black','white','white']
    colorlis3  = ['blue','deepskyblue','skyblue','skyblue','deepskyblue','blue','white','deepskyblue','blue','skyblue','cyan']
    colorlis4  = ['darkgreen','green','white','lightgreen','yellowgreen','springgreen','white','green','darkgreen','lightgreen','springgreen']
    colorlis5  = ['purple','purple','white','pink','hotpink','fuchsia','red','pink','red','plum','plum']
                #字体颜色[0] 框架颜色[1] 按钮框按下[2] 浅背景[3] 深按钮背景[4] 高亮按钮框[5] 高亮文本[6] 路径色[7] 敌人标记[8] 自己标记[9] 鼠标位置显示[10]
    colorlists = [colorlis1,colorlis2,colorlis3,colorlis4,colorlis5]
    with open('resources\\cache.txt','r') as infile:data = infile.readline()
    theme = int(data)
    colorlis = colorlists[theme-1]
    # 游戏变量 #
    flulis = [0.01,0.03,0.07,0.14,0.24,0.39,0.67,0.82,0.92,0.99,1.03,1.05,1.06,1.04,1]
    info_lists = [[0]*9 for _ in range(10)]
    b_j,b_s1,b_s2,b_x1,b_x2,b_m1,b_m2,b_c1,b_c2,b_p1,b_p2,b_z1,b_z2,b_z3,b_z4,b_z5 = [0]*16
    r_j,r_s1,r_s2,r_x1,r_x2,r_m1,r_m2,r_c1,r_c2,r_p1,r_p2,r_z1,r_z2,r_z3,r_z4,r_z5 = [0]*16
    peice_lists =  [b_j,b_s1,b_s2,b_x1,b_x2,b_m1,b_m2,b_c1,b_c2,b_p1,b_p2,b_z1,b_z2,b_z3,b_z4,b_z5,
                    r_j,r_s1,r_s2,r_x1,r_x2,r_m1,r_m2,r_c1,r_c2,r_p1,r_p2,r_z1,r_z2,r_z3,r_z4,r_z5]
    board_lists =  [[ 7, 5, 3, 1, 0, 2, 4, 6, 8],#初始棋子摆法
                    [-1,-1,-1,-1,-1,-1,-1,-1,-1],
                    [-1, 9,-1,-1,-1,-1,-1,10,-1],
                    [11,-1,12,-1,13,-1,14,-1,15],
                    [-1,-1,-1,-1,-1,-1,-1,-1,-1],
                    [-1,-1,-1,-1,-1,-1,-1,-1,-1],
                    [27,-1,28,-1,29,-1,30,-1,31],
                    [-1,25,-1,-1,-1,-1,-1,26,-1],
                    [-1,-1,-1,-1,-1,-1,-1,-1,-1],
                    [23,21,19,17,16,18,20,22,24]]
    peices=['将','士','士','象','象','马','马','车','车','炮','炮','卒','卒','卒','卒','卒',
            '帅','仕','仕','相','相','马','马','车','车','炮','炮','兵','兵','兵','兵','兵']
    number = ['一','二','三','四','五','六','七','八','九']
    b_team = range(16)
    r_team = range(16,32)
    team = r_team
    step = 0
    stepcontent = ''
    templists = []
    play_count = 0
    play_temp_x,play_temp_y = -2,-2
    play_tempvalue = -2
    DEAD = 0
    steptextlis = []
    firststep = 250
    gameinfo_temp = None
    p_rc1,p_rc2,p_rp1,p_rp2,p_rm1,p_rm2 = [0,0,0,0,0,0]
    p_bc1,p_bc2,p_bp1,p_bp2,p_bm1,p_bm2 = [0,0,0,0,0,0]
    p_r = [p_rc1,p_rc2,p_rp1,p_rp2,p_rm1,p_rm2]#让子列表
    p_b = [p_bc1,p_bc2,p_bp1,p_bp2,p_bm1,p_bm2]
    regretuselis = [eval(str(board_lists))]
    # 图片资源 #
    background = PhotoImage(file='resources\\background.png')
    victory    = PhotoImage(file='resources\\victory.png')
    defeat     = PhotoImage(file='resources\\defeat.png')
    dead       = PhotoImage(file='resources\\dead.png')
    gank       = PhotoImage(file='resources\\gank.png')
    face       = PhotoImage(file='resources\\face.png')
    bigface    = PhotoImage(file='resources\\bigface.png')
    makebg     = PhotoImage(file='resources\\makebg.png')
    helpbg     = PhotoImage(file='resources\\helpbg.png')
    bglis = []#图片列表
    image_b_j  = PhotoImage(file='resources\\peices\\b_j.png')
    image_b_s1 = PhotoImage(file='resources\\peices\\b_s.png')
    image_b_s2 = PhotoImage(file='resources\\peices\\b_s.png')
    image_b_x1 = PhotoImage(file='resources\\peices\\b_x.png')
    image_b_x2 = PhotoImage(file='resources\\peices\\b_x.png')
    image_b_m1 = PhotoImage(file='resources\\peices\\b_m.png')
    image_b_m2 = PhotoImage(file='resources\\peices\\b_m.png')
    image_b_c1 = PhotoImage(file='resources\\peices\\b_c.png')
    image_b_c2 = PhotoImage(file='resources\\peices\\b_c.png')
    image_b_p1 = PhotoImage(file='resources\\peices\\b_p.png')
    image_b_p2 = PhotoImage(file='resources\\peices\\b_p.png')
    image_b_z1 = PhotoImage(file='resources\\peices\\b_z.png')
    image_b_z2 = PhotoImage(file='resources\\peices\\b_z.png')
    image_b_z3 = PhotoImage(file='resources\\peices\\b_z.png')
    image_b_z4 = PhotoImage(file='resources\\peices\\b_z.png')
    image_b_z5 = PhotoImage(file='resources\\peices\\b_z.png')
    image_r_j  = PhotoImage(file='resources\\peices\\r_j.png')
    image_r_s1 = PhotoImage(file='resources\\peices\\r_s.png')
    image_r_s2 = PhotoImage(file='resources\\peices\\r_s.png')
    image_r_x1 = PhotoImage(file='resources\\peices\\r_x.png')
    image_r_x2 = PhotoImage(file='resources\\peices\\r_x.png')
    image_r_m1 = PhotoImage(file='resources\\peices\\r_m.png')
    image_r_m2 = PhotoImage(file='resources\\peices\\r_m.png')
    image_r_c1 = PhotoImage(file='resources\\peices\\r_c.png')
    image_r_c2 = PhotoImage(file='resources\\peices\\r_c.png')
    image_r_p1 = PhotoImage(file='resources\\peices\\r_p.png')
    image_r_p2 = PhotoImage(file='resources\\peices\\r_p.png')
    image_r_z1 = PhotoImage(file='resources\\peices\\r_z.png')
    image_r_z2 = PhotoImage(file='resources\\peices\\r_z.png')
    image_r_z3 = PhotoImage(file='resources\\peices\\r_z.png')
    image_r_z4 = PhotoImage(file='resources\\peices\\r_z.png')
    image_r_z5 = PhotoImage(file='resources\\peices\\r_z.png')
    resourcelists = [image_b_j,image_b_s1,image_b_s2,image_b_x1,image_b_x2,image_b_m1,image_b_m2,image_b_c1,
                    image_b_c2,image_b_p1,image_b_p2,image_b_z1,image_b_z2,image_b_z3,image_b_z4,image_b_z5,
                    image_r_j, image_r_s1,image_r_s2,image_r_x1,image_r_x2,image_r_m1,image_r_m2,image_r_c1,
                    image_r_c2,image_r_p1,image_r_p2,image_r_z1,image_r_z2,image_r_z3,image_r_z4,image_r_z5]
    # 文本变量 #
    helptext = '- 游戏说明 -\n白框标识棋为当前选中棋\n黄框标识位为当前棋可走路径\n红框标识棋为当前棋可吃棋\n\
              \n- 游戏规则 -\n马走日;相走田;士走斜\n将、帅和士不可出九宫格\n车和炮直走,炮隔着吃子\n河前兵往前,河后左右前\n\
              \n- 快捷键 -\n设置(s)、悔棋(r)、退出(q)\n帮助(h)、重置(a)、制作人员(m)'
    maketext = '《中国象棋》\n\n\n作者:小康\n版本:1.0\n\
              \n- 开发说明 -\n\n语言:Python\n开发工具:Visual Studio\n代码量:约72KB\n启动文件:Luncher.py\n\
              \n- 更新时间 -\n\n2022/07/14\n\
              \n- 特别说明 -\n\n图片均来源于互联网\n\
              \n- 免责声明 -\n\n若有侵权,请联系我\n\
              \n- 联系邮箱 -\n\n392126563@qq.com\n\
              \n\n\n感谢您体验这款游戏!'
    # 界面变量 #
    help_canvas = Canvas(game,highlightthickness=0)# 帮助界面 #
    help_canvas.create_image(480,250,image=helpbg)
    help_canvas.create_text(482,62,text='游戏帮助',font=('华文新魏',60),fill='grey')
    help_canvas.create_text(480,60,text='游戏帮助',font=('华文新魏',60),fill='orange')
    help_canvas.create_text(481,291,text=helptext,font=('华文新魏',20),justify='center')
    help_canvas.create_text(480,290,text=helptext,font=('华文新魏',20),fill='white',justify='center')
    make_canvas = Canvas(game,highlightthickness=0)# 制作人员界面 #
    make_canvas.create_image(480,250,image=makebg)
    make_canvas.create_image(680,150,image=bigface)
    make_canvas2 = Canvas(make_canvas,highlightthickness=0)
    make_canvas2.place(width=300,height=150,x=420,y=260)
    make_canvas2.create_image(480-420,250-260,image=makebg)
    textspeed = -1#文本滚动速度
    set_canvas = Canvas(game,highlightthickness=0,bg=colorlis[3])# 设置界面 #
    set_canvas.create_rectangle(10,50,950,490,width=3,outline=colorlis[1])
    set_canvas.create_rectangle(15,55,945,485,outline=colorlis[1])
    set_canvas.create_line(230,70,230,470,fill=colorlis[1])
    set_canvas.create_rectangle(799,9,950,40,outline=colorlis[1])
    sbt1 = Button(set_canvas,text='返回',font=('华文新魏',17),bd=0,bg=colorlis[3])
    sbt1.place(width=150,height=30,x=800,y=10)
    set_canvas.create_rectangle(639,9,790,40,outline=colorlis[1])
    sbt2 = Button(set_canvas,text='重置',font=('华文新魏',17),bd=0,bg=colorlis[3])
    sbt2.place(width=150,height=30,x=640,y=10)
    text_canvas = Canvas(set_canvas,bg=colorlis[3],highlightthickness=0)
    text_canvas.place(width=700,height=400,x=231,y=70)
    s1 = Button(set_canvas,bd=0,bg=colorlis[3],font=('华文新魏',20),text='模式设置')
    s2 = Button(set_canvas,bd=0,bg=colorlis[3],font=('华文新魏',20),text='棋局设置')
    s3 = Button(set_canvas,bd=0,bg=colorlis[3],font=('华文新魏',20),text='闯关设置')
    s4 = Button(set_canvas,bd=0,bg=colorlis[3],font=('华文新魏',20),text='主题设置')
    s5 = Button(set_canvas,bd=0,bg=colorlis[3],font=('华文新魏',20),text='音效设置')
    s6 = Button(set_canvas,bd=0,bg=colorlis[3],font=('华文新魏',20),text='窗口设置')
    s7 = Button(set_canvas,bd=0,bg=colorlis[3],font=('华文新魏',20),text='系统说明')
    s8 = Button(set_canvas,bd=0,bg=colorlis[3],font=('华文新魏',20),text='暂无设置')
    slis = [s1,s2,s3,s4,s5,s6,s7,s8]
    s1_,s2_,s3_,s4_,s5_,s6_,s7_,s8_ = [],[],[],[],[],[],[],[]

【rule.py】

# 制定规则 #
from tkinter import *
from value import value
from copy import deepcopy
from AI import AI
class rule:
  def __init__(self):
    self.gameinfo()
  def stepinfo(self,dy,now_x):#棋谱记录
    v = value.play_tampvalue
    before_x = value.play_tamp_x
    try:
      if len(value.steptextlis) > 12:
        for i in value.steptextlis:
          value.canvas2.move(i,0,250-len(value.steptextlis)*20-value.firststep)
        value.firststep = 250-len(value.steptextlis)*20
    except:
      pass
    if 16<=v<=31:#“红方”情况
      player = '红方' if value.mode in ['对弈','网络','机机'] else '玩家'
      way = '进' if dy < 0 else '退' if dy > 0 else '平'
      num = value.number[-before_x-1]
      if way == '平':
        dis = value.number[-now_x-1]
      else:
        if value.peices[v] in ['马','相','仕']:
          dis = value.number[-now_x-1]
        else:
          dis = value.number[abs(dy)//50-1]
    if 0<=v<=15:#“黑方”情况
      player = '黑方' if value.mode in ['对弈','网络','机机'] else '电脑'
      way = '进' if dy > 0 else '退' if dy < 0 else '平'
      num = value.number[before_x]
      if way == '平':
        dis = value.number[now_x]
      else:
        if value.peices[v] in ['马','象','士']:
          dis = value.number[now_x]
        else:
          dis = value.number[abs(dy)//50-1]
    steptext = '[%s]%s  [%03d]'%(player,value.peices[v]+num+way+dis,value.step)
    s = value.canvas2.create_text(102,250,text=steptext,font=('楷体',15),fill=value.colorlis[0])
    value.steptextlis.append(s)
    for i in value.steptextlis:
      value.canvas2.move(i,0,-20)
    value.firststep -= 20
  def gameinfo(self):#信息显示
    try:
      value.canvas.delete(value.gameinfo_temp)
    except:
      pass
    gamecontent ='\n游戏模式: '+value.mode+'模式'\
          +'\n人机难度: '+value.level\
          +'\n闯关关数: '+value.challenge\
          +'\n'\
          +'\n先手方:   '+value.first\
          +'\n当前方:   '+value.player\
          +'\n'\
          +'\n红方让子: '+value.r_please\
          +'\n黑方让子: '+value.b_please\
          +'\n'\
          +'\n悔棋记录:  '+str(value.regret)+' 次'
    value.gameinfo_temp = value.canvas.create_text(130,160,text=gamecontent,font=('楷体',15),fill=value.colorlis[0])
  def pleaseprocess(self):#让子操作
    lis1 = [value.p_r,value.p_b]
    lis2 = [value.r_please,value.b_please]
    for i in [0,1]:#文字显示
      c = lis1[i][0]+lis1[i][1]
      p = lis1[i][2]+lis1[i][3]
      m = lis1[i][4]+lis1[i][5]
      if c+p+m == 0:
        lis2[i] = '无'
      else:
        lis2[i] = ''
        for a,b in zip([c,p,m],['车','炮','马']):
          lis2[i] += b if a != 0 else ''
        if c//2+p//2+m//2 != 0:
          lis2[i] += '双'
          for x,y in zip([c,p,m],['车','炮','马']):
            if x == 2:
              lis2[i] = lis2[i].replace(y,'')
              lis2[i] += y
    value.r_please,value.b_please = lis2
    for i,y,v in zip([0,1],[[-1,-1,-3,-3,-1,-1],[0,0,2,2,0,0]],[[23,24,25,26,21,22],[7,8,9,10,5,6]]):#实际操作
      if lis1[i][0] == 1 and value.board_lists[y[0]][0] != -1:#左车让子
        value.canvas.move(value.peice_lists[value.board_lists[y[0]][0]],0,600)
        value.regretuselis[0][y[0]][0] = -1
        value.board_lists[y[0]][0] = -1
      if lis1[i][0] == 0 and value.board_lists[y[0]][0] == -1:#左车恢复
        value.regretuselis[0][y[0]][0] = v[0]
        value.board_lists[y[0]][0] = v[0]
        value.canvas.move(value.peice_lists[value.board_lists[y[0]][0]],0,-600)
      if lis1[i][1] == 1 and value.board_lists[y[1]][-1] != -1:#右车让子
        value.canvas.move(value.peice_lists[value.board_lists[y[1]][-1]],0,600)
        value.regretuselis[0][y[1]][-1] = -1
        value.board_lists[y[1]][-1] = -1
      if lis1[i][1] == 0 and value.board_lists[y[1]][-1] == -1:#右车恢复
        value.regretuselis[0][y[1]][-1] = v[1]
        value.board_lists[y[1]][-1] = v[1]
        value.canvas.move(value.peice_lists[value.board_lists[y[1]][-1]],0,-600)
      if lis1[i][2] == 1 and value.board_lists[y[2]][1] != -1:#左炮让子
        value.canvas.move(value.peice_lists[value.board_lists[y[2]][1]],0,600)
        value.regretuselis[0][y[2]][1] = -1
        value.board_lists[y[2]][1] = -1
      if lis1[i][2] == 0 and value.board_lists[y[2]][1] == -1:#左炮恢复
        value.regretuselis[0][y[2]][1] = v[2]
        value.board_lists[y[2]][1] = v[2]
        value.canvas.move(value.peice_lists[value.board_lists[y[2]][1]],0,-600)
      if lis1[i][3] == 1 and value.board_lists[y[3]][-2] != -1:#右炮让子
        value.canvas.move(value.peice_lists[value.board_lists[y[3]][-2]],0,600)
        value.regretuselis[0][y[3]][-2] = -1
        value.board_lists[y[3]][-2] = -1
      if lis1[i][3] == 0 and value.board_lists[y[3]][-2] == -1:#右炮恢复
        value.regretuselis[0][y[3]][-2] = v[3]
        value.board_lists[y[3]][-2] = v[3]
        value.canvas.move(value.peice_lists[value.board_lists[y[3]][-2]],0,-600)
      if lis1[i][4] == 1 and value.board_lists[y[4]][1] != -1:#左马让子
        value.canvas.move(value.peice_lists[value.board_lists[y[4]][1]],0,600)
        value.regretuselis[0][y[4]][1] = -1
        value.board_lists[y[4]][1] = -1
      if lis1[i][4] == 0 and value.board_lists[y[4]][1] == -1:#左马恢复
        value.regretuselis[0][y[4]][1] = v[4]
        value.board_lists[y[4]][1] = v[4]
        value.canvas.move(value.peice_lists[value.board_lists[y[4]][1]],0,-600)
      if lis1[i][5] == 1 and value.board_lists[y[5]][-2] != -1:#右马让子
        value.canvas.move(value.peice_lists[value.board_lists[y[5]][-2]],0,600)
        value.regretuselis[0][y[5]][-2] = -1
        value.board_lists[y[5]][-2] = -1
      if lis1[i][5] == 0 and value.board_lists[y[5]][-2] == -1:#右马恢复
        value.regretuselis[0][y[5]][-2] = v[5]
        value.board_lists[y[5]][-2] = v[5]
        value.canvas.move(value.peice_lists[value.board_lists[y[5]][-2]],0,-600)
  def AIprocess(self):
    '''
    if value.mode in ['对弈','网络']:side = None
    elif value.mode in ['人机','闯关']:side = 'b' if value.player == '黑方' else None
    else:side = 'b' if value.player == '黑方' else 'r'
    '''
    def fluent(k,dx,dy,flu=0,lis=[0.02,0.02,0.06,0.1,0.18,0.3,0.18,0.1,0.06,0.02,0.02,-0.06]):
      value.canvas.move(value.peice_lists[k],lis[flu]*dx,lis[flu]*dy)
      if flu < 11:
        value.canvas.after(10,fluent,k,dx,dy,flu+1)
    def AImove():
      lis = AI(deepcopy(value.board_lists)).search('Red',10)
      y,x,sy,sx = lis[0],lis[1],lis[2],lis[3]
      if value.board_lists[sy][sx] != -1:
        value.canvas.move(value.peice_lists[value.board_lists[sy][sx]],0,600)
      value.board_lists[sy][sx] = value.board_lists[y][x]
      k = value.board_lists[y][x]
      dx,dy = (sx-x)*50,(sy-y)*50
      fluent(k,dx,dy)
      value.board_lists[y][x] = -1
      rule.Dead(self)
      value.step += 1
      rule.stepinfo(self,dy,sx)
      rule.Modes(self)
      rule.gameinfo(self)
      value.regretuselis.append(eval(str(value.board_lists)))
      #rule.AIprocess(self)
    if value.mode in ['人机','机机']:
      AImove()
  def Modes(self):
    if value.mode in ['人机','闯关']:#人机模式、闯关模式
      if value.player == '黑方':
        value.player = '红方'
        value.team = value.r_team
      else:
        value.player = '黑方'
        value.team = []
    elif value.mode == '机机':
      value.team = []#机机模式
    else:#对弈模式、网络模式
      if value.player == '黑方':
        value.player = '红方'
        value.team = value.r_team
      else:
        value.player = '黑方'
        value.team = value.b_team
  def Gank(self):#“将军”
    pass
  def Dead(self,j=0):#“绝杀”
    def func(c=0):
      if c == 1:
        value.canvas.delete(self.dead)
      else:
        value.canvas.after(1000,func,1)
    for i in value.board_lists:
      if 0 in i:
        j += 1
      if 16 in i:
        j += 1
    if j != 2:
      self.dead = value.canvas.create_image(480,250,image=value.dead)
      value.DEAD = 1
      func()

【AI.py】

# 人机AI #
from copy import deepcopy
class AI:
    def __init__(self,data):
        self.data = data
    def search(self,side,depth,data=[]):
        if depth == 0 or len(data) == 1:
            from pprint import pprint;pprint(data[0])
            return data[0]
        side = 'Black' if side == 'Red' else 'Red'
        if data == []:
            tree = []
            lis = self.data
            for i in range(10):
                for j in range(9):
                    if 0<= lis[i][j] <=15:
                        for x in range(10):
                            for y in range(9):
                                if self.Isstep(lis,'Black',i,j,x,y):
                                    temp = deepcopy(lis)
                                    temp[x][y] = -1
                                    temp[x][y],temp[i][j] = temp[i][j],temp[x][y]
                                    tree.append([i,j,x,y,temp,self.scores(temp)])
            data = tree
        else:
            for ind,l in enumerate(data):
                lis = l[4]
                scorelist = []
                for i in range(10):
                    for j in range(9):
                        if (side == 'Red' and 16<= lis[i][j] <= 31) or (side == 'Black' and 0<= lis[i][j] <=15):
                            for x in range(10):
                                for y in range(9):
                                    if self.Isstep(lis,side,i,j,x,y):
                                        temp = deepcopy(lis)
                                        temp[x][y] = -1
                                        temp[x][y],temp[i][j] = temp[i][j],temp[x][y]
                                        scorelist.append(self.scores(temp))
                tot,length = 0,0
                for i in scorelist:
                    if i != 0:
                        tot += i
                        length += 1
                if length:
                    data[ind][-1] += tot/length
                else:
                    data[ind][-1] += 0
                '''
                k = 1 if side == 'Black' else -1
                scorelist = [k*i for i in scorelist]
                key = abs(min(scorelist))
                tot = 0
                for i in scorelist:
                    tot += (i+key)**2
                ans = 0
                for i in scorelist:
                    try:
                        ans += i*((i+key)**2/tot)
                    except:
                        continue
                data[ind][-1] += ans*k
                '''
        return self.search(side,depth-1,sorted(data,key=lambda x:-x[-1])[0:round(0.618*len(data))])#[1:round(0.618*len(data))]
    def scores(self,data):#计算棋面得分
        lib = (99999,1500,1500,1000,1000,4000,4000,6000,6000,4000,4000,100,300,500,300,100)
        Black,Red = 0,0
        for i in data:
            for j in i:
                if 0<= j <= 15:
                    Black += lib[j]
                if 16<= j <= 31:
                    Red += lib[j-16]
        #return Black-Red
        if Black-Red > 0:
            return Black-Red*0.618
        else:
            return 0.618*Black-Red
    def Isstep(self,data,side,x,y,tx,ty):#判断是否可以走子
        i = data[x][y]
        if i != -1:
            if side == 'Black':
                lib = list(range(16,32))
            else:
                lib = list(range(16))
            if i in [0,16]:#将帅
                for sx,sy in zip([x+1,x-1,x,x],[y,y,y+1,y-1]):
                    if 0+7*(i//16)<=sx<=2+7*(i//16) and 3<=sy<=5:
                        if [tx,ty] == [sx,sy] and data[sx][sy] in [-1]+lib:
                            return True
            if i in [1,2,17,18]:#士仕
                for sx,sy in zip([x+1,x-1,x+1,x-1],[y+1,y-1,y-1,y+1]):
                    if  0+7*(i//17)<=sx<=2+7*(i//17) and 3<=sy<=5:
                        if [tx,ty] == [sx,sy] and data[sx][sy] in [-1]+lib:
                            return True
            elif i in [3,4,19,20]:#象相(撇腿)
                for sx,sy in zip([x+2,x-2,x+2,x-2],[y+2,y-2,y-2,y+2]):
                    if  0+5*(i//19)<=sx<=4+5*(i//19) and 0<=sy<=8 and data[(sx+x)//2][(sy+y)//2] == -1:
                        if [tx,ty] == [sx,sy] and data[sx][sy] in [-1]+lib:
                            return True
            elif i in [5,6,21,22]:#马(撇腿)
                for sx,sy in zip([x+2,x+2,x-2,x-2,x+1,x+1,x-1,x-1],[y+1,y-1,y+1,y-1,y+2,y-2,y+2,y-2]):
                    if  0<=sx<=9 and 0<=sy<=8 and data[round((sx+2*x)/3)][round((sy+2*y)/3)] == -1:
                        if [tx,ty] == [sx,sy] and data[sx][sy] in [-1]+lib:
                            return True
            elif i in [7,8,23,24]:#车
                for lis in [range(1,10),range(-1,-10,-1)]:
                        for d in lis:
                            if 9>=x+d>=0:
                                if data[x+d][y] != -1:
                                    if [tx,ty] != [x+d,y]:
                                        break
                                if data[x+d][y] in [-1]+lib:
                                    if [tx,ty] == [x+d,y]:
                                        return True
                                else:
                                    break
                        for d in lis:
                            if 8>=y+d>=0:
                                if data[x][y+d] != -1:
                                    if [tx,ty] != [x,y+d]:
                                        break
                                if data[x][y+d] in [-1]+lib:
                                    if [tx,ty] == [x,y+d]:
                                        return True
                                else:
                                    break
            elif i in [9,10,25,26]:#炮
                for lis in [range(1,10),range(-1,-10,-1)]:
                    pao_c = 0
                    for d in lis:
                        if 9>=x+d>=0:
                            if data[x+d][y] == -1 and pao_c == 0:
                                if [tx,ty] == [x+d,y]:
                                    return True
                            elif data[x+d][y] != -1:
                                pao_c += 1
                            if pao_c == 2:
                                if [tx,ty] == [x+d,y] and data[x+d][y] in lib:
                                    return True
                    pao_c = 0
                    for d in lis:
                        if 8>=y+d>=0:
                            if data[x][y+d] == -1 and pao_c == 0:
                                if [tx,ty] == [x,y+d]:
                                    return True
                            elif data[x][y+d] != -1:
                                pao_c += 1
                            if pao_c == 2:
                                if [tx,ty] == [x,y+d] and data[x][y+d] in lib:
                                    return True
            elif i in [11,12,13,14,15,27,28,29,30,31]:#卒兵
                if (x<5 and i//27==0)or(4<x and i//27==1):#未过河
                    sx = x+(-1)**(i//27)
                    if [tx,ty] == [sx,y] and data[sx][y] in [-1]+lib:
                        return True
                elif ((5<=x<=9 and i//27==0)or(0<=x<=4 and i//27==1))and 0<=y<=8:#已过河
                    dx = x+(-1)**(i//27)
                    for sx,sy in zip([x,dx,x],[y-1,y,y+1]):
                        if [tx,ty] == [sx,sy] and data[sx][sy] in [-1]+lib:
                            return True
        return False
目录
相关文章
|
26天前
QT实现植物大战僵尸中文版工具代码
QT实现植物大战僵尸中文版工具代码
|
1月前
|
IDE 数据可视化 开发工具
【Qt】—— Qt开发环境的搭建
【Qt】—— Qt开发环境的搭建
|
7月前
|
Linux Python
Python3,1行代码,制作GUI图形界面,果然被种草了。
Python3,1行代码,制作GUI图形界面,果然被种草了。
50 0
|
10月前
|
数据挖掘 Java Linux
【毕业设计之python系列】基于Python+GUI的在线音乐播放器的设计与实现
【毕业设计之python系列】基于Python+GUI的在线音乐播放器的设计与实现
342 0
|
10月前
|
Python
Tkinter模块GUI界面化编程实战(五)——大鱼吃小鱼游戏(含超详解及完整源码、完整程序免费下载链接)
Tkinter模块GUI界面化编程实战(五)——大鱼吃小鱼游戏(含超详解及完整源码、完整程序免费下载链接)
106 0
|
10月前
|
Python
Tkinter模块GUI界面化编程实战(三)——2048小游戏(含详解及完整源码、完整程序下载链接)
Tkinter模块GUI界面化编程实战(三)——2048小游戏(含详解及完整源码、完整程序下载链接)
129 0
|
10月前
|
前端开发 Python
Tkinter模块GUI界面化编程实战(六)——超级游戏盒子(含超详解及完整源码、完整程序免费下载链接)
Tkinter模块GUI界面化编程实战(六)——超级游戏盒子(含超详解及完整源码、完整程序免费下载链接)
118 0
|
10月前
|
Python
Python Qt GUI设计:做一款串口调试助手(实战篇—1)
Python Qt GUI设计系列博文终于到了实战篇,本篇博文将贯穿之前的基础知识点实现一款串口调试助手。
|
10月前
|
Python
Tkinter模块GUI界面化编程实战(二)—— 计算器(含详解及完整源码、完整程序下载链接)
Tkinter模块GUI界面化编程实战(二)—— 计算器(含详解及完整源码、完整程序下载链接)
93 0
|
10月前
|
Python
Tkinter模块GUI界面化编程实战(一)——登录界面(含详解及完整源码、完整程序下载链接)
Tkinter模块GUI界面化编程实战(一)——登录界面(含详解及完整源码、完整程序下载链接)
107 0