python实现人机五子棋


Posted in Python onMarch 25, 2020

本文实例为大家分享了python实现人机五子棋的具体代码,供大家参考,具体内容如下

图形界面引用PyQt5,还有socket通信。可以局域网对战,可以人机对战,应该存在一些小的bug,但是还没有找出来。希望读者可以找到

下面附几张运行的截图:

python实现人机五子棋

python实现人机五子棋

python实现人机五子棋

五子棋.py代码:

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import sys

import MyButton
import DoublePlayerGame
import SinglePlayerGame
from NetConfig import *
import NetPlayerGame

class Mainwindow(QWidget):


 def __init__(self,parent = None):
 super().__init__(parent)
 self.resize(760,650)
 self.setWindowTitle("我的五子棋")
 #设置窗口图标
 self.setWindowIcon(QIcon("source/icon.ico"))


 #设置背景图片
 p = QPalette(self.palette())#获得当前的调色板
 brush = QBrush(QImage("source/五子棋界面.png"))
 p.setBrush(QPalette.Background,brush)#设置调色版
 self.setPalette(p)#给窗口设置调色板


 self.singlePlayerBtn = MyButton.MyButton('source/人机对战_hover.png',
 'source/人机对战_normal.png',
 'source/人机对战_press.png',
 parent=self)
 self.singlePlayerBtn.move(300,300)

 self.dancelePlayerBtn = MyButton.MyButton('source/双人对战_hover.png',
 'source/双人对战_normal.png',
 'source/双人对战_press.png',
 parent=self)
 self.dancelePlayerBtn.move(300,400)
 #self.dancelePlayerBtn.clicked.connect(DoublePlayerGame)

 self.drawlePlayerBtn = MyButton.MyButton('source/联机对战_hover.png',
 'source/联机对战_normal.png',
 'source/联机对战_press.png',
 parent=self)
 self.drawlePlayerBtn.move(300,500)

 #绑定开始双人游戏信号和槽函数
 self.dancelePlayerBtn.clicked.connect(self.startDoubliGame)
 self.singlePlayerBtn.clicked.connect(self.startSingleGame)
 self.drawlePlayerBtn.clicked.connect(self.startNetGame)


 def startDoubliGame(self):
 print("in")
 #构建双人对战界面
 self.doublePlayerGame = DoublePlayerGame.DoublePlayGame()
 #绑定返回界面
 self.doublePlayerGame.backSignal.connect(self.showStartGame)
 
 self.doublePlayerGame.show()#显示游戏界面
 self.close()


 def startSingleGame(self):
 self.SingleGame = SinglePlayerGame.SinglePlayerGame()
 self.SingleGame.backSignal.connect(self.showStartGame2)
 self.SingleGame.show()
 self.close()


 def startNetGame(self):
 self.netConfig = NetConfigWidget()
 self.netConfig.exit_signal.connect(self.show)
 self.netConfig.show()
 self.netConfig.config_signal.connect(self.receiveNetConfig)
 self.close()


 def receiveNetConfig(self,nettype,name,ip,port):
 '''
 接收网络配置信息
 '''
 print("net config:",nettype,name,ip,port)
 if nettype == "client":
 net_object = NetClient(name,ip,port)
 elif nettype == "server":
 net_object = NetServer(name,ip,port)
 else:
 return
 self.netPlayerGame = NetPlayerGame.NetPlayerGame(net_object=net_object)
 self.netPlayerGame.backSignal.connect(self.show)
 self.close()
 self.netPlayerGame.show()
 self.netConfig.hide()
 '''lbl = QLabel(self)
 pix = QPixmap("source/人机大战_norma.")'''

 #显示开始界面
 def showStartGame(self):
 self.show()
 self.doublePlayerGame.close()

 def showStartGame2(self):
 self.show()
 self.SingleGame.close()
 

if __name__ == "__main__":
 import cgitb
 cgitb.enable("text")
 a = QApplication(sys.argv)
 m = Mainwindow()
 m.show()
 sys.exit(a.exec_())

doubleplayergame.py代码:

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5 import *
import sys


class Chessman(QLabel):

 def __init__(self, color = "black",parent = None):
 super().__init__(parent)
 self.color = color
 self.pic = None
 if self.color == "black":
 self.pic = QPixmap("source/黑子.png")
 else:
 self.pic = QPixmap("source/白子.png")
 self.setPixmap(self.pic)
 self.setFixedSize(self.pic.size())#设置棋子大小
 self.show()

 self.x = 0
 self.y = 0

 def move(self,a0:QtCore.QPoint):
 super().move(a0.x()-15,a0.y()-15)

 def setIndex(self,x,y):
 self.x = x
 self.y = y

import MyButton

class DoublePlayGame(QWidget):
 
 backSignal = pyqtSignal()#返回信号
 def __init__(self,parent = None):
 super().__init__(parent=parent)
 #左上角chessboard[0][0]
 #右上角chessboard[0][18]
 #左下角chessboard[18][0]
 #右下角chessboard[18][18]
 #chessboard[行下标][列下标]
 self.chessboard = [[None for i in range(19)] for i in range(19)]
 #落子棋子颜色
 self.turnChessColor = "black"
 self.history = []
 self.history2 = []
 self.is_over = False

 #配置背景图
 p = QPalette(self.palette())#获得当前的调色板
 brush = QBrush(QImage("source/游戏界面.png"))
 p.setBrush(QPalette.Background,brush)#设置调色版
 self.setPalette(p)#给窗口设置调色板

 #设置标题
 #self.resize(760,650)
 self.setWindowTitle("双人联机")

 #设置窗口图标
 self.setWindowIcon(QIcon("source/icon.ico"))
 #设置窗口大小
 self.setFixedSize(QImage("source/游戏界面.png").size())

 self.backBtn = MyButton.MyButton('source/返回按钮_hover.png',
 'source/返回按钮_normal.png',
 'source/返回按钮_press.png',
 parent=self)
 self.backBtn.move(650,50)

 self.startBtn = MyButton.MyButton('source/开始按钮_hover.png',
 'source/开始按钮_normal.png',
 'source/开始按钮_press.png',
 parent=self)
 self.startBtn.move(650,300)

 self.returnBtn = MyButton.MyButton('source/悔棋按钮_hover.png',
 'source/悔棋按钮_normal.png',
 'source/悔棋按钮_press.png',
 parent=self)
 self.returnBtn.move(650,400)

 self.loseBtn = MyButton.MyButton('source/认输按钮_hover.png',
 'source/认输按钮_normal.png',
 'source/认输按钮_press.png',
 parent=self)
 self.loseBtn.move(650,500)

 #绑定返回按钮
 self.backBtn.clicked.connect(self.goBack)
 self.startBtn.clicked.connect(self.restar)
 self.loseBtn.clicked.connect(self.lose)
 self.returnBtn.clicked.connect(self.huiback)

 self.gameStatu = []

 self.focusPoint = QLabel(self)
 self.focusPoint.setPixmap(QPixmap("source/标识.png"))

 def goBack(self):
 self.backSignal.emit()
 self.close()

 def closeEvent(self, a0: QtGui.QCloseEvent):
 self.backSignal.emit()

 def mouseReleaseEvent(self, a0: QtGui.QMouseEvent):
 if self.gameStatu == False:
 return None
 print(a0.pos())
 print("x:",a0.x())
 print("y:",a0.y())
 pos,chess_index = self.reversePos(a0)
 if pos is None:
 return

 if self.chessboard[chess_index[1]][chess_index[0]] != None:
 return

 
 self.chess = Chessman(color=self.turnChessColor,parent=self)
 self.chess.setIndex(chess_index[0], chess_index[1])
 self.chess.move(pos)
 self.chess.show()#显示棋子
 self.history.append(self.chess)
 self.history2.append(self.focusPoint)

 self.focusPoint.move(QPoint(pos.x()-15,pos.y()-15))
 self.focusPoint.show()
 self.focusPoint.raise_()

 print("棋盘交点位置:",chess_index)

 #放入棋盘
 self.chessboard[chess_index[1]][chess_index[0]] = self.chess

 if self.turnChessColor=="black":
 self.turnChessColor="white"
 else:
 self.turnChessColor="black"

 self.lbl = None
 result = self.isWin(self.chess)
 if result != None:
 print(result + '赢了')
 self.showResult(result)
 
 #自动落子
 #self.autoDown()
 #坐标转换
 def reversePos(self, a0: QtCore.QPoint):
 if a0.x() <= 50 - 15 or a0.x() >= 590 +15 or a0.y() <= 50 - 15 or a0.y() >= 590+15 :
 return None, None
 self.x = (a0.x()-35)//30
 self.y = (a0.y()-35)//30
 x = 50+30*self.x
 y = 50+30*self.y
 return QPoint(x, y),(self.x, self.y)
 
 def isWin(self,chessman):
 print("in iswin,lastChessman:",chessman.color,chessman.x,chessman.y)
 #水平方向y相同,chessboard[chessman.y][i]
 count = 1
 #左边
 i = chessman.x - 1
 while i>=0:
 if self.chessboard[chessman.y][i] == None or self.chessboard[chessman.y][i].color != chessman.color:
 break
 count += 1
 i -= 1
 #右边
 i = chessman.x + 1
 while i<=18:
 if self.chessboard[chessman.y][i] == None or self.chessboard[chessman.y][i].color != chessman.color:
 break
 count += 1
 i += 1

 if count >=5:
 return chessman.color

 count = 1
 j = chessman.y - 1
 while j >= 0:
 if self.chessboard[j][chessman.x] == None or self.chessboard[j][chessman.x].color != chessman.color:
 break
 count += 1
 j -= 1

 j = chessman.y + 1
 while j <= 18:
 if self.chessboard[j][chessman.x] == None or self.chessboard[j][chessman.x].color != chessman.color:
 break
 count += 1
 j += 1


 if count >=5:
 return chessman.color

 count = 1
 j,i = chessman.y - 1,chessman.x + 1
 while j >= 0 and i <= 18:
 if self.chessboard[j][i] == None or self.chessboard[j][i].color != chessman.color:
 break
 count += 1
 j -= 1
 i += 1

 j,i = chessman.y + 1,chessman.x - 1
 while i >= 0 and j <= 18:
 if self.chessboard[j][i] == None or self.chessboard[j][i].color != chessman.color:
 break
 count += 1
 i -= 1
 j += 1
 if count >=5:
 return chessman.color

 count = 1
 j,i = chessman.y-1,chessman.x-1
 while j>=0 and i>=0:
 if self.chessboard[j][i] == None or self.chessboard[j][i].color != chessman.color:
 break
 count += 1
 j -= 1
 i -= 1

 j,i = chessman.y+1,chessman.x+1
 while j<=18 and i<=18:
 if self.chessboard[j][i] == None or self.chessboard[j][i].color != chessman.color:
 break
 count += 1
 j += 1
 i += 1

 if count >=5:
 return chessman.color

 return None


 def showResult(self,isWin = None):
 self.gameStatu = False
 if isWin == "white":
 self.lbl = QLabel(self)
 self.lbl.setPixmap(QPixmap("source/白棋胜利.png"))
 self.lbl.move(150,150)
 self.lbl.show()
 elif isWin == "black":
 self.lbl = QLabel(self)
 self.lbl.setPixmap(QPixmap("source/黑棋胜利.png"))
 self.lbl.move(150,150)
 self.lbl.show() 
 else:
 return

 def restar(self):
 for i in range(19):
 for j in range(19):
 if self.chessboard[i][j] != None:
 self.chessboard[i][j].close()
 self.chessboard[i][j] = None
 self.focusPoint.close()
 else:
 pass
 if self.lbl != None:
 self.lbl.close()

 self.gameStatu = True 

 def lose(self):
 if self.gameStatu == False:
 return
 if self.turnChessColor == "black":
 self.lbl = QLabel(self)
 self.lbl.setPixmap(QPixmap("source/白棋胜利.png"))
 self.lbl.move(150,150)
 self.lbl.show()
 elif self.turnChessColor == "white":
 self.lbl = QLabel(self)
 self.lbl.setPixmap(QPixmap("source/黑棋胜利.png"))
 self.lbl.move(150,150)
 self.lbl.show()
 else:
 return

 def huiback(self):
 if self.gameStatu == False:
 return
 m = self.history.pop()
 a = self.history2.pop()
 self.chessboard[m.y][m.x] = None
 m.close() 
 a.close() 
 if self.turnChessColor=="black":
 self.turnChessColor="white"
 else:
 self.turnChessColor="black"
 

if __name__ == "__main__":
 import cgitb
 cgitb.enable("text")
 a = QApplication(sys.argv)
 m = DoublePlayGame()
 m.show()
 sys.exit(a.exec_())
 pass

NetConfig.py代码:

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import *
import socket
import threading
class NetConfigWidget(QWidget):
 config_signal = pyqtSignal([str,str,str,str])
 exit_signal = pyqtSignal()
 def __init__(self,parent = None):
 super().__init__(parent = parent)
 self.initUI()

 def initUI(self):
 self.setWindowTitle("网络配置")
 self.name_label = QLabel("姓名:",self)
 self.name_input = QLineEdit("玩家1",self)
 self.ip_label = QLabel("IP:",self)
 self.ip_input = QLineEdit("127.0.0.1",self)
 self.port_label = QLabel("Prot:",self)
 self.port_input = QLineEdit("10086",self)
 self.client_button = QPushButton("链接主机",self)
 self.server_button = QPushButton("我是主机",self)
 

 gridLayout = QGridLayout()
 gridLayout.addWidget(self.name_label,0,0)
 gridLayout.addWidget(self.name_input,0,1)
 gridLayout.addWidget(self.ip_label,1,0)
 gridLayout.addWidget(self.ip_input,1,1)
 gridLayout.addWidget(self.port_label,2,0)
 gridLayout.addWidget(self.port_input,2,1)
 gridLayout.addWidget(self.client_button,3,0)
 gridLayout.addWidget(self.server_button,3,1)
 self.setLayout(gridLayout)

 self.client_button.clicked.connect(self.client_btn_signal)
 self.server_button.clicked.connect(self.server_btn_signal)

 def server_btn_signal(self):
 self.config_signal.emit("server",self.name_input.text(),self.ip_input.text(),self.port_input.text())
 
 def client_btn_signal(self):
 self.config_signal.emit("client",self.name_input.text(),self.ip_input.text(),self.port_input.text())

 def closeEvent(self,a0:QtGui.QCloseEvent):
 self.close()
 self.exit_signal.emit()

class NetClient(QObject):
 msg_signal = pyqtSignal([str])
 def __init__(self,name,ip,port):
 super().__init__()
 self.name = name
 self.ip = ip
 self.port = port
 self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

 def buildConnect(self):
 '''建立链接'''
 self.socket.connect((self.ip,int(self.port)))
 threading.Thread(target=self.recv).start()
 pass

 def send(self,data):
 '''发送数据
 data(发送的数据)字符串类型'''
 self.socket.send(data.encode())
 pass

 def recv(self):
 '''接收数据'''
 while True:
 try:
 data = self.socket.recv(4096).decode()
 self.msg_signal.emit(data)
 except:
 pass

class NetServer(QObject):
 msg_signal = pyqtSignal([str])
 def __init__(self,name,ip,port):
 super().__init__()
 self.name = name
 self.ip = ip
 self.port = port
 self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 self.cli_socket = None

 def buildConnect(self):
 self.socket.bind(("",int(self.port)))
 self.socket.listen(1)
 threading.Thread(target=self.__acceptConnect).start()


 def __acceptConnect(self):
 try:
 self.cli_socket,cli_addr = self.socket.accept()
 except:
 pass
 
 while True:
 try:
 data = self.cli_socket.recv(4096).decode()
 self.msg_signal.emit(data)
 except Exception as e:
 print(e)

 def send(self,data):
 if self.cli_socket == None:
 return
 self.cli_socket.send(data.encode())


if __name__ == "__main__":
 import sys
 import cgitb
 cgitb.enable("text")
 a = QApplication(sys.argv)
 m = NetConfigWidget()
 m.show()
 sys.exit(a.exec_())
 pass

NetplayerGame.py代码:

from DoublePlayerGame import *
import json
from NetConfig import *
from PyQt5.QtMultimedia import QSound

class NetPlayerGame(DoublePlayGame):
 def __init__(self,net_object, parent = None):
 super().__init__(parent = parent)
 self.net_object = net_object
 self.net_object.buildConnect()#建立网络链接
 self.net_object.msg_signal.connect(self.parseData)
 self.m_color = None#玩家棋子颜色

 self.cuicuBtn = MyButton.MyButton('source/催促按钮_hover.png',
 'source/催促按钮_normal.png',
 'source/催促按钮_press.png',
 parent=self)
 self.cuicuBtn.move(650,600)

 self.cuicuBtn.clicked.connect(self.cuicu)

 def cuicu(self):
 QSound.play('source/cuicu.wav')
 msg = {}
 msg['msg_type'] = 'cuicu'
 self.net_object.send(json.dumps(msg))
 pass

 def goBack(self):
 self.backSignal.emit()
 self.close()
 self.net_object.socket.close()


 def downChessman(self,point,color):
 '''
 自动落子
 :return:
 '''
 #point = self.getPoint()

 # 注意:x,y坐标对应
 chess_index = (point.y(), point.x()) # 棋子在棋盘中的下标
 pos = QPoint(50+point.x()*30, 50+point.y()*30) # 棋子在棋盘中的坐标

 self.chessman = Chessman(color=color, parent=self)
 self.chessman.setIndex(chess_index[0], chess_index[1])
 self.chessman.move(pos)
 self.chessman.show() # 显示棋子

 # 显示标识
 self.focusPoint.move(QPoint(pos.x() - 15, pos.y() - 15))
 self.focusPoint.show()
 self.focusPoint.raise_()

 self.chessboard[chess_index[0]][chess_index[1]] = self.chessman

 # 历史记录
 self.history.append((chess_index[0], chess_index[1], self.chessman.color))

 # 改变落子颜色
 if self.turnChessColor == 'black':
 self.turnChessColor = 'white'
 else:
 self.turnChessColor = 'black'
 # 判断输赢
 result = self.isWin(self.chessman)
 if result != None:
 print(result + '赢了')
 self.showResult(result)

 pass
 '''
 {
 "msg_type":"positon",
 "x":"10",
 "y":"15",
 "color":"black"
 }
 '''
 #解析网路数据
 def parseData(self,data):
 print("pardata:",data)
 try:
 msg = json.loads(data)
 except Exception as e:
 print(e)
 
 #msg = json.loads(data)
 print("msg:",msg)
 if msg["msg_type"] == "position":
 self.downChessman(QPoint(int(msg["x"]),int(msg["y"])),msg["color"])
 pass

 elif msg["msg_type"] == "restart":
 result = QMessageBox.information(None,'五子棋_提示消息','请求开始游戏',QMessageBox.Yes |QMessageBox.No)
 if result == QMessageBox.Yes:
 self.restartGame()#白子
 self.m_color = 'white'
 msg = {}
 msg['msg_type'] = "response"
 msg['action_type'] = 'restart'
 msg['action_result'] = 'yes'
 self.net_object.send(json.dumps(msg))

 else:
 msg = {}
 msg['msg_type'] = "response"
 msg['action_type'] = 'restart'
 msg['action_result'] = 'no'
 self.net_object.send(json.dumps(msg))
 elif msg['msg_type'] == 'response':
 if msg['action_type'] == 'restart':
 if msg['action_result'] == 'yes':
 self.restartGame()
 self.m_color = 'balck'
 else:
 QMessageBox.information(self,'五子棋_提示消息','对方拒绝游戏')
 elif msg['action_type'] == 'huiqi':
 if msg['action_result'] == 'Yes':
 self.huiqigame()
 else:
 QMessageBox.information(self,'五子棋_提示消息','对方拒绝悔棋',QMessageBox.Yes |QMessageBox.No)


 elif msg['msg_type'] == 'huiqi':
 result = QMessageBox.information(self,'五子棋_提示消息','对方请求悔棋',QMessageBox.Yes |QMessageBox.No)
 if result == QMessageBox.Yes: 
 msg = {}
 msg['msg_type'] = "response"
 msg['action_type'] = 'huiqi'
 msg['action_result'] = 'Yes'
 self.net_object.send(json.dumps(msg))
 self.huiqigame()
 else:
 msg = {}
 msg['msg_type'] = "response"
 msg['action_type'] = 'huiqi'
 msg['action_result'] = 'No'
 self.net_object.send(json.dumps(msg))
 elif msg['msg_type'] == 'lose':
 show.showResult(self.m_color)

 elif msg['msg_type'] == 'cuicu':
 QSound.play('source/cuicu.wav')
 QMessageBox.window(self,'0')

 def restartGame(self):

 for i in range(19):
 for j in range(19):
 if self.chessboard[i][j] != None:
 self.chessboard[i][j].close()
 self.chessboard[i][j] = None
 self.focusPoint.close()
 else:
 pass
 self.lbl = None
 if self.lbl != None:
 self.lbl.close()

 self.gameStatu = True 
 self.focusPoint.hide()
 self.turnChessColor="black"
 

 def mouseReleaseEvent(self, a0: QtGui.QMouseEvent):
 if self.m_color != self.turnChessColor:
 return
 if self.gameStatu == False:
 return None
 pos,chess_index = self.reversePos(a0)
 if pos is None:
 return
 if self.chessboard[chess_index[1]][chess_index[0]] != None:
 return

 self.chess = Chessman(color=self.turnChessColor,parent=self)
 self.chess.setIndex(chess_index[1], chess_index[0])
 self.chess.move(pos)
 self.chess.show()#显示棋子
 self.history.append(self.chess)
 self.history2.append(self.focusPoint)

 self.focusPoint.move(QPoint(pos.x()-15,pos.y()-15))
 self.focusPoint.show()
 self.focusPoint.raise_()

 print("棋盘交点位置:",chess_index)

 #放入棋盘
 self.chessboard[chess_index[1]][chess_index[0]] = self.chess
 #发送落子信息
 msg = {}
 msg["msg_type"] = "position"
 msg["x"] = chess_index[1]
 msg["y"] = chess_index[0]
 msg["color"] = self.turnChessColor
 self.net_object.send(json.dumps(msg))
 

 if self.turnChessColor=="black":
 self.turnChessColor="white"
 else:
 self.turnChessColor="black"
 
 self.lbl = None
 result = self.isWin(self.chess)
 if result != None:
 print(result + '赢了') 
 self.showResult(result)


 def huiqi(self):
 if self.gameStatu == None:
 QMessageBox.warning(self,'五子棋提示','游戏没有开始,不能悔棋')
 if self.m_color != self.turnChessColor:
 QMessageBox.warning(self,'五子棋提示','不是你的回合')
 msg = {}
 msg['msg_type'] = 'huiqi'
 self.net_object.send(json.dumps(msg))

 def huiqigame(self):
 if self.gameStatu == False:
 return
 m = self.history.pop()
 a = self.history2.pop()
 self.chessboard[m.y][m.x] = None
 m.close() 
 a.close() 
 if self.turnChessColor=="black":
 self.turnChessColor="white"
 else:
 self.turnChessColor="black"

 def restar(self):
 msg = {}
 msg["msg_type"] = "restart"
 self.net_object.send(json.dumps(msg))


def lose(self):
 if self.gameStatu == False:
 QMessageBox.warning(None,'五子棋','游戏没有开始')
 if self.m_color == "black":
 self.lbl = QLabel(self)
 self.lbl.setPixmap(QPixmap("source/白棋胜利.png"))
 self.lbl.move(150,150)
 self.lbl.show()
 elif self.m_color == "white":
 self.lbl = QLabel(self)
 self.lbl.setPixmap(QPixmap("source/黑棋胜利.png"))
 self.lbl.move(150,150)
 self.lbl.show()
 else:
 return
 msg = {}
 msg['msg_type'] = "lose"
 #msg['action_type'] = 'restart'
 #msg['action_result'] = 'no'
 self.net_object.send(json.dumps(msg))
 


if __name__ == '__main__':
 import cgitb
 cgitb.enable("text")
 a = QApplication(sys.argv)
 m = NetPlayerGame()
 m.show()
 sys.exit(a.exec_())
 pass

MyButton.py代码:

# -*- coding:utf-8 -*-
# @author: alex 
# @time: 2018/12/27 16:29
from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import *
from PyQt5 import *
from PyQt5.QtGui import *
import sys

from PyQt5.QtCore import *

class MyButton(QLabel):


 clicked = pyqtSignal()#自定义一个信号

 def __init__(self, *args, parent=None):
 super().__init__(parent)

 self.hoverPixmap = QPixmap(args[0])
 self.normalPixmap = QPixmap(args[1])
 self.pressPixmap = QPixmap(args[2])

 self.enterState = False
 self.setPixmap(self.normalPixmap)
 self.setFixedSize(self.normalPixmap.size())

 def mouseReleaseEvent(self, ev: QtGui.QMouseEvent):
 if self.enterState == False:
 self.setPixmap(self.normalPixmap)
 else:
 self.setPixmap(self.hoverPixmap)

 self.clicked.emit()#发射信号

 print("鼠标释放")
 pass

 def mousePressEvent(self, ev: QtGui.QMouseEvent):
 self.setPixmap(self.pressPixmap)
 print("鼠标按下")
 pass

 def enterEvent(self, a0: QtCore.QEvent):
 self.setPixmap(self.hoverPixmap)
 self.enterState = True
 print("鼠标进入")
 pass

 def leaveEvent(self, a0: QtCore.QEvent):
 self.setPixmap(self.normalPixmap)
 self.enterState = False
 print("鼠标离开")
 pass


if __name__ == '__main__':
 a = QApplication(sys.argv)
 mybtn = MyButton('source/人机对战_hover.png',
 'source/人机对战_normal.png',
 'source/人机对战_press.png')
 mybtn.show()
 sys.exit(a.exec_())

SingerPlayerGame.py代码:

from DoublePlayerGame import *

class SinglePlayerGame(DoublePlayGame):

 def __init__(self, parent=None):
 super().__init__(parent=parent)
 self.setWindowTitle('五子棋-单机模式')

 def mouseReleaseEvent(self, a0: QtGui.QMouseEvent):

 if self.gameStatu == False:
 return None
 print(a0.pos())
 print("x:",a0.x())
 print("y:",a0.y())
 pos,chess_index = self.reversePos(a0)
 if pos is None:
 return

 if self.chessboard[chess_index[1]][chess_index[0]] != None:
 return
 # 玩家落子
 super().mouseReleaseEvent(a0)
 # 电脑落子
 self.autoDown()

 def getPointScore(self, x, y, color):
 '''
 返回每个点的得分
 y:行坐标
 x:列坐标
 color:棋子颜色
 :return:
 '''
 # 分别计算点周围5子以内,空白、和同色的分数
 blank_score = 0
 color_score = 0

 # 记录每个方向的棋子分数
 blank_score_plus = [0, 0, 0, 0] # 横向 纵向 正斜线 反斜线
 color_score_plus = [0, 0, 0, 0]

 # 横线
 # 右侧
 i = x # 横坐标
 j = y # 纵坐标
 while i < 19:
 if self.chessboard[j][i] is None:
 blank_score += 1
 blank_score_plus[0] += 1
 break
 elif self.chessboard[j][i].color == color:
 color_score += 1
 color_score_plus[0] += 1
 else:
 break
 if i >= x + 4:
 break
 i += 1
 # print('123123')
 # 左侧
 i = x # 横坐标
 j = y # 纵坐标
 while i >= 0:
 if self.chessboard[j][i] is None:
 blank_score += 1
 blank_score_plus[0] += 1
 break
 elif self.chessboard[j][i].color == color:
 color_score += 1
 color_score_plus[0] += 1
 else:
 break
 if i <= x - 4:
 break
 i -= 1

 # 竖线
 # 上方
 i = x # 横坐标
 j = y # 纵坐标
 while j >= 0:
 if self.chessboard[j][i] is None:
 blank_score += 1
 blank_score_plus[1] += 1
 break
 elif self.chessboard[j][i].color == color:
 color_score += 1
 color_score_plus[1] += 1
 else:
 break
 if j <= y - 4:
 break
 j -= 1
 # 竖线
 # 下方
 i = x # 横坐标
 j = y # 纵坐标
 while j < 19:
 if self.chessboard[j][i] is None:
 blank_score += 1
 blank_score_plus[1] += 1
 break
 elif self.chessboard[j][i].color == color:
 color_score += 1
 color_score_plus[1] += 1
 else:
 break

 if j >= y + 4: # 最近五个点
 break
 j += 1
 # 正斜线
 # 右上
 i = x
 j = y
 while i < 19 and j >= 0:
 if self.chessboard[j][i] is None:
 blank_score += 1
 blank_score_plus[2] += 1
 break
 elif self.chessboard[j][i].color == color:
 color_score += 1
 color_score_plus[2] += 1
 else:
 break

 if i >= x + 4: # 最近五个点
 break
 i += 1
 j -= 1
 # 左下
 i = x
 j = y
 while j < 19 and i >= 0:
 if self.chessboard[j][i] is None:
 blank_score += 1
 blank_score_plus[2] += 1
 break
 elif self.chessboard[j][i].color == color:
 color_score += 1
 color_score_plus[2] += 1
 else:
 break

 if j >= y + 4: # 最近五个点
 break
 i -= 1
 j += 1
 # 反斜线
 # 左上
 i = x
 j = y
 while i >= 0 and j >= 0:
 if self.chessboard[j][i] is None:
 blank_score += 1
 blank_score_plus[3] += 1
 break
 elif self.chessboard[j][i].color == color:
 color_score += 1
 color_score_plus[3] += 1
 else:
 break
 if i <= x - 4:
 break
 i -= 1
 j -= 1
 # 右上
 i = x
 j = y
 while i < 19 and j < 19:
 if self.chessboard[j][i] is None:
 blank_score += 1
 blank_score_plus[3] += 1
 break
 elif self.chessboard[j][i].color == color:
 color_score += 1
 color_score_plus[3] += 1
 else:
 break
 if i >= x + 4:
 break
 i += 1
 j += 1

 for k in range(4):
 if color_score_plus[k] >= 5:
 return 100

 # color_score *= 5
 return max([x + y for x, y in zip(color_score_plus, blank_score_plus)])

 def getPoint(self):
 '''
 返回落子位置
 :return:
 '''
 # 简单实现:返回一个空白交点
 # for i in range(19):
 # for j in range(19):
 # if self.chessboard[i][j] == None:
 # return QPoint(j, i)
 #
 # 没有找到合适的点
 white_score = [ [ 0 for i in range(19) ] for j in range(19)]
 black_score = [ [ 0 for i in range(19) ] for j in range(19)]

 for i in range(19):
 for j in range(19):
 if self.chessboard[i][j] != None:
 continue
 # 模拟落子
 self.chessboard[i][j] = Chessman(color='white',parent=self)
 white_score[i][j] = self.getPointScore(j, i, 'white')
 self.chessboard[i][j].close()
 self.chessboard[i][j] = None
 self.chessboard[i][j] = Chessman(color='black',parent=self)
 black_score[i][j] = self.getPointScore(j, i, 'black')
 self.chessboard[i][j].close()
 self.chessboard[i][j] = None


 print('----------------')
 # 将二维坐标转换成以为进行计算
 r_white_score = []
 r_black_score = []
 for i in white_score:
 r_white_score.extend(i)
 for i in black_score:
 r_black_score.extend(i)

 # 找到分数最大值
 score = [ max(x,y) for x,y in zip(r_white_score,r_black_score) ]

 # 找到分数做大的下标
 chess_index = score.index(max(score))

 print(score,'\n',max(score))

 y = chess_index //19
 x = chess_index % 19

 return QPoint(x,y)

 def autoDown(self):
 '''
 自动落子
 :return:
 '''
 point = self.getPoint()

 # 注意:x,y坐标对应
 chess_index = (point.y(), point.x()) # 棋子在棋盘中的下标
 pos = QPoint(50+point.x()*30, 50+point.y()*30) # 棋子在棋盘中的坐标

 self.chessman = Chessman(color=self.turnChessColor, parent=self)
 self.chessman.setIndex(chess_index[1], chess_index[0])
 self.chessman.move(pos)
 self.chessman.show() # 显示棋子

 # 显示标识
 self.focusPoint.move(QPoint(pos.x() - 15, pos.y() - 15))
 self.focusPoint.show()
 self.focusPoint.raise_()

 self.chessboard[chess_index[0]][chess_index[1]] = self.chessman

 # 历史记录
 self.history.append((chess_index[0], chess_index[1], self.chessman.color))

 # 改变落子颜色
 if self.turnChessColor == 'black':
 self.turnChessColor = 'white'
 else:
 self.turnChessColor = 'black'
 # 判断输赢
 result = self.isWin(self.chessman)
 if result != None:
 print(result + '赢了')
 self.showResult(result)

 pass

if __name__ == '__main__':

 import cgitb
 cgitb.enable('text')

 a = QApplication(sys.argv)
 m = SinglePlayerGame()
 m.show()
 sys.exit(a.exec_())

更多关于python游戏的精彩文章请点击查看以下专题:

源码下载:五子棋游戏人机版

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用Python标准库中的wave模块绘制乐谱的简单教程
Mar 30 Python
Python中生成Epoch的方法
Apr 26 Python
Django的HttpRequest和HttpResponse对象详解
Jan 26 Python
python3.X 抓取火车票信息【修正版】
Jun 19 Python
python实现图片批量压缩程序
Jul 23 Python
Python 实现还原已撤回的微信消息
Jun 18 Python
pyqt 实现为长内容添加滑轮 scrollArea
Jun 19 Python
Python高级特性——详解多维数组切片(Slice)
Nov 26 Python
Django-imagekit的使用详解
Jul 06 Python
在keras中对单一输入图像进行预测并返回预测结果操作
Jul 09 Python
Python文件名匹配与文件复制的实现
Dec 11 Python
Python初学者必备的文件读写指南
Jun 23 Python
pyqt5数据库使用详细教程(打包解决方案)
Mar 25 #Python
详解基于Jupyter notebooks采用sklearn库实现多元回归方程编程
Mar 25 #Python
python自动下载图片的方法示例
Mar 25 #Python
Python短信轰炸的代码
Mar 25 #Python
PyQt5事件处理之定时在控件上显示信息的代码
Mar 25 #Python
基于Python计算圆周率pi代码实例
Mar 25 #Python
Python异常原理及异常捕捉实现过程解析
Mar 25 #Python
You might like
php curl模拟post提交数据示例
2013/12/31 PHP
关于PHP文件的自动运行方法分析
2016/05/13 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
2018/05/23 PHP
php实现的证件照换底色功能示例【人像抠图/换背景图】
2020/05/29 PHP
JavaScript 学习 - 提高篇
2007/02/02 Javascript
JS下拉框内容左右移动效果的具体实现
2013/07/10 Javascript
JavaScript改变HTML元素的样式改变CSS及元素属性
2013/11/12 Javascript
Jquery each方法跳出循环,并获取返回值(实例讲解)
2013/12/12 Javascript
IE8下Jquery获取select选中的值post到后台报错问题
2014/07/02 Javascript
jQuery遍历页面所有CheckBox查看是否被选中的方法
2015/04/14 Javascript
javascript实现跨域的方法汇总
2015/06/25 Javascript
原生javascript实现图片无缝滚动效果
2016/02/12 Javascript
JSON与JS对象的区别与对比
2017/03/01 Javascript
Extjs表单输入框异步校验的插件实现方法
2017/03/20 Javascript
webpack3之loader全解析
2017/10/26 Javascript
JavaScript学习笔记之DOM基础操作实例小结
2019/01/09 Javascript
JavaScript实现放大镜效果代码示例
2020/04/29 Javascript
vue组件开发之slider组件使用详解
2020/08/21 Javascript
[01:01:52]DOTA2-DPC中国联赛正赛 iG vs LBZS BO3 第一场 3月4日
2021/03/11 DOTA
Python实现批量读取word中表格信息的方法
2015/07/30 Python
Django与JS交互的示例代码
2017/08/23 Python
Pandas之排序函数sort_values()的实现
2019/07/09 Python
tensor和numpy的互相转换的实现示例
2019/08/02 Python
python实现KNN分类算法
2019/10/16 Python
Python tkinter常用操作代码实例
2020/01/03 Python
Django框架获取form表单数据方式总结
2020/04/22 Python
OpenCV图片漫画效果的实现示例
2020/08/18 Python
python利用线程实现多任务
2020/09/18 Python
基于python判断字符串括号是否闭合{}[]()
2020/09/21 Python
python3中布局背景颜色代码分析
2020/12/01 Python
网络教育自我鉴定
2013/11/01 职场文书
会计电算化专业自荐信
2014/03/15 职场文书
优秀员工推荐信
2014/05/10 职场文书
模具设计与制造专业自荐书
2014/07/01 职场文书
企业安全隐患排查治理制度
2015/08/05 职场文书
Spring Cloud OAuth2实现自定义token返回格式
2022/06/25 Java/Android