您好,登錄后才能下訂單哦!
這篇文章主要講解了“Python3怎么利用Qt5實現簡易的五子棋游戲”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Python3怎么利用Qt5實現簡易的五子棋游戲”吧!
要寫出一個五子棋游戲,我們最先要解決的,就是如何下子,如何判斷已經五子連珠,而不是如何繪制畫面,因此我們先確定棋盤
五子棋采用15*15的棋盤,因此,我們可以使用二維列表來創建一個棋盤,不妨認為0表示未放置棋子,1表示放置白子,2表示放置黑子。
顯而易見可以創建列表,注意不能使用*來復制列表
self.chess_board = [[0 for i in range(15)] for i in range(15)]
下棋的步驟十分好做,只需要找到對應的索引進行賦值即可,下一步應該解決如何判斷五子連珠的問題。
每當我們落子結束后,應該判斷是否已經完成五子連珠。對于剛放置的一顆棋子而言,可能的情況大致分為四種:
1.水平
2.斜向右下
3.豎直
4.斜向右上
要判斷是否已經連珠成功,我們以剛放置的棋子為起點,先向前遍歷4個棋子,并計算相同棋子的個數,一旦遇到不同的棋子,就停止,然后從起點向后遍歷4個棋子,直到全部遍歷完成或者棋子總數已經達到5個,就可以返回。我們只需要注意如何獲得棋子的前后棋子以及棋盤的邊界問題,棋子不可能超出棋盤,因此被遍歷的棋子也不能超出棋盤。
以水平為例,可以得到代碼
def judge_1(self,x:int,y:int) -> bool: count = 1 if self.chess_board[x][y] != 0: for i in range(1,5): if y - i >= 0: if self.chess_board[x][y] == self.chess_board[x][y-i]: print(x,y-i) count += 1 else: break else: break for i in range(1,5): if y + i <=14: if self.chess_board[x][y] == self.chess_board[x][y+i]: print(x,y+i) count += 1 else: break else: break if count == 5: return True return False
以相似的步驟完成其余三種判斷,就已經完成了五子棋游戲的核心要素了,剩下的就需要交給PyQt5來完成游戲的繪制來完善游戲了。
我們創建一個類來繼承QWidget類,創建一個窗口,之后我們需要創建幾個屬性來完成儲存我們的數據信息
#棋子的坐標 self.x = -1 self.y = -1 #區分玩家 #開始標簽 self.flag = False #儲存已經下好的白子 self.white_chess = [] #儲存已經下好的黑子 self.black_chess = []
我們已經可以開始繪制棋盤,在Qt5中,如果我們需要進行繪制,我們應該重寫paintEvent方法,這個方法會由程序自動調用執行。創建一個QPainter對象,將需要繪制的內容用begin與end方法包裹起來,就可以完成繪制。
我們用drawLine方法來繪制線條,用drawEllipse方法來繪制棋子,使用setPen來更改線條樣式,setBrush來更改棋子樣式。
得到代碼(本段代碼有參考他人代碼,這是我第一次接觸Qt的繪制)
--------------------GUI中的x軸豎直向下,y軸水平向右,因此繪制棋子時的x與y需要顛倒---------------
#繪制棋盤與棋子 def paintEvent(self, e) -> None: qp = QPainter() qp.begin(self) qp.fillRect(self.rect(), QColor("light blue")) qp.drawRect(self.rect()) qp.setBackground(QColor("yellow")) qp.setPen(QPen(QColor(0, 0, 0), 2, Qt.SolidLine)) for i in range(15): qp.drawLine(QPoint(30, 30 + 30 * i), QPoint(450, 30 + 30 * i)) for i in range(15): qp.drawLine(QPoint(30 + 30 * i, 30), QPoint(30 + 30 * i, 450)) qp.setBrush(QColor(0, 0, 0)) key_points = [(3, 3), (11, 3), (3, 11), (11, 11), (7, 7)] if len(self.black_chess) != 0: for t in self.black_chess: #畫黑子 qp.drawEllipse(QPoint(30 + 30 * t[1], 30 + 30 * t[0]), 6, 6) for t in key_points: #棋盤的5個定點 qp.drawEllipse(QPoint(30 + 30 * t[0], 30 + 30 * t[1]), 3, 3) qp.setBrush(QColor(255,255,255)) if len(self.white_chess) != 0: for t in self.white_chess: #畫白子 qp.drawEllipse(QPoint(30 + 30 * t[1], 30 + 30 * t[0]), 6, 6) qp.end()
另一個需要在GUI中解決的問題就是,如何獲取要下的棋子的坐標?我們可以通過重寫鼠標事件來解決,重寫單機事件mousePressEvent,并修改棋子的x坐標與y坐標即可,另外,用戶不可能每次都恰巧點到我們規定的坐標點上,因此需要給出一個大致范圍判斷,這里我的方式是先獲取坐標,然后根據坐標找到距離最近的點
def mousePressEvent(self, e) -> None: if e.buttons() == QtCore.Qt.LeftButton: if e.x() > 15 and e.x() < 465 and e.y() > 15 and e.y() < 465: x = e.x()/30 - e.x()//30 y = e.y()/30 - e.y()//30 self.y = (e.x()-30)//30 if x < 0.5 else (e.x()-30)//30 + 1 self.x = (e.y()-30)//30 if y < 0.5 else (e.y()-30)//30 + 1 if self.flag: print(self.x,self.y) if self.player % 2 == 1: if goBang.put_white_chess(self.x,self.y): self.player += 1 print('黑子行動') else: print('白子行動') if goBang.judge(self.x,self.y): msg_box = QMessageBox(QMessageBox.Information, '提示', '白子獲勝!') msg_box.exec_() else: if goBang.put_black_chess(self.x,self.y): self.player += 1 print('白子行動') else: print('黑子行動') if goBang.judge(self.x,self.y): msg_box = QMessageBox(QMessageBox.Information, '提示', '黑子獲勝!') msg_box.exec_()
每當游戲完成,我們應該可以清空棋盤,也就是將所有儲存數據的變量都重新初始化再重繪棋盤
#清除棋盤,重開游戲 def clear(self) -> None: self.x = -1 self.y = -1 self.player = 0 self.flag = False self.white_chess = [] self.black_chess = [] self.chess_board = [[0 for i in range(15)] for i in range(15)] self.update()
這樣就大致結束了!!
下面是全部代碼:
from PyQt5 import * from PyQt5 import QtCore from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * import sys class GoBang(QWidget): #初始化棋盤 def __init__(self): super().__init__() self.setWindowTitle('五子棋Hi~ o(* ̄▽ ̄*)ブ') self.x = -1 self.y = -1 #區分玩家 self.player = 0 #開始標簽 self.flag = False #儲存已經下好的白子 self.white_chess = [] #儲存已經下好的黑子 self.black_chess = [] self.setFixedSize(800,600) self.chess_board = [[0 for i in range(15)] for i in range(15)] btn1 = QPushButton('開始',self) btn1.setGeometry(500,100,50,30) btn1.clicked.connect(self.setFlag) btn2 = QPushButton('重開',self) btn2.setGeometry(550,100,50,30) btn2.clicked.connect(self.clear) self.show() #繪制棋盤與棋子 def paintEvent(self, e) -> None: qp = QPainter() qp.begin(self) qp.fillRect(self.rect(), QColor("light blue")) qp.drawRect(self.rect()) qp.setBackground(QColor("yellow")) qp.setPen(QPen(QColor(0, 0, 0), 2, Qt.SolidLine)) for i in range(15): qp.drawLine(QPoint(30, 30 + 30 * i), QPoint(450, 30 + 30 * i)) for i in range(15): qp.drawLine(QPoint(30 + 30 * i, 30), QPoint(30 + 30 * i, 450)) qp.setBrush(QColor(0, 0, 0)) key_points = [(3, 3), (11, 3), (3, 11), (11, 11), (7, 7)] if len(self.black_chess) != 0: for t in self.black_chess: #畫黑子 qp.drawEllipse(QPoint(30 + 30 * t[1], 30 + 30 * t[0]), 6, 6) for t in key_points: #棋盤的5個定點 qp.drawEllipse(QPoint(30 + 30 * t[0], 30 + 30 * t[1]), 3, 3) qp.setBrush(QColor(255,255,255)) if len(self.white_chess) != 0: for t in self.white_chess: #畫白子 qp.drawEllipse(QPoint(30 + 30 * t[1], 30 + 30 * t[0]), 6, 6) qp.end() #更改標簽,開始游戲 def setFlag(self) -> None: self.flag = True def mousePressEvent(self, e) -> None: if e.buttons() == QtCore.Qt.LeftButton: if e.x() > 15 and e.x() < 465 and e.y() > 15 and e.y() < 465: x = e.x()/30 - e.x()//30 y = e.y()/30 - e.y()//30 self.y = (e.x()-30)//30 if x < 0.5 else (e.x()-30)//30 + 1 self.x = (e.y()-30)//30 if y < 0.5 else (e.y()-30)//30 + 1 if self.flag: print(self.x,self.y) if self.player % 2 == 1: if goBang.put_white_chess(self.x,self.y): self.player += 1 print('黑子行動') else: print('白子行動') if goBang.judge(self.x,self.y): msg_box = QMessageBox(QMessageBox.Information, '提示', '白子獲勝!') msg_box.exec_() else: if goBang.put_black_chess(self.x,self.y): self.player += 1 print('白子行動') else: print('黑子行動') if goBang.judge(self.x,self.y): msg_box = QMessageBox(QMessageBox.Information, '提示', '黑子獲勝!') msg_box.exec_() #下白子 def put_white_chess(self,x:int,y:int) -> bool: if self.chess_board[x][y] != 0: msg_box = QMessageBox(QMessageBox.Information, '提示', '這個位置已經有棋子了!') msg_box.exec_() return False else: self.chess_board[x][y] = 1 self.white_chess.append((x,y)) self.update() return True #下黑子 def put_black_chess(self,x:int,y:int) -> bool: if self.chess_board[x][y] != 0: msg_box = QMessageBox(QMessageBox.Information, '提示', '這個位置已經有棋子了!') msg_box.exec_() return False else: self.chess_board[x][y] = 2 self.black_chess.append((x,y)) self.update() return True #清除棋盤,重開游戲 def clear(self) -> None: self.x = -1 self.y = -1 self.player = 0 self.flag = False self.white_chess = [] self.black_chess = [] self.chess_board = [[0 for i in range(15)] for i in range(15)] self.update() #判斷是否已經五子連珠 def judge(self,x:int,y:int) -> bool: if self.judge_1(x,y) or self.judge_2(x,y) or self.judge_3(x,y) or self.judge_4(x,y): return True return False #判斷橫線 def judge_1(self,x:int,y:int) -> bool: count = 1 if self.chess_board[x][y] != 0: for i in range(1,5): if y - i >= 0: if self.chess_board[x][y] == self.chess_board[x][y-i]: print(x,y-i) count += 1 else: break else: break for i in range(1,5): if y + i <=14: if self.chess_board[x][y] == self.chess_board[x][y+i]: print(x,y+i) count += 1 else: break else: break if count == 5: return True return False #判斷右下線 def judge_2(self,x:int,y:int) -> bool: count = 1 if self.chess_board[x][y] != 0: for i in range(1,5): if x-i >= 0 and y - i >= 0: if self.chess_board[x][y] == self.chess_board[x-i][y-i]: print(x-i,y-i) count += 1 else: break else: break for i in range(1,5): if x + i <= 14 and y + i <= 14: if self.chess_board[x][y] == self.chess_board[x+i][y+i]: print(x+i,y+i) count += 1 else: break else: break if count == 5: return True return False #判斷豎線 def judge_3(self,x:int,y:int) -> bool: count = 1 if self.chess_board[x][y] != 0: for i in range(1,5): if x - i >= 0: if self.chess_board[x][y] == self.chess_board[x-i][y]: print(x-i,y) count += 1 else: break else: break for i in range(1,5): if x + i <= 14: if self.chess_board[x][y] == self.chess_board[x+i][y]: print(x+i,y) count += 1 else: break else: break if count == 5: return True return False #判斷右上線 def judge_4(self,x:int,y:int) -> bool: count = 1 if self.chess_board[x][y] != 0: for i in range(1,5): if x - i >= 0 and y + i <= 14: if self.chess_board[x][y] == self.chess_board[x-i][y+i]: print(x-i,y+i) count += 1 else: break else: break for i in range(1,5): if x + i <= 14 and y - i >= 0: if self.chess_board[x][y] == self.chess_board[x+i][y-i]: print(x+i,y-i) count += 1 else: break else: break if count == 5: return True return False #程序入口 if __name__ == '__main__': app = QApplication(sys.argv) goBang = GoBang() sys.exit(app.exec_())
感謝各位的閱讀,以上就是“Python3怎么利用Qt5實現簡易的五子棋游戲”的內容了,經過本文的學習后,相信大家對Python3怎么利用Qt5實現簡易的五子棋游戲這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。