Python实现 人工智能 五子棋人机对战

这是一个使用Python和wxPython库实现的五子棋游戏,包含了人机对战功能。游戏界面简洁,玩家可以点击棋盘落子,而AI会根据棋盘局面计算最佳落子位置。AI的算法考虑了棋子的连线得分,以决定最优走法。当一方连成五子或堵住对方五子连珠时,游戏结束并显示胜者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目下载:
https://download.csdn.net/download/qq_45021180/15435774

项目目录:
在这里插入图片描述

ChessMain.py


import wx
from ChessData import Chess
from Point import Point


CellSize=40 # 棋盘单元格大小
MY=1
ENEMY=-1



class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, size=(650, 660), title="人机五子棋")
        self.Center()

        self.chess = Chess()  # 定义一个棋盘数据类
        self.DATA=self.chess.chessData


        self.panel = wx.Panel(parent=self)

        self.panel.Bind(wx.EVT_PAINT, self.PaintBackground)  # 绘图
        self.panel.Bind(wx.EVT_LEFT_DOWN, self.GoChess)  # 绑定鼠标左键消息
        self.picture = [wx.Bitmap("黑.png"), wx.Bitmap("白.png")]
        self.IsGoGame=True






        # self.StartGame()

    # 画背景函数
    def PaintBackground(self,event):
        dc = wx.PaintDC(self.panel)
        # 创造背景
        # brush = wx.Brush("white")
        # dc.SetBackground(brush)
        dc.Clear()
        # 画方格线
        pen = wx.Pen(wx.Colour(0, 0, 0), 1, wx.SOLID)
        dc.SetPen(pen)
        for i in range(1,self.chess.Row+1):
            dc.DrawLine(CellSize, CellSize*i, 600, CellSize*i)
            dc.DrawLine(CellSize * i, CellSize, CellSize * i, 600)



    # 在x,y坐标绘制棋子
    def PaintPiece(self,point=None,Indentity=0):
        dc = wx.ClientDC(self.panel)
        if Indentity==MY:
            brush = wx.Brush("white")
            pictureTemp=self.picture[0]
        else:
            brush = wx.Brush("black")
            pictureTemp = self.picture[1]

        dc.SetBrush(brush)
        dc.DrawCircle((point.x+1)* CellSize, (point.y+1) * CellSize, 20)
        # image = wx.StaticBitmap(self.panel, -1, pictureTemp, size=(40, 40),
        #                         pos=(point.x * CellSize + CellSize / 2, point.y * CellSize + CellSize / 2))
        # image.SetPosition((x*Cell+Cell/2,y*Cell+Cell/2))

    # 玩家自己走棋
    def GoChess(self,event):
        #SetPosition(event.GetPosition())
        if self.IsGoGame:
            pos = event.GetPosition()  # 在x,y坐标绘制棋子
            x = int((pos.x - CellSize / 2) // CellSize)
            y = int((pos.y - CellSize / 2) // CellSize)
            if self.DATA[x][y] == 0:
                self.PaintPiece(Point(x,y), MY)
                self.DATA[x][y]=MY
                if self.chess.JudgeWin_Lose(Point(x,y),1):
                    self.win_loseDialog("win")
                    return

                # 对方下棋
                point=self.chess.DownChess(-1)
                print(point.x,point.y)
                self.PaintPiece(point,ENEMY)
                self.DATA[point.x][point.y] = ENEMY
                if self.chess.JudgeWin_Lose(point, -1):
                    self.win_loseDialog("lose")
            else:
                print("此位置不能下!")

            # 判断是否胜利
            self.IsGoGame=True

    # 输赢对话框
    def win_loseDialog(self, msg):
        if msg == "win":
            dlg = wx.MessageDialog(None, u"你胜利了!", u"恭喜", wx.YES_NO | wx.ICON_QUESTION)
            if dlg.ShowModal() == wx.ID_YES:
                self.Close(True)
            dlg.Destroy()
        if msg == "lose":
            dlg = wx.MessageDialog(None, u"你输了!", u"很遗憾", wx.YES_NO | wx.ICON_QUESTION)
            if dlg.ShowModal() == wx.ID_YES:
                self.Close(True)
            dlg.Destroy()



# 应用程序
class App(wx.App):
    def OnInit(self):
        frame=MyFrame()
        frame.Show()
        return True

    def OnExit(self):
        return 0

# 进入main函数运行:循环
if __name__=="__main__":
    app=App()
    app.MainLoop()

ChessData.py

from Point import Point


LEFT_RIGHT=0
TOP_BOTTOM=1
LEFTTOP_RIGHTBOTTOM=2
RIGHTTOP_LEFTBOTTOM=3

class Chess:
    def __init__(self):
        self.chessData=[[0 for i in range(15)] for i in range(15)] # 1表示自己 0表示空 -1表示对手
        self.Row=15
        self.Col=15

    def InitWindows(self):
        for i in range(self.Row):
            for j in range(self.Col):
                self.chessData[i][j]=0



    # 获取point点的下棋的得分,取最有力的分数下棋
    # 1. ------00000 5个棋 100000

    # 2. ------0000 4个无堵住 1600
    # 3. ------#0000# 4个堵住 10

    # 4. ------000 3个无堵住 400
    # 5. ------#000# 3个堵住 6

    # 6. ------00 2个无堵住 100
    # 7. ------#00# 2个堵住 4

    # 8. ------0 1个无堵住 10
    # 9. ------#0# 1个堵住 1
    def GetGrade(self,point,Indentity):
        grade = 0
        for k in range(4):
            count1,count2,isWall=self.Count(point, Indentity, k)
            tempGrade=0
            # 1. ------00000 5个棋 分数1000
            if count1>=5:
                return 100000
            # 2. ------0000 4个无堵住 100
            elif count1==4 and count2>=5:
                tempGrade=1600
            # 3. ------#0000# 4个堵住 10
            elif count1==4 and count2<5:
                tempGrade=20
            # 4. ------000 3个无堵住 60
            elif count1==3 and count2>=5:
                tempGrade=400
            # 5. ------#000# 3个堵住 6
            elif count1==3 and count2<5:
                tempGrade=10

            # 6. ------00 2个无堵住 40
            elif count1==2 and count2>=5:
                tempGrade=100
            # 7. ------#00# 2个堵住 4
            elif count1==2 and count2<5:
                tempGrade=4

            # 8. ------0 1个无堵住 10
            elif count1==1 and count2>=5:
                tempGrade=10
            # 9. ------#0# 1个堵住 1
            elif count1==1 and count2<5:
                tempGrade=1

            if isWall:
                grade+=(tempGrade)*0.3
            else:
                grade+=tempGrade
        return grade


    # 根据Indentity人工智能 下棋
    def DownChess(self,Indentity):
        MaxGrade=0
        MaxPoint=None
        point=Point(0,0)
        for i in range(self.Row):
            for j in range(self.Col):
                if self.chessData[i][j] != 0: continue
                point.x=i
                point.y=j
                myGrade=self.GetGrade(point,Indentity)
                enemyGrade = self.GetGrade(point, -Indentity)
                if myGrade>=100000: myGrade=199999
                if myGrade>=1600: myGrade+=1201
                if myGrade>=400: myGrade+=301
                if myGrade>=100: myGrade+=31
                grade=max(myGrade, enemyGrade)
                if grade>MaxGrade:
                    MaxGrade=grade
                    MaxPoint=Point(point.x,point.y)
        self.chessData[MaxPoint.x][MaxPoint.y]=Indentity
        return MaxPoint

    def Count(self,point,Indentity,direction):
        x = point.x
        y = point.y
        isWall=False
        fg=0
        count1 = count2=1
        if direction==LEFT_RIGHT:
            for i in range(y-1,-1,-1):
                if self.chessData[x][i]==Indentity and fg==0:
                    count1+=1
                    count2+=1
                    if i-1>-1 and self.chessData[x][i-1]==-Indentity: isWall=True
                elif self.chessData[x][i]==0:
                    count2+=1
                    fg=1
                else:
                    break
            fg=0
            temp=0
            for i in range(y+1,self.Col):
                if self.chessData[x][i]==Indentity and fg==0:
                    count1+=1
                    count2+=1
                    if i + 1 < self.Col and self.chessData[x][i + 1] == -Indentity: isWall = True
                elif self.chessData[x][i]==0:
                    count2+=1
                    fg=1
                else:
                    break
        if direction==TOP_BOTTOM:
            for i in range(x-1,-1,-1):
                if self.chessData[i][y]==Indentity and fg==0:
                    count1+=1
                    count2+=1
                    if i - 1 >-1 and self.chessData[i-1][y] == -Indentity: isWall = True
                elif self.chessData[i][y]==0:
                    count2+=1
                    fg=1
                else:
                    break
            fg=0
            for i in range(x+1,self.Row):
                if self.chessData[i][y]==Indentity and fg==0:
                    count1+=1
                    count2+=1
                    if i + 1 < self.Row and self.chessData[i + 1][y] == -Indentity: isWall = True
                elif self.chessData[i][y]==0:
                    count2+=1
                    fg=1
                else:
                    break
        if direction==LEFTTOP_RIGHTBOTTOM:
            n=min(x,y)
            for i in range(1,n):
                if self.chessData[x-i][y-i]==Indentity and fg==0:
                    count1+=1
                    count2+=1
                    if x-i-1> -1 and y-i-1>-1 and self.chessData[x-i-1][y-i-1] == -Indentity: isWall = True
                elif self.chessData[x-i][y-i]==0:
                    count2 += 1
                    fg=1
                else:
                    break
            fg=0
            n=self.Row-max(x,y)
            for i in range(1,n):
                if self.chessData[x+i][y+i]==Indentity and fg==0:
                    count1+=1
                    count2+=1
                    if x + i + 1 < n and y + i + 1 < n and self.chessData[x + i + 1][
                        y + i + 1] == -Indentity: isWall = True
                elif self.chessData[x+i][y+i]==0:
                    count2 += 1
                    fg=1
                else:
                    break
        if direction==RIGHTTOP_LEFTBOTTOM:
            n=min(x,self.Row-y)
            for i in range(1,n):
                if self.chessData[x-i][y+i]==Indentity and fg==0:
                    count1+=1
                    count2+=1
                    if x-i-1>-1 and y+i+1<n and self.chessData[x-i-1][y+i+1]==-Indentity: isWall=True
                elif self.chessData[x-i][y+i]==0:
                    count2 += 1
                    fg=1
                else:
                    break
            fg=0
            n=min(self.Row-x,y)
            for i in range(1,n):
                if self.chessData[x+i][y-i]==Indentity and fg==0:
                    count1+=1
                    count2+=1
                    if x+i+1<n and y-i-1>-1 and self.chessData[x+i+1][y-i-1]==-Indentity: isWall=True
                elif self.chessData[x+i][y-i]==0:
                    count2 += 1
                    fg=1
                else:
                    break
        return count1,count2,isWall

    def JudgeWin_Lose(self,point,Indentity):
        for i in range(4):
            if self.Count(point,Indentity,i)[0]>=5:
                return True

Point.py

class Point:
    def __init__(self,x,y):
        self.x=x
        self.y=y

你若盛开,蝴蝶自来!

与君共勉!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

战胜.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值