在下面的教程中,我们将使用Python编程语言从头开始创建一个名为井字游戏的游戏。我们将整个程序分为不同的步骤,以便更好地理解。但在开始操作之前,让我们先了解一下这个游戏。

什么是井字游戏?

井字游戏是两名玩家之间进行的一种游戏,游戏是在一个3 x 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")  

解释:

在上面的代码片段中,我们定义了一个用于井字游戏的函数,该函数以值作为参数。这里的val参数是一个包含网格中每个单元格状态的列表。在函数内部,我们打印了井字游戏网格的设计。

现在,下一步是使用数据结构存储数据。

使用数据结构存储数据

任何游戏的原理都依赖于游戏背后的机制。由于我们正在创建一个相对简单的游戏,所包含的机制也很简单。

在任何时间点,都需要两个关键信息:

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' : []}  

解释:

在上述代码片段中,我们定义了一个用于井字游戏的单个游戏的函数,其中val表示前一个函数的参数,playerpos存储由叉号(X)零(O)分别占据的方块的位置。

字符列表中通常有三个值,用于管理网格状态:

  1. ' ' - 此字符表示空单元格。
  2. 'X' - 此字符表示X玩家占据的单元格。
  3. 'O' - 此字符表示O玩家占据的单元格。

每位玩家的动作都存储在一个整数列表的字典中,其中键由'X''O'表示对应的玩家。它们的各自列表包括分配给它们在网格中的单元格的数字。

注意:curplayer变量存储着当前进行移动的玩家,如'X'或'O'。

理解游戏循环

每个游戏都包含某种游戏循环,允许玩家玩游戏,直到有玩家获胜或游戏结束为止。在井字游戏中,游戏的每个迭代表示玩家的一个动作。

让我们考虑以下代码片段以设计游戏循环。

语法:

# Loop of Game for a single game of Tic-Tac-Toe  
while True:  
    mytictactoe(val) 

解释:

正如我们可以看到的,我们使用while循环来打印函数mytictactoe()的值,为单个井字游戏创建了一个游戏循环。

处理玩家输入

在游戏的每个迭代中,玩家必须提供他们的移动输入。让我们考虑以下语法以处理玩家的输入。

语法:

# 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块来处理玩家的意外值。然后我们处理了ValueError的异常,以便游戏不会停止。然后我们进行了一些合理性检查,例如输入值是否是有效位置,如果是有效位置,它是否已经被填充?

现在,让我们继续下一步。

更新游戏信息

根据玩家提供的输入,我们必须更新游戏的信息,以确保游戏顺利进行。我们可以通过将以下代码片段添加到主项目来更新游戏信息。

语法:

# 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列表将根据当前玩家更新单元格。玩家的位置将添加到当前玩家刚占据的位置。

一旦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语句来检查胜利或平局。如果singlegame()函数返回当前玩家,那么他/她获胜了游戏。否则,游戏是平局的,会返回'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(): 它存储了所有获胜游戏的组合。函数检查当前玩家的位置是否满足任何获胜组合的要求。如果是,它将返回True;否则,它将返回False,表示不满足要求。
  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)  

解释:

在上面的代码片段中,我们将当前玩家设置为第一个玩家。我们还存储了玩家的选择、可用选项和记分板。

设计记分板

我们将设计一个字典数据结构的记分板。在此记分板中,玩家的名称将充当键,其获胜的总数将充当值。让我们考虑以下语法,以设计Tic-Tac-Toe的记分板。

语法:

def myscoreboard(scoreboard):  
    print("\t--------------------------------")  
    print("\t         SCORE BOARD       ")  
    print("\t--------------------------------")  
   
    listlistofplayers = list(scoreboard.keys())  
    print("\t   ", listofplayers[0], "\t    ", scoreboard[listofplayers[0]])  
    print("\t   ", listofplayers[1], "\t    ", scoreboard[listofplayers[1]])  
   
    print("\t--------------------------------\n")  

解释:

在上述代码片段中,我们定义了myscoreboard函数,该函数接受scoreboard作为参数。然后,我们打印了记分板的设计。我们使用.keys()函数将玩家的名称存储为列表,并将它们索引到记分板并显示得分。

创建外部游戏循环

为了维护多场Tic-Tac-Toe比赛,我们需要另一个循环来进行游戏。当前玩家将在每场比赛中选择标记。在每次迭代中,都应显示选择菜单。

让我们考虑以下语法以创建外部游戏循环。

语法:

# 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循环,以在每次迭代中显示主菜单,当前玩家可以在其中选择标记(Cross 'X'或Naught '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")  

解释:

在上述代码片段中,我们通过input()函数获取当前玩家的选择。然后,我们对选择进行验证,以确保它是1、2或3。最后,我们根据选择将当前玩家分配为'X'或'O',并更改另一个玩家的选择。

执行游戏

在存储所有所需信息后,我们可以执行一场独立的比赛并记录胜利者。

下面是相应的语法。

语法:

# 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语句来在玩家之间切换选择标记(叉或圈)。

因此,我们已经成功构建了我们自己的井字棋游戏。

下载代码

游戏的代码可以从此链接下载: https://static.javatpoint.com/python/download/TicTacToe.zip

游戏时间到了

由于所有步骤最终都完成了,这是游戏的最终输出。

输出:

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
        --------------------------------

标签: Tkinter教程, Tkinter安装, Tkinter库, Tkinter入门, Tkinter学习, Tkinter入门教程, Tkinter, Tkinter进阶, Tkinter指南, Tkinter学习指南, Tkinter进阶教程, Tkinter编程