Python五子棋人机对战算法,python ai五子棋
川川以前梦寐以求的想找个五子棋对手,由于学习原因,实在没小伙伴陪我玩了,于是我就想着做一个人工智能五子棋来陪我玩吧。网上的游戏搜可以看到一大堆,我们不能说白嫖,白嫖过来总要改一改成自己想要的吧,虽然我也喜欢白嫖,但是我还是喜欢改成我自己想要的。
于是我就改编做了一个五子棋,别说,这五子棋真的强,有时候我下不过他!
看一小段视频演示一下:
AI.mp4
截屏看下:
代码实在太多了,我就只上传一部分了,有需要再加我QQ .
来自PyQt5 .QtWidgets导入QMainWindow,QMessageBox
来自PyQt5 .模块导入QPainter、QPen、QColor、QPalette、QBrush、QPixmap、QRadialGradient
来自PyQt5 .QtCore导入Qt,QPoint,QTimer
导入追溯
从游戏导入五子棋
从corner_widget导入角落部件
def run_with_exc(f):
游戏运行出现错误时,用messagebox把错误信息显示出来
极好的调用(window,*args,**kwargs):
尝试:
return f(window,*args,**kwargs)
例外情况除外:
exc_info=traceback.format_exc()
QMessageBox.about(window,错误信息,exc_info)
回答呼号
五子棋类(QMainWindow):
def __init__(self):
超级()。__init__()
self.init_ui() #初始化游戏界面
self.g=Gomoku() #初始化游戏内容
self.last_pos=(-1,-1)
self.res=0 #记录那边获得了胜利
self.operate_status=0 #游戏操作状态。0为游戏中(可操作),1为游戏结束闪烁过程中(不可操作)
定义初始化界面(自身):
初始化游戏界面
# 1.确定游戏界面的标题,大小和背景颜色
self.setObjectName(MainWindow )
self.setWindowTitle(五子棋)
self.setFixedSize(650,650)
#自我。设置样式表( #主窗口{ background-color:green } )
palette=QPalette()
setBrush(QPalette .窗口,QBrush(QPixmap(imgs/muzm.jpg ))
自我。设置调色板(调色板)
# 2.开启鼠标位置的追踪。并在鼠标位置移动时,使用特殊符号标记当前的位置
self.setMouseTracking(True)
# 3.鼠标位置移动时,对鼠标位置的特殊标记
自我。corner _ widget=corner widget(self)
self.corner_widget.repaint()
self.corner_widget.hide()
# 4.游戏结束时闪烁的定时器
self.end_timer=QTimer(self)
自我。结束计时器。暂停。连接(自我。end _ flash)
self.flash_cnt=0 #游戏结束之前闪烁了多少次
self.flash_pieces=((-1,-1),)#哪些棋子需要闪烁
# 5.显示初始化的游戏界面
self.show()
@run_with_exc
定义绘画事件(自身,e):
绘制游戏内容
def draw_map():
绘制棋盘
qp.setPen(QPen(QColor(0,0,0),2,Qt .实线))#棋盘的颜色为黑色
# 绘制横线
对于范围(15)内的x:
qp.drawLine(40 * (x 1),40,40 * (x 1),600)
# 绘制竖线
对于范围(15)内的y:
qp.drawLine(40,40 * (y 1),600,40 * (y 1))
# 绘制棋盘中的黑点
qp.setBrush(QColor(0,0,0))
key_points=[(4,4),(12,4),(4,12),(12,12),(8,8)]
对于关键点中的t:
qp.drawEllipse(QPoint(40 * t[0],40 * t[1]),5,5)
def draw_pieces():
绘制棋子
# 绘制黑棋子
qp.setPen(QPen(QColor(0,0,0),1,Qt .实线))
# qp.setBrush(QColor(0,0,0))
对于范围(15)内的x:
对于范围(15)内的y:
if self.g.g_map[x][y]==1:
如果self.flash_cnt % 2==1且(x,y)在self.flash_pieces中:
继续
radial=QRadialGradient(40 * (x 1),40 * (y 1),15,40 * x 35,40 * y 35) #棋子的渐变效果
radial.setColorAt(0,QColor(96,96,96))
radial.setColorAt(1,QColor(0,0,0))
qp.setBrush(QBrush(径向))
qp.drawEllipse(QPoint(40 * (x 1),40 * (y 1)),15,15)
# 绘制白棋子
qp.setPen(QPen(QColor(160,160,160),1,Qt .实线))
# qp.setBrush(QColor(255,255,255))
对于范围(15)内的x:
对于范围(15)内的y:
if self.g.g_map[x][y]==2:
如果self.flash_cnt % 2==1且(x,y)在self.flash_pieces中:
继续
radial=QRadialGradient(40 * (x 1),40 * (y 1),15,40 * x 35,40 * y 35) #棋子的渐变效果
radial.setColorAt(0,QColor(255,255,255))
radial.setColorAt(1,QColor(160,160,160))
qp.setBrush(QBrush(径向))
qp.drawEllipse(QPoint(40 * (x 1),40 * (y 1)),15,15)
if hasattr(self, g): #游戏还没开始的话,就不用画了
qp=QPainter()
qp.begin(自我)
draw_map() #绘制棋盘
draw_pieces() #绘制棋子
qp.end()
@run_with_exc
def mouseMoveEvent(self,e):
# 1.首先判断鼠标位置对应棋盘中的哪一个格子
mouse_x=e.windowPos().x()
mouse_y=e.windowPos().y()
如果25=鼠标x=615且25=mouse_y=615且(鼠标x % 40=15或鼠标x % 40=25)且(mouse_y % 40=15或mouse_y % 40=25):
game_x=int((mouse_x 15) //40) - 1
game_y=int((mouse_y 15) //40) - 1
否则:#鼠标当前的位置不对应任何一个游戏格子,将其标记为(01, 01
game_x=-1
game_y=-1
# 2.然后判断鼠标位置较前一时刻是否发生了变化
pos_change=False #标记鼠标位置是否发生了变化
如果game_x!=self.last_pos[0]或game_y!=self.last_pos[1]:
pos_change=True
self.last_pos=(game_x,game_y)
# 3.最后根据鼠标位置的变化,绘制特殊标记
如果pos_change和game_x!=-1:
self.setCursor(Qt .指向手光标)
如果pos_change和game_x==-1:
self.setCursor(Qt .箭头光标)
如果pos_change和game_x!=-1:
自我。corner _ widget。移动(25 game _ x * 40,25 game_y * 40)
self.corner_widget.show()
如果pos_change和game_x==-1:
self.corner_widget.hide()
@run_with_exc
def mousePressEvent(self,e):
根据鼠标的动作,确定落子位置
如果不是(hasattr(self, operate_status )且self.operate_status==0):
返回
if e.button()==Qt .左按钮:
# 1.首先判断按下了哪个格子
mouse_x=e.windowPos().x()
mouse_y=e.windowPos().y()
if (mouse_x % 40=15或鼠标x % 40=25)和(mouse_y % 40=15或mouse_y % 40=25):
game_x=int((mouse_x 15) //40) - 1
game_y=int((mouse_y 15) //40) - 1
否则:#鼠标点击的位置不正确
返回
self.g.move_1step(True,game_x,game_y)
# 2.根据操作结果进行一轮游戏循环
研究,自我。flash _ pieces=self。g . game _ result(show=True)#判断游戏结果
if res!=0: # 如果游戏结果为"已经结束",则显示游戏内容,并退出主循环
自我重画(0,0,650,650)
self.game_restart(res)
返回
# self.g.ai_move_1step() #电脑下一步
self.g.ai_play_1step() #电脑下一步
研究,自我。flash _ pieces=self。g . game _ result(显示=真)
if res!=0:
自我重画(0,0,650,650)
self.game_restart(res)
返回
自助重画(0,0,650,650) #在游戏还没有结束的情况下,显示游戏内容,并继续下一轮循环
@run_with_exc
def end_flash(自身):
# 游戏结束时的闪烁操作
如果self.flash_cnt=5:
# 执行闪烁
self.flash_cnt=1
self.repaint()
否则:
# 闪烁完毕,执行重新开始的操作
self.end_timer.stop()
# 1.显示游戏结束的信息
如果self.res==1:
QMessageBox.about(self,游戏结束, 玩家获胜!)
elif self.res==2:
QMessageBox.about(self,游戏结束, 电脑获胜!)
elif self.res==3:
QMessageBox.about(self,游戏结束, 平局!)
否则:
提高值错误(当前游戏结束的标志位为self.res .而游戏结束的标志位必须为1, 2 或3)
# 2.游戏重新开始的操作
self.res=0
self.operate_status=0
self.flash_cnt=0
self.g=Gomoku() #重新初始化游戏内容
自助重画(0,0,650,650) #重新绘制游戏界面
def game_restart(self,res):
游戏出现开始
self.res=res #标记谁获胜了
self.operate_status=1 #游戏结束时的闪烁过程中,不可操作
self.end_timer.start(300) #开始结束时闪烁的计时器来自PyQt5 .模块导入画家,钢笔
来自PyQt5 .QtWidgets导入窗口
来自PyQt5 .QtCore导入
类CornerWidget(QWidget):
def __init__(self,parent):
超级()。__init__(parent=parent)
self.setFixedSize(30,30)
定义绘画事件(自身,e):
qp=QPainter()
qp.begin(自我)
pen=QPen(Qt.red,3,Qt。实线)
qp.setPen
绘图线(0,8,0,0)
qp.drawLine(0,0,8,0)
qp.drawLine(22,0,28,0)
qp.drawLine(28,0,28,8)
qp .绘制线(28,22,28,28)
qp .绘制线(28,28,20,28)
qp.drawLine(8,28,0,28)
Qp.drawLine(0,28,0,22)现在我准备把这个打包成exe软件使用,呵呵!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。