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数据分析中Groupby用法之通过字典或Series进行分组的实例
Dec 08 Python
python实现决策树
Dec 21 Python
解决每次打开pycharm直接进入项目的问题
Oct 28 Python
Python中作用域的深入讲解
Dec 10 Python
python读取有密码的zip压缩文件实例
Feb 08 Python
Python3实现汉语转换为汉语拼音
Jul 08 Python
解决python 上传图片限制格式问题
Oct 30 Python
Python操作Sonqube API获取检测结果并打印过程解析
Nov 27 Python
tensorflow 利用expand_dims和squeeze扩展和压缩tensor维度方式
Feb 07 Python
python通过函数名调用函数的几种场景
Sep 23 Python
2020年10款优秀的Python第三方库,看看有你中意的吗?
Jan 12 Python
Python使用永中文档转换服务
May 06 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中用加号与用array_merge合并数组的区别深入分析
2013/06/03 PHP
windwos下使用php连接oracle数据库的过程分享
2014/05/26 PHP
CI框架给视图添加动态数据
2014/12/01 PHP
PHP排序算法类实例
2015/06/17 PHP
PHP SESSION跨页面传递失败解决方案
2020/12/11 PHP
模仿JQuery.extend函数扩展自己对象的js代码
2009/12/09 Javascript
javascript常用方法、属性集合及NodeList 和 HTMLCollection 的浏览器差异
2010/12/25 Javascript
js Dialog 去掉右上角的X关闭功能
2014/04/23 Javascript
jquery实现的鼠标下拉滚动置顶效果
2014/07/24 Javascript
JavaScript参数个数可变的函数举例说明
2014/10/10 Javascript
ie8模式下click无反应点击option无反应的解决方法
2014/10/11 Javascript
jQuery实现的网页右下角tab样式在线客服效果代码
2015/10/23 Javascript
JS使用正则表达式除去字符串中重复字符的方法
2015/11/05 Javascript
jQuery Validate插件实现表单强大的验证功能
2015/12/18 Javascript
JavaScript+CSS无限极分类效果完整实现方法
2015/12/22 Javascript
如何提高Dom访问速度
2017/01/05 Javascript
jQuery实现动态给table赋值的方法示例
2017/07/04 jQuery
nodejs 图解express+supervisor+ejs的用法(推荐)
2017/09/08 NodeJs
angularJS自定义directive之带参方法传递详解
2018/10/09 Javascript
更改Python命令行交互提示符的方法
2015/01/14 Python
Python实现ssh批量登录并执行命令
2016/10/25 Python
python3.4+pycharm 环境安装及使用方法
2019/06/13 Python
Python pandas DataFrame操作的实现代码
2019/06/21 Python
python识别图像并提取文字的实现方法
2019/06/28 Python
Python 通过微信控制实现app定位发送到个人服务器再转发微信服务器接收位置信息
2019/08/05 Python
python list转置和前后反转的例子
2019/08/26 Python
使用Django和Postgres进行全文搜索的实例代码
2020/02/13 Python
Django Channel实时推送与聊天的示例代码
2020/04/30 Python
澳大利亚波希米亚风时尚品牌:Tree of Life
2019/09/15 全球购物
网络信息管理员岗位职责
2014/01/05 职场文书
主持人演讲稿
2014/05/13 职场文书
平安建设工作方案
2014/06/02 职场文书
中学综治宣传月活动总结
2015/05/07 职场文书
高二化学教学反思
2016/02/22 职场文书
SSM VUE Axios详解
2021/10/05 Vue.js
Vue h函数的使用详解
2022/02/18 Vue.js