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 相关文章推荐
Windows下用py2exe将Python程序打包成exe程序的教程
Apr 08 Python
Python3 socket同步通信简单示例
Jun 07 Python
浅谈Python2获取中文文件名的编码问题
Jan 09 Python
Python实现的微信好友数据分析功能示例
Jun 21 Python
opencv python 2D直方图的示例代码
Jul 20 Python
python 利用for循环 保存多个图像或者文件的实例
Nov 09 Python
python使用zip将list转为json的方法
Dec 31 Python
Python判断对象是否相等及eq函数的讲解
Feb 25 Python
Python Opencv实现图像轮廓识别功能
Mar 23 Python
Python re 模块findall() 函数返回值展现方式解析
Aug 09 Python
python os模块在系统管理中的应用
Jun 22 Python
Python pip install之SSL异常处理操作
Sep 03 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的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法
2015/10/20 PHP
PHP中读取文件的几个方法总结(推荐)
2016/06/03 PHP
PHP 年月日的三级联动实例代码
2017/05/24 PHP
PHP实现浏览器中直接输出图片的方法示例
2018/03/14 PHP
php实现断点续传大文件示例代码
2020/06/19 PHP
jquery中获得$.ajax()事件返回的值并添加事件的方法
2010/04/15 Javascript
Wordpress ThickBox 点击图片显示下一张图的修改方法
2010/12/11 Javascript
js读写(删除)Cookie实例详解
2013/04/17 Javascript
Javascript实现的常用算法(如冒泡、快速、鸽巢、奇偶等)
2014/04/29 Javascript
Html5的placeholder属性(IE兼容)实现代码
2014/08/30 Javascript
jQuery简单实现禁用右键菜单
2015/03/10 Javascript
js实现两点之间画线的方法
2015/05/12 Javascript
Angular模板表单校验方法详解
2017/08/11 Javascript
Express的HTTP重定向到HTTPS的方法
2018/06/06 Javascript
laydate时间日历插件使用方法详解
2018/11/14 Javascript
纯js实现无缝滚动功能代码实例
2020/02/21 Javascript
python解析xml模块封装代码
2014/02/07 Python
Python返回真假值(True or False)小技巧
2015/04/10 Python
部署Python的框架下的web app的详细教程
2015/04/30 Python
Python PyQt5运行程序把输出信息展示到GUI图形界面上
2020/04/27 Python
HTML5标签嵌套规则详解【必看】
2016/04/26 HTML / CSS
阿提哈德航空官方网站:Etihad Airways
2017/01/06 全球购物
Sephora丝芙兰泰国官方网站:国际知名化妆品购物
2017/11/15 全球购物
英国高街奥特莱斯:Highstreet Outlet
2019/11/21 全球购物
C语言基础笔试题
2013/04/27 面试题
编程实现去掉XML的重复结点
2014/05/28 面试题
JSF界面控制层技术
2013/06/17 面试题
毕业生个人的自我评价优秀范文
2013/10/03 职场文书
资产经营总监岗位职责范文
2013/12/01 职场文书
合同专员岗位职责
2013/12/18 职场文书
行政专员工作职责
2013/12/22 职场文书
淘宝客服工作职责
2014/07/11 职场文书
2014年英语教师工作总结
2014/12/03 职场文书
刘公岛导游词
2015/02/05 职场文书
2015年基层党支部工作总结
2015/05/21 职场文书
详解jQuery的核心函数和事件处理
2022/02/18 jQuery