Python 中的井字棋

2025 年 1 月 8 日 | 12 分钟阅读

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

什么是井字游戏?

井字游戏是一种在 3x3 方格网格上进行的双人游戏。每个玩家轮流占据一个单元格,目标是在垂直、水平或对角线上放置三个相同的标记。第一个玩家使用交叉 (X) 作为标记,而另一个玩家使用圆圈或零 (O)

现在,让我们了解一下井字游戏的设计。

井字游戏的设计

我们将使用命令提示符来玩井字游戏。因此,首要目标是为井字游戏构建一个设计。

目标:如果玩家需要标记特定方块,他/她必须输入网格中显示的相应数字。例如,如果我们想占据右上角的方块,那么我们必须在终端中输入数字 3。

让我们了解一下生成网格的代码片段。

程序

说明

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

现在,下一步是借助数据结构存储数据。

使用数据结构存储数据

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

在任何时候,都需要两条关键信息

  1. 网格状态:我们必须创建一个由每个单元格状态组成的数据结构。状态可以是已被占据或空闲。
  2. 每个玩家的走法:需要某种方式记录每个玩家过去和现在的走法数据,即 'X' 和 'O' 占据的位置。因此,我们将创建一个数据结构来存储玩家的位置。

注意:上述数据可以通过网格状态来访问。然而,每次我们想获取玩家位置时,都需要遍历这些信息。这可以称为时间与空间复杂度的权衡。这是一种节省时间的通用技术。

其语法如下所示

代码片段

说明

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

管理网格状态的字符列表通常有三个值

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

每个玩家的移动都以整数列表的字典形式保存,其中键由相应玩家的 'X''O' 表示。它们各自的列表包含他们占据的网格单元格所提供的数字。

注意:curplayer 变量存储当前正在移动的玩家,例如 'X' 或 'O'。

理解游戏循环

每个游戏都包含某种类型的游戏循环,允许玩家一直玩游戏,直到一个玩家获胜或游戏平局。在井字游戏中,每次循环迭代都表示任何玩家做出的一次移动。

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

语法

说明

正如我们所观察到的,我们使用了 while 循环来打印函数 mytictactoe() 的值,从而为一局井字游戏生成一个游戏循环。

处理玩家输入

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

语法

说明

对于上面的代码片段,我们创建了一个 try 块来处理玩家的意外值。然后我们处理了 ValueError 异常,以防止游戏停止。之后,我们进行了一些健全性检查,例如输入的值是否是有效位置,如果是有效位置,它是否已经被填充?

现在,让我们进入下一步。

更新游戏信息

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

语法

说明

在上面的代码片段中,我们通过更新网格状态和玩家位置来更新游戏信息。val 列表将根据当前玩家更新已填充的单元格。玩家位置将添加当前玩家刚刚占据的位置。

一旦 val 列表更新,我们将调用 mytictactoe() 函数,网格将如下图所示

输出

             |     |
          1  |  2  |  3
        _____|_____|_____
             |     |
          4  |  5  |  6
        _____|_____|_____
             |     |
          7  |  8  |  9
             |     |

检查输赢或平局

每一步之后,我们需要检查是否有玩家获胜或比赛是否平局。我们可以借助以下语法进行检查

语法

说明

在上面的语法中,我们使用了 if 语句来检查胜利或平局。如果 singlegame() 函数返回当前玩家赢得比赛,则返回该玩家。否则,比赛平局,返回 'D'

让我们考虑一下检查是否有玩家获胜的函数。

语法

说明

在上面的代码片段中,我们定义了检查胜利或平局的函数。这些函数分别是 check_Victory()check_Tie()

  1. check_Victory():它存储了所有获胜组合。该函数检查当前玩家的位置是否满足任何获胜组合。如果满足,则返回 TRUE;否则,返回 FALSE,表示不满足要求。
  2. check_Tie():这很简单,它检查是否所有“九个”位置都被占据,如果都被占据,则游戏平局。

切换当前玩家

每个玩家每次只有一次机会。因此,每次成功移动后,当前玩家将被交换。让我们考虑以下代码片段来实现这一点

语法

说明

在以下代码片段中,我们使用 if-else 语句来切换玩家的移动,这样如果当前玩家标记一个位置,则当前玩家将被更改,另一个玩家将标记他们的移动。

这些是我们在制作一个游戏时需要关注的一些步骤。但是,我们将创建一个计分板系统来跟踪想要玩多个游戏的玩家。

输入玩家姓名

由于我们正在创建一个记分板,因此显示每个玩家的姓名变得很有必要。

以下是相应的语法

语法

说明

正如我们所观察到的,我们使用了特殊变量 __name__ 来获取 "__main__" 的值。然后我们分别提供了第一位和第二位玩家的姓名输入。这将成为程序的入口点,当程序执行时,它将首先询问姓名。

存储游戏相关信息

我们需要存储诸如当前玩家、玩家选择(即 X 或 O)、可用选择(X 或 O)和记分板等信息。

语法

说明

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

设计记分板

我们将使用字典数据结构设计一个记分板。对于这个记分板,玩家姓名将作为键,他们的总胜利次数将作为值。让我们考虑以下代码片段来设计井字游戏的记分板。

语法

说明

在上面的代码片段中,我们定义了函数 myscoreboard,它以 scoreboard 作为参数。然后我们打印了记分板的设计。我们定义了一个变量,该变量使用 .keys() 函数以列表形式存储玩家的姓名。然后我们将它们索引到记分板中并显示分数。

创建外部游戏循环

为了维护多场井字游戏,我们需要另一个游戏循环。当前玩家将为每场比赛选择标记。选择菜单应在游戏的每次迭代中显示。

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

语法

说明

在上面的代码片段中,我们创建了一个 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-except 块来处理 the_choice 输入的任何异常。然后我们使用了 if-else 语句来为当前玩家创建选择菜单,供他们选择。

根据玩家做出的选择,数据将被存储。这很重要,因为它将告诉我们在每场比赛后哪个玩家获胜。

执行游戏

一旦所有必要的信息都已存储,我们就可以执行一场独立的比赛并记录获胜标记。

其语法如下所示。

语法

说明

在上面的代码片段中,我们存储了单场井字游戏的获胜者详细信息。

更新计分板

每场井字游戏结束后,我们都必须更新记分板。

让我们考虑以下代码片段来更新计分板。

语法

说明

在上面的代码片段中,我们使用 if 语句来检查比赛是否未平局。一旦比赛未平局,记分板就会更新。

切换选择玩家

在玩游戏时,切换选择标记的机会是强制性的。因此,让我们考虑以下语法来理解交换。

语法

说明

在上面的代码片段中,我们再次使用 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
        --------------------------------