Python 中的井字棋

在下面的教程中,我們將從頭開始使用 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")

說明:

在上面的代碼片段中,我們為井字棋定義了一個以值為參數的函數。這裡的值參數是由網格中每個單元的狀態組成的列表。在功能中,我們打印了井字棋網格的設計。

現在,下一步是藉助數據結構存儲數據。

任何遊戲的原理都依賴於遊戲背後的機制。因為我們正在創建一個相對簡單和容易的遊戲,包括的機制也很簡單。

在任何時間點,都需要兩條關鍵信息:

  1. 網格狀態:我們必須創建一個包含每個單元狀態的數據結構。這個州可以是有人的,也可以是空的。
  2. 每個玩家的招式:不知何故需要知道每個玩家過去和現在的招式,也就是『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) 佔據的區塊位置。

管理網格狀態的字符列表中通常有三個值:

  1. ‘ ‘ -該字符表示空單元格。
  2. 『X』-這個字符表示一個細胞被 X 玩家居住。
  3. 『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() 。

  1. check_Victory(): 它存儲了贏得遊戲的所有組合。該功能檢查當前玩家的位置是否滿足任何獲勝組合。如果是,它將返回真;否則,不滿足要求將為假。
  2. 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-hk/n/127321.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
LE01V的頭像LE01V
上一篇 2024-10-03 23:13
下一篇 2024-10-03 23:15

相關推薦

  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • Python列表中負數的個數

    Python列表是一個有序的集合,可以存儲多個不同類型的元素。而負數是指小於0的整數。在Python列表中,我們想要找到負數的個數,可以通過以下幾個方面進行實現。 一、使用循環遍歷…

    編程 2025-04-29
  • 如何查看Anaconda中Python路徑

    對Anaconda中Python路徑即conda環境的查看進行詳細的闡述。 一、使用命令行查看 1、在Windows系統中,可以使用命令提示符(cmd)或者Anaconda Pro…

    編程 2025-04-29
  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29
  • Python編程二級證書考試相關現已可以上網購買

    計算機二級Python考試是一項重要的國家級認證考試,也是Python編程的入門考試。與其他考試一樣,Python編程二級證書的考生需要進入正式考試,而為了備考,這篇文章將詳細介紹…

    編程 2025-04-29

發表回復

登錄後才能評論