📜  谜题 80 |井字游戏重温(1)

📅  最后修改于: 2023-12-03 15:41:48.545000             🧑  作者: Mango

谜题 80 | 井字游戏重温

简介

本题是一道关于井字游戏的谜题,需要实现一个可以判断胜负的游戏程序。井字游戏是一种在3x3方格中进行的游戏,其中两个玩家轮流将X和O填入格子中,先在一行、一列或对角线上连成三个符号的玩家获胜。

要求

实现一个函数,参数为一个包含井字游戏的所有格子的列表,列表中每一个元素表示一个格子的状态,返回值为当前胜者的符号('X'或'O')或字符串'Draw'代表平局。如果游戏还未结束则返回字符串'Pending'。

示例
def tictactoe(moves: List[List[int]]) -> str:
    # Your Code
print(tictactoe([[0, 0], [2, 0], [1, 1], [2, 1], [2, 2]])) # 'A'
print(tictactoe([[0, 0], [1, 1], [0, 1], [0, 2], [1, 0], [2, 0]])) # 'B'
print(tictactoe([[0, 0], [1, 1], [2, 0], [1, 0], [1, 2], [2, 1], [0, 1], [0, 2], [2, 2]])) # 'Draw'
print(tictactoe([[0, 0], [1, 1]])) # 'Pending'
思路

井字游戏只有九个格子,所以可以考虑直接遍历所有可能获胜的情况(一行、一列、两条对角线)。由于先手一定是X,后手一定是O,所以我们也可以直接用剩余的格子数来判断当前轮到了哪一位玩家。

class Solution:
    def tictactoe(self, moves: List[List[int]]) -> str:
        # 初始化棋盘
        board = [[' ' for i in range(3)] for j in range(3)]
        # 标记是否轮到 X
        X_turn = True
        # 遍历所有步骤
        for move in moves:
            # 获取 row 和 col
            row, col = move
            # 更改棋盘状态
            board[row][col] = 'X' if X_turn else 'O'
            # 判断当前玩家是否获胜
            if self.check_win(board, 'X' if X_turn else 'O'):
                return 'X' if X_turn else 'O'
            # 检查是否为平局
            if self.check_draw(board):
                return 'Draw'
            # 更改轮到哪一位玩家
            X_turn = not X_turn
        # 如果还未结束则返回 Pending
        return 'Pending'

    # 检查是否平局
    def check_draw(self, board) -> bool:
        for i in range(3):
            for j in range(3):
                if board[i][j] == ' ':
                    return False
        return True

    # 检查是否获胜
    def check_win(self, board, symbol) -> bool:
        # 检查所有行
        for i in range(3):
            if board[i][0] == board[i][1] == board[i][2] == symbol:
                return True
        # 检查所有列
        for j in range(3):
            if board[0][j] == board[1][j] == board[2][j] == symbol:
                return True
        # 检查主对角线
        if board[0][0] == board[1][1] == board[2][2] == symbol:
            return True
        # 检查副对角线
        if board[0][2] == board[1][1] == board[2][0] == symbol:
            return True
        # 如果都没有获胜则返回 False
        return False
总结

本题是一道比较简单的逻辑编程题目,适合新手练习。主要考察对数组和循环的理解,以及如何通过遍历实现对所有情况的判断。同时,本题也可以通过使用位运算来优化解法,不过这里暂不展开讲解。