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中下划线的使用方法
Mar 27 Python
使用PyCharm配合部署Python的Django框架的配置纪实
Nov 19 Python
一波神奇的Python语句、函数与方法的使用技巧总结
Dec 08 Python
Python cookbook(数据结构与算法)将名称映射到序列元素中的方法
Mar 22 Python
Python 读取指定文件夹下的所有图像方法
Apr 27 Python
Python使用pickle模块报错EOFError Ran out of input的解决方法
Aug 16 Python
python中selenium操作下拉滚动条的几种方法汇总
Jul 14 Python
Django框架模型简单介绍与使用分析
Jul 18 Python
python实现的爬取电影下载链接功能示例
Aug 26 Python
Python matplotlib实时画图案例
Apr 23 Python
python中关于数据类型的学习笔记
Jul 19 Python
vue.js刷新当前页面的实例讲解
Dec 29 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 checkbox复选框值的获取与checkbox默认值输出方法
2010/05/15 PHP
PHP生成Gif图片验证码
2013/10/27 PHP
PHP实现CSV文件的导入和导出类
2015/03/24 PHP
php支持断点续传、分块下载的类
2016/05/02 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
php处理多图上传压缩代码功能
2018/06/13 PHP
简单的js分页脚本
2009/05/21 Javascript
基于jQuery实现的百度导航li拖放排列效果,即时更新数据库
2012/07/31 Javascript
js获取鼠标点击的位置实现思路及代码
2014/05/09 Javascript
去除html代码里面的script正则方法
2016/05/19 Javascript
jQuery基于BootStrap样式实现无限极地区联动
2016/08/26 Javascript
Vue 开发音乐播放器之歌手页右侧快速入口功能
2018/08/08 Javascript
vue组件三大核心概念图文详解
2019/05/30 Javascript
js实现页面多个日期时间倒计时效果
2019/06/20 Javascript
Vue+Typescript中在Vue上挂载axios使用时报错问题
2019/08/07 Javascript
js中!和!!的区别与用法
2020/05/09 Javascript
node.js基础知识汇总
2020/08/25 Javascript
v-slot和slot、slot-scope之间相互替换实例
2020/09/04 Javascript
[01:01:25]DOTA2上海特级锦标赛B组资格赛#2 Fnatic VS Spirit第三局
2016/02/27 DOTA
[52:05]EG vs OG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
Python入门篇之函数
2014/10/20 Python
python 多线程实现检测服务器在线情况
2015/11/25 Python
python如何定义带参数的装饰器
2018/03/20 Python
Python实现计算对象的内存大小示例
2019/07/10 Python
python+selenium select下拉选择框定位处理方法
2019/08/24 Python
关于Numpy中的行向量和列向量详解
2019/11/30 Python
使用keras框架cnn+ctc_loss识别不定长字符图片操作
2020/06/29 Python
css3截图_动力节点Java学院整理
2017/07/11 HTML / CSS
美国办公用品购物网站:Quill.com
2016/09/01 全球购物
政府信息公开实施方案
2014/05/09 职场文书
2014小学语文教师个人工作总结
2014/12/03 职场文书
软件项目经理岗位职责
2015/04/01 职场文书
入党积极分子党支部意见
2015/06/02 职场文书
《山中访友》教学反思
2016/02/24 职场文书
使用python求解迷宫问题的三种实现方法
2022/03/17 Python
Go语言实现一个简单的并发聊天室的项目实战
2022/03/18 Golang