在下面的教程中,我們將從頭開始使用 Python 編程語言創建一個名為井字棋的遊戲。為了更好地理解,我們將整個程序分成了不同的步驟。但是在我們進入程序之前,讓我們了解一下這個遊戲。
井字棋是兩名玩家在3×3 方形格子上玩的遊戲之一。每個玩家在各自的回合中佔據一個單元,保持以垂直、水平或對角線模式放置三個相似標記的目標。第一個玩家使用十字(X) 作為標記,而另一個玩家使用零或零(O) 。
現在,讓我們了解井字棋的設計。
我們將使用命令提示符來玩井字棋。因此,主要目標是為井字棋構建一個設計。
目的:如果玩家需要標記特定的區塊,他/她必須輸入網格中顯示的對應數字。例如,我們想佔據右上方的塊,然後我們必須在終端中輸入數字 3。
讓我們理解生成網格的代碼片段。
程序:
# Function to print the Tic-Tac-Toe Design
def mytictactoe(val):
print("\n")
print("\t | |")
print("\t {} | {} | {}".format(val[0], val[1], val[2]))
print('\t_____|_____|_____')
print("\t | |")
print("\t {} | {} | {}".format(val[3], val[4], val[5]))
print('\t_____|_____|_____')
print("\t | |")
print("\t {} | {} | {}".format(val[6], val[7], val[8]))
print("\t | |")
print("\n")
說明:
在上面的代碼片段中,我們為井字棋定義了一個以值為參數的函數。這裡的值參數是由網格中每個單元的狀態組成的列表。在功能中,我們打印了井字棋網格的設計。
現在,下一步是藉助數據結構存儲數據。
任何遊戲的原理都依賴於遊戲背後的機制。因為我們正在創建一個相對簡單和容易的遊戲,包括的機制也很簡單。
在任何時間點,都需要兩條關鍵信息:
- 網格狀態:我們必須創建一個包含每個單元狀態的數據結構。這個州可以是有人的,也可以是空的。
- 每個玩家的招式:不知何故需要知道每個玩家過去和現在的招式,也就是‘X’和‘O’所佔據的位置。
其語法如下所示:
代碼片段:
# Function for a single game of Tic-Tac-Toe
def singlegame(curplayer):
# Representing the Tic-Tac-Toe
val = [' ' for i in range(9)]
# Storing the positions occupied by X and O
playerpos = {'X' : [], 'O' : []}
說明:
在上面的代碼片段中,我們為井字棋定義了一個函數,其中值代表前一個函數的參數, playerpos 分別存儲由十字(X) 和零(O) 佔據的區塊位置。
管理網格狀態的字符列表中通常有三個值:
- ‘ ‘ -該字符表示空單元格。
- ‘X’-這個字符表示一個細胞被 X 玩家居住。
- ‘O’-這個字符表示一個細胞被 O 玩家居住。
每個玩家的移動被保存為整數列表的字典,其中鍵由對應玩家的【X】和【O】表示。它們各自的列表由提供給它們所在網格中的單元格的數字組成。
每一個遊戲都由某種類型的遊戲循環組成,允許玩家玩遊戲,直到玩家贏了或者遊戲打成平手。在井字棋中,每個循環迭代都表示任何玩家的一次移動。
讓我們考慮下面的代碼片段來設計遊戲循環。
語法:
# Loop of Game for a single game of Tic-Tac-Toe
while True:
mytictactoe(val)
說明:
正如我們所觀察到的,我們已經使用 While
循環打印了函數 mytictactoe() 的值,為 Tic-Tac-Toe 的單個遊戲生成了一個遊戲循環。
處理玩家的輸入
對於遊戲中的每一次迭代,玩家必須為他的移動提供輸入。讓我們考慮以下語法來處理玩家的輸入。
語法:
# Try-Exception block for CHANCE input
try:
print("Player ", curplayer, " turn. Choose your Block : ", end="")
chance = int(input())
except ValueError:
print("Invalid Input!!! Try Again")
continue
# Sanity check for CHANCE input
if chance < 1 or chance > 9:
print("Invalid Input!!! Try Again")
continue
# Checking if the block is not occupied already
if val[chance - 1] != ' ':
print("Oops! The Place is already occupied. Try again!!")
continue
說明:
對於上面的代碼片段,我們已經創建了一個 try 塊來處理玩家的非預期值。然後我們處理了值錯誤的異常,這樣遊戲就不會停止。稍後,我們進行了一些健全性檢查,例如輸入的值是否是有效的位置,如果是有效的位置,它是否已經被填充?
現在,讓我們進入下一步。
根據玩家提供的輸入,為了遊戲的順利進行,我們必須更新信息。我們可以通過在主項目中添加以下代碼片段來更新遊戲信息。
語法:
# Updating the game information
# Update the status of the grid
val[chance - 1] = curplayer
# Update the positions of the player
playerpos[curplayer].append(chance)
說明:
在上面的代碼片段中,我們通過更新網格的狀態和玩家的位置來更新遊戲信息。值列表將根據當前玩家更新填充的單元格。玩家的位置會加上當前玩家剛剛佔據的位置。
一旦 val 列表更新,我們將調用 mytictactoe() 函數,網格如下圖所示:
輸出:
| |
1 | 2 | 3
_____|_____|_____
| |
4 | 5 | 6
_____|_____|_____
| |
7 | 8 | 9
| |
在每一次移動之後,我們需要檢查是否有球員贏得了比賽或者比賽已經打成平手。我們可以藉助下面給出的語法來檢查它:
語法:
# Calling Function to check Victory
if check_Victory(playerpos, curplayer):
mytictactoe(val)
print("Congratulations! Player ", curplayer, " has won the game!")
print("\n")
return curplayer
# Calling Function to check Tie
if check_Tie(playerpos):
mytictactoe(val)
print("Oh! Game Tied")
print("\n")
return 'D'
說明:
在上面的語法中,我們使用了 if 語句來檢查 Win 或 Tie。單人遊戲()功能將返回當前玩家,如果他/她贏得遊戲。否則,比賽打成平手,‘D’被送回。
讓我們考慮一下檢查是否有玩家獲勝的功能。
語法:
# Defining Function to check Victory
def check_Victory(playerpos, curplayer):
# All probable winning combinations
solution = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 4, 7], [2, 5, 8], [3, 6, 9], [1, 5, 9], [3, 5, 7]]
# Loop to check whether any winning combination is satisfied or not
for i in solution:
if all(j in playerpos[curplayer] for j in i):
# Return True if any winning combination is satisfied
return True
# Return False if no combination is satisfied
return False
# Defining Function to check if the game is Tied
def check_Tie(playerpos):
if len(playerpos['X']) + len(playerpos['O']) == 9:
return True
return False
說明:
在上面的代碼片段中,我們已經定義了檢查勝利或平局的函數。這些功能分別是 check_Victory() 和 check_Tie() 。
- check_Victory(): 它存儲了贏得遊戲的所有組合。該功能檢查當前玩家的位置是否滿足任何獲勝組合。如果是,它將返回真;否則,不滿足要求將為假。
- check_Tie(): 挺簡單的,檢查所有‘九’位是否都被佔用,遊戲就平手了。
每個玩家一次只有一次機會。因此,每成功一次,當前玩家將被交換。讓我們考慮下面的代碼片段:
語法:
# Switching moves of the player
if curplayer == 'X':
curplayer = 'O'
else:
curplayer = 'X'
說明:
在下面的代碼片段中,我們使用了 if-else 語句來切換玩家的移動,如果當前玩家標記了一個位置,那麼當前玩家將被改變,另一個玩家將標記他們的移動。
這些是我們在製作一個遊戲時需要關注的一些步驟。然而,我們將創建一個記分板系統來記錄想要玩多種遊戲的玩家。
因為我們正在創建一個記分牌,所以我們有必要顯示每個玩家的名字。
下面是相同的語法:
語法:
if __name__ == "__main__":
print("First Player")
FirstPlayer = input("Specify the Name: ")
print("\n")
print("Second Player")
SecondPlayer = input("Specify the Name: ")
print("\n")
說明:
我們可以觀察到,我們使用了特殊變量 name 來獲得“ main ”的值。然後,我們分別為第一個和第二個玩家的名字提供了輸入。這將成為程序的入口點,當我們將要執行的程序時,它會先詢問名字。
我們必須存儲諸如當前玩家、玩家選擇(即 X 或 O)、可用選擇(X 或 O)和記分板等信息。
語法:
# Storing the player who chooses X and O
curplayer = FirstPlayer
# Storing the Players' choice
playerchoice = {'X' : "", 'O' : ""}
# Storing the options
opt = ['X', 'O']
# Storing the scoreboard
scoreboard = {FirstPlayer: 0, SecondPlayer: 0}
myscoreboard(scoreboard)
說明:
在上面的代碼片段中,我們已經將當前玩家設置為第一個玩家。我們還存儲了玩家的選擇、可用選項和記分板。
我們將在字典數據結構中設計一個記分板。對於這個記分牌,玩家的名字將作為鍵,他們的勝利總數將作為值。讓我們考慮下面的代碼片段來設計井字棋的記分牌。
語法:
def myscoreboard(scoreboard):
print("\t--------------------------------")
print("\t SCORE BOARD ")
print("\t--------------------------------")
listofplayers = list(scoreboard.keys())
print("\t ", listofplayers[0], "\t ", scoreboard[listofplayers[0]])
print("\t ", listofplayers[1], "\t ", scoreboard[listofplayers[1]])
print("\t--------------------------------\n")
說明:
在上面的代碼片段中,我們將函數定義為 myscoreboard ,它將參數作為記分牌。然後,我們為計分板打印了設計。我們已經使用定義了一個變量,該變量將玩家的名字存儲為一個列表。按鍵()功能。然後我們將它們編入記分牌並顯示分數。
為了維持井字棋的多場比賽,我們要求遊戲再循環一次。當前玩家將為每場比賽選擇標記。選擇菜單應該在遊戲的每次迭代中顯示。
讓我們考慮以下語法來創建外部玩家循環。
語法:
# Loop for a series of Tic-Tac-Toe game
# The loop executes until the players quit
while True:
# Main Menu for Players
print(curplayer, "will make the choice:")
print("Press 1 for X")
print("Press 2 for O")
print("Press 3 to Quit")
說明:
在上面的代碼片段中,我們創建了一個 while 循環來顯示玩家的主菜單,當前玩家可以在標記(十字“X”或零“O”)之間進行選擇或退出遊戲。
輸出:
First Player
Specify the Name: Andy
Second Player
Specify the Name: Carlo
--------------------------------
SCORE BOARD
--------------------------------
Andy 0
Carlo 0
--------------------------------
Andy will make the choice:
Press 1 for X
Press 2 for O
Press 3 to Quit
我們需要為每次迭代處理和存儲當前玩家的選擇。讓我們考慮下面的代碼片段。
語法:
# Try exception for THE_CHOICE input
try:
the_choice = int(input())
except ValueError:
print("Invalid Input!!! Try Again\n")
continue
# Conditions for player choice
if the_choice == 1:
playerchoice['X'] = curplayer
if curplayer == FirstPlayer:
playerchoice['O'] = SecondPlayer
else:
playerchoice['O'] = FirstPlayer
elif the_choice == 2:
playerchoice['O'] = curplayer
if curplayer == FirstPlayer:
playerchoice['X'] = SecondPlayer
else:
playerchoice['X'] = FirstPlayer
elif the_choice == 3:
print("The Final Scores")
myscoreboard(scoreboard)
break
else:
print("Invalid Selection!! Try Again\n")
說明:
在上面的代碼片段中,我們使用了 try-exception 塊來處理 _choice 輸入的任何異常。然後,我們使用 If-else
語句為當前玩家創建了可供選擇的選項菜單。
根據玩家的選擇,數據將被存儲。這很有意義,因為它會告訴我們每場比賽後誰贏了。
一旦存儲了所有需要的信息,我們就可以執行獨立的比賽並記錄勝利標記。
其語法如下所示。
語法:
# Storing the winner in a single game of Tic-Tac-Toe
win = singlegame(opt[the_choice - 1])
說明:
在上面的代碼片段中,我們已經存儲了一個井字棋的贏家詳細信息。
井字棋的每一場比賽後,我們都要更新記分牌。
讓我們考慮以下代碼片段來更新記分板。
語法:
# Updation of the scoreboard as per the winner
if win != 'D' :
playerWon = playerchoice[win]
scoreboard[playerWon] = scoreboard[playerWon] + 1
myscoreboard(scoreboard)
說明:
在上面的代碼片段中,我們使用了 if
語句來檢查匹配是否不匹配。一旦比賽沒有結束,記分牌就會更新。
在玩遊戲時,切換選擇標記的機會變得強制性。因此,讓我們考慮以下語法來理解交換。
語法:
# Switching player who chooses X or O
if curplayer == FirstPlayer:
curplayer = SecondPlayer
else:
curplayer = FirstPlayer
說明:
在上面的代碼片段中,我們再次使用 If-else
語句在玩家之間切換以選擇標記(十字或無)。
因此,我們成功地構建了自己的井字棋。遊戲代碼可從該鏈接下載: 點擊此處下載
由於所有的步驟最終都完成了,這裡是遊戲的最終輸出。
輸出:
First Player
Specify the Name: Andy
Second Player
Specify the Name: Carlo
--------------------------------
SCORE BOARD
--------------------------------
Andy 0
Carlo 0
--------------------------------
Andy will make the choice:
Press 1 for X
Press 2 for O
Press 3 to Quit
1
| |
| |
_____|_____|_____
| |
| |
_____|_____|_____
| |
| |
| |
Player X turn. Choose your Block : 5
| |
| |
_____|_____|_____
| |
| X |
_____|_____|_____
| |
| |
| |
Player O turn. Choose your Block : 3
| |
| | O
_____|_____|_____
| |
| X |
_____|_____|_____
| |
| |
| |
Player X turn. Choose your Block : 1
| |
X | | O
_____|_____|_____
| |
| X |
_____|_____|_____
| |
| |
| |
Player O turn. Choose your Block : 9
| |
X | | O
_____|_____|_____
| |
| X |
_____|_____|_____
| |
| | O
| |
Player X turn. Choose your Block : 6
| |
X | | O
_____|_____|_____
| |
| X | X
_____|_____|_____
| |
| | O
| |
Player O turn. Choose your Block : 4
| |
X | | O
_____|_____|_____
| |
O | X | X
_____|_____|_____
| |
| | O
| |
Player X turn. Choose your Block : 2
| |
X | X | O
_____|_____|_____
| |
O | X | X
_____|_____|_____
| |
| | O
| |
Player O turn. Choose your Block : 8
| |
X | X | O
_____|_____|_____
| |
O | X | X
_____|_____|_____
| |
| O | O
| |
Player X turn. Choose your Block : 7
| |
X | X | O
_____|_____|_____
| |
O | X | X
_____|_____|_____
| |
X | O | O
| |
Game Tied
--------------------------------
SCORE BOARD
--------------------------------
Andy 0
Carlo 0
--------------------------------
Carlo will make the choice:
Press 1 for X
Press 2 for O
Press 3 to Quit
3
The Final Scores
--------------------------------
SCORE BOARD
--------------------------------
Andy 0
Carlo 0
--------------------------------
原創文章,作者:LE01V,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/127321.html