python实现人机五子棋

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

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

下面附几张运行的截图:

五子棋.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经典小游戏汇总

python微信跳一跳游戏集合

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

以上是 python实现人机五子棋 的全部内容, 来源链接: utcz.com/z/349359.html

回到顶部