この記事の例では、参考のためにヒューマンマシンゴバンを実現するためのpythonの特定のコードを共有しています。具体的な内容は次のとおりです。
グラフィカルインターフェイスは、PyQt5とソケット通信を参照します。 LANと対戦したり、マシンと対戦したりできます。小さなバグがいくつかあるはずですが、まだわかりません。読者が見つけることができることを願っています
実行中のスクリーンショットは次のとおりです。
Gobang.pyコード:
from PyQt5.QtWidgets import*from PyQt5.QtGui import*import sys
import MyButton
import DoublePlayerGame
import SinglePlayerGame
from NetConfig import*import NetPlayerGame
classMainwindow(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/2人のプレーヤー_hover.png','source/2人のプレーヤー_normal.png','source/2人のプレーヤー_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)
# スタート2プレイヤーゲームシグナルとスロット機能をバインドします
self.dancelePlayerBtn.clicked.connect(self.startDoubliGame)
self.singlePlayerBtn.clicked.connect(self.startSingleGame)
self.drawlePlayerBtn.clicked.connect(self.startNetGame)
def startDoubliGame(self):print("in")
# 2人用のバトルインターフェースを構築する
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
classChessman(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
classDoublePlayGame(QWidget):
backSignal =pyqtSignal()#戻り信号
def __init__(self,parent = None):super().__init__(parent=parent)
# 左上隅のチェスボード[0][0]
# 右上隅のチェスボード[0][18]
# 左下隅のチェスボード[18][0]
# 右下隅のチェスボード[18][18]
# chessboard[行の添え字][列の添え字]
self.chessboard =[[None for i inrange(19)]for i inrange(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:returnif 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
returnQPoint(x, y),(self.x, self.y)
def isWin(self,chessman):print("in iswin,lastChessman:",chessman.color,chessman.x,chessman.y)
# 水平方向yは同じです、チェスボード[chessman.y][i]
count =1
# 左
i = chessman.x -1while 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 +1while i<=18:if self.chessboard[chessman.y][i]== None or self.chessboard[chessman.y][i].color != chessman.color:break
count +=1
i +=1if count =5:return chessman.color
count =1
j = chessman.y -1while 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 +1while j <=18:if self.chessboard[j][chessman.x]== None or self.chessboard[j][chessman.x].color != chessman.color:break
count +=1
j +=1if count =5:return chessman.color
count =1
j,i = chessman.y -1,chessman.x +1while 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 -1while 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 +=1if count =5:return chessman.color
count =1
j,i = chessman.y-1,chessman.x-1while 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+1while 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 +=1if 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 inrange(19):for j inrange(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:returnif 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
classNetConfigWidget(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()classNetClient(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
classNetServer(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
classNetPlayerGame(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 inrange(19):for j inrange(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:returnif self.gameStatu == False:return None
pos,chess_index = self.reversePos(a0)if pos is None:returnif 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/2716:29from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import*from PyQt5 import*from PyQt5.QtGui import*import sys
from PyQt5.QtCore import*classMyButton(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*classSinglePlayerGame(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:returnif self.chessboard[chess_index[1]][chess_index[0]]!= None:return
# プレーヤーの配置
super().mouseReleaseEvent(a0)
# コンピューターの配置
self.autoDown()
def getPointScore(self, x, y, color):'''
各ポイントのスコアを返す
y:行座標
x:列座標
色:チェスピースの色
: 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 #Y軸
while i <19:if self.chessboard[j][i] is None:
blank_score +=1
blank_score_plus[0]+=1break
elif self.chessboard[j][i].color == color:
color_score +=1
color_score_plus[0]+=1else:breakif i = x +4:break
i +=1
# print('123123')
# 左
i = x #アブシッサ
j = y #Y軸
while i =0:if self.chessboard[j][i] is None:
blank_score +=1
blank_score_plus[0]+=1break
elif self.chessboard[j][i].color == color:
color_score +=1
color_score_plus[0]+=1else:breakif i <= x -4:break
i -=1
# 垂直線
# 上
i = x #アブシッサ
j = y #Y軸
while j =0:if self.chessboard[j][i] is None:
blank_score +=1
blank_score_plus[1]+=1break
elif self.chessboard[j][i].color == color:
color_score +=1
color_score_plus[1]+=1else:breakif j <= y -4:break
j -=1
# 垂直線
# 未満
i = x #アブシッサ
j = y #Y軸
while j <19:if self.chessboard[j][i] is None:
blank_score +=1
blank_score_plus[1]+=1break
elif self.chessboard[j][i].color == color:
color_score +=1
color_score_plus[1]+=1else:breakif j = y +4: #最後の5つのポイント
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]+=1break
elif self.chessboard[j][i].color == color:
color_score +=1
color_score_plus[2]+=1else:breakif i = x +4: #最後の5つのポイント
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]+=1break
elif self.chessboard[j][i].color == color:
color_score +=1
color_score_plus[2]+=1else:breakif j = y +4: #最後の5つのポイント
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]+=1break
elif self.chessboard[j][i].color == color:
color_score +=1
color_score_plus[3]+=1else:breakif 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]+=1break
elif self.chessboard[j][i].color == color:
color_score +=1
color_score_plus[3]+=1else:breakif i = x +4:break
i +=1
j +=1for k inrange(4):if color_score_plus[k]=5:return100
# color_score *=5returnmax([x + y for x, y inzip(color_score_plus, blank_score_plus)])
def getPoint(self):'''
位置に戻る
: return:'''
# 簡単な実装:空白の交差点を返す
# for i inrange(19):
# for j inrange(19):
# if self.chessboard[i][j]== None:
# returnQPoint(j, i)
#
# 適切なポイントが見つかりませんでした
white_score =[[0for i inrange(19)]for j inrange(19)]
black_score =[[0for i inrange(19)]for j inrange(19)]for i inrange(19):for j inrange(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('----------------')
# 2次元座標を計算用に変換します
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 inzip(r_white_score,r_black_score)]
# スコアを大きくする添え字を見つける
chess_index = score.index(max(score))print(score,'\n',max(score))
y = chess_index //19
x = chess_index %19returnQPoint(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ゲームに関するよりエキサイティングな記事については、クリックして次のトピックを表示してください。
pythontetrisゲームコレクション
Pythonクラシックゲームの概要
PythonWeChatジャンプジャンプゲームコレクション
ソースダウンロード:Gomokuゲームマンマシンバージョン
以上が本稿の内容ですので、皆様のご勉強に役立てていただければ幸いです。
Recommended Posts