如何在 Python 中创建井字游戏?

让我们用 Python 创建一个简单的井字游戏。 它将帮助您构建游戏逻辑并了解如何构建代码。

游戏是人类的娱乐方式之一。 我们可以在网络、移动设备、桌面等上找到不同类型的游戏。我们现在不是来制作这些重度游戏的。 我们将使用 Python 创建一个 CLI 井字游戏。

如果您不熟悉井字游戏,请直观地玩一下 这里 去理解。 不用担心,即使您不理解它,我们也会看到它。

井字游戏

本教程分为三个不同的部分。 在第一部分中,您将了解如何玩井字游戏。 之后,我们将看到一个算法帮助我们提出游戏逻辑。 最后,我们将看到结构化代码及其解释。

如果您已经知道如何玩井字游戏,您可以跳过第一部分。

所以,事不宜迟,让我们进入我们的第一部分。

玩井字游戏

一场比赛将有两名球员。 两个标志代表每个玩家。 游戏中使用的一般标志是 X 和 O。最后会有一个有 9 个盒子的棋盘。

直观地查看井字棋盘。

井字游戏板

游戏玩法如下。

  • 首先,一位用户将他们的标志放在一个可用的空框中。
  • 接下来,第二个用户将他们的标志放在一个可用的空框中。
  • 玩家的目标是将他们各自的标志完全按行或按列或对角放置。
  • 游戏一直持续到一名玩家赢得比赛,或者在没有获胜比赛的情况下填满所有盒子而以平局告终。

让我们从视觉上看一些游戏玩法。

井字游戏获胜

玩家 X 在上述游戏中获胜。 所有框对角填充有 X 符号。 因此,相应的玩家赢得了比赛。

共有 8 种方式排列相同的标志并赢得比赛。 让我们看看能赢得比赛的所有 8 种安排。

井字游戏中奖安排

最后,平局填满了棋盘,没有任何获胜安排。 我希望您现在了解如何玩井字游戏。

现在,你的游戏时间到了。 你可以走了 这里 并玩它以完全了解游戏玩法。 如果您已经得到它,请留下它。

现在,是时候移动算法部分了。

算法

我们现在将讨论编写代码的算法。 该算法将帮助您使用您选择的任何编程语言编写代码。 让我们看看它是如何完成的。

  • 使用二维数组创建一个板,并将每个元素初始化为空。
    • 您可以使用任何您喜欢的符号来表示空。 在这里,我们将使用连字符。 ‘-‘。
  • 编写一个函数来检查板子是否被填满。
    • 如果板子包含空符号,则遍历板子并返回 false,否则返回 true。
  • 编写一个函数来检查玩家是否获胜。
    • 我们必须检查我们在上一节中讨论的所有可能性。
    • 检查所有行、列和两条对角线。
  • 编写一个函数来显示棋盘,因为我们将在用户玩游戏时多次向用户显示棋盘。
  • 编写一个函数来启动游戏。
    • 随机选择玩家的第一回合。
    • 编写一个无限循环,在游戏结束时中断(无论是赢还是平)。
      • 向用户展示棋盘以选择下一步行动的地点。
      • 要求用户输入行号和列号。
      • 用相应的球员标志更新现场。
      • 检查当前玩家是否赢得了比赛。
      • 如果当前玩家赢得比赛,则打印获胜消息并打破无限循环。
      • 接下来,检查板子是否已填满。
      • 如果棋盘已满,则打印绘图消息并打破无限循环。
    • 最后,向用户展示板的最终视图。

您可能能够想象正在发生的事情。 不用担心,即使您没有完全理解它。 看到代码后,您会更加清楚。

所以,让我们跳到代码部分。 我假设你已经在你的 PC 上安装了 Python 来尝试代码。

代码

浏览下面的代码。

import random


class TicTacToe:

    def __init__(self):
        self.board = []

    def create_board(self):
        for i in range(3):
            row = []
            for j in range(3):
                row.append('-')
            self.board.append(row)

    def get_random_first_player(self):
        return random.randint(0, 1)

    def fix_spot(self, row, col, player):
        self.board[row][col] = player

    def is_player_win(self, player):
        win = None

        n = len(self.board)

        # checking rows
        for i in range(n):
            win = True
            for j in range(n):
                if self.board[i][j] != player:
                    win = False
                    break
            if win:
                return win

        # checking columns
        for i in range(n):
            win = True
            for j in range(n):
                if self.board[j][i] != player:
                    win = False
                    break
            if win:
                return win

        # checking diagonals
        win = True
        for i in range(n):
            if self.board[i][i] != player:
                win = False
                break
        if win:
            return win

        win = True
        for i in range(n):
            if self.board[i][n - 1 - i] != player:
                win = False
                break
        if win:
            return win
        return False

        for row in self.board:
            for item in row:
                if item == '-':
                    return False
        return True

    def is_board_filled(self):
        for row in self.board:
            for item in row:
                if item == '-':
                    return False
        return True

    def swap_player_turn(self, player):
        return 'X' if player == 'O' else 'O'

    def show_board(self):
        for row in self.board:
            for item in row:
                print(item, end=" ")
            print()

    def start(self):
        self.create_board()

        player="X" if self.get_random_first_player() == 1 else 'O'
        while True:
            print(f"Player {player} turn")

            self.show_board()

            # taking user input
            row, col = list(
                map(int, input("Enter row and column numbers to fix spot: ").split()))
            print()

            # fixing the spot
            self.fix_spot(row - 1, col - 1, player)

            # checking whether current player is won or not
            if self.is_player_win(player):
                print(f"Player {player} wins the game!")
                break

            # checking whether the game is draw or not
            if self.is_board_filled():
                print("Match Draw!")
                break

            # swapping the turn
            player = self.swap_player_turn(player)

        # showing the final view of board
        print()
        self.show_board()


# starting the game
tic_tac_toe = TicTacToe()
tic_tac_toe.start()

查看代码的示例输出。

$ python tic_tac_toe.py 
Player X turn
- - -
- - -
- - -
Enter row and column numbers to fix spot: 1 1

Player O turn
X - -
- - -
- - -
Enter row and column numbers to fix spot: 2 1

Player X turn
X - -
O - -
- - -
Enter row and column numbers to fix spot: 1 2

Player O turn
X X -
O - -
- - -
Enter row and column numbers to fix spot: 1 3

Player X turn
X X O
O - -
- - -
Enter row and column numbers to fix spot: 2 2

Player O turn
X X O
O X -
- - -
Enter row and column numbers to fix spot: 3 3

Player X turn
X X O        
O X -        
- - O
Enter row and column numbers to fix spot: 3 2

Player X wins the game!

X X O
O X -
- X O

帮助您理解代码结构的一些要点。

  • 我们使用一个类将所有方法放在一个地方。 它也可以很容易地成为其他代码中的可重用包。
  • 接下来,我们为每个职责定义了不同的功能,即使它是一个小任务。 它有助于轻松维护代码。
  • 如果我们想更新游戏,以上两种方法可以帮助我们毫不费力地更新应用程序。
  谷歌幻灯片初学者指南

随意调整结构并根据您的项目进行改进。 代码结构不受限制。

最后的话

欢呼! 😎 您完全从头开始创建游戏。 这不是我们每天玩的视觉游戏之一。 但它可以帮助您编写逻辑并在代码中保持干净的结构。 遵循类似的准则来创建一些类似这样的有趣游戏。 如果您回到童年时代,您可以找到类似的游戏。

快乐编码! 👩‍💻

接下来,探索如何使用 Python unittest 模块创建猜数游戏和单元测试。

喜欢阅读这篇文章吗? 与世界分享如何?