最具Python风格的井字棋棋盘表示方法?

1 投票
1 回答
1092 浏览
提问于 2025-04-18 11:46

在Python中,表示井字棋游戏的棋盘和获胜组合的最“Pythonic”方式是什么呢?

我一开始选择了第一种方案,觉得把每个棋子作为独立的对象放在一个二维数组里,这样更符合面向对象的编程思想:

class GameTile:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.value = None  # value is either "x", "o", or None

class GameBoard:
    _board_size = 3
    _player = "o"
    _computer = "x"

    def __init__(self):
        # generate the tile set
        self.tiles = [[GameTile(x, y) for y in range(GameBoard._board_size)] for x in range(GameBoard._board_size)]

        # generate winning combos
        self.winning_combos = [col for col in self.tiles] + \  #vertical
                          [[col[i] for col in self.tiles] for i in range(GameBoard._board_size)] + \  # horizontal
                          [[self.tiles[i][i] for i in range(GameBoard._board_size)]] + \  #diagonal
                          [[self.tiles[i][GameBoard._board_size - i - 1] for i in range(GameBoard._board_size)]]  #diagonal

不过,越看越觉得,其实棋盘可以更简单地用一个值的列表来表示这些移动,同时用一个固定的获胜组合列表,这样就不需要动态定义了:

class GameBoard:
    _board_size = 3
    _player = "o"
    _computer = "x"
    _winning_combos = [[0, 1, 2], [3, 4, 5], [6, 7, 8], etc...]

    def __init__(self):
        self.board = [None] * 9

第二种方法简单多了,但这真的是最“Pythonic”的做法吗?或者我问的问题根本就不对?

另外,在第二个例子中,获胜组合用元组的列表表示会不会更好,因为元组是不可变的?还是说这样在计算赢家时会造成效率低下,因为要和列表进行比较?

1 个回答

3

我觉得你可能把事情想得太复杂了。

我不确定这是不是最符合Python风格的方法,但最合理的做法是使用一个二维的整数或字符串矩阵,而不是使用GameTile对象。为什么呢?当一个整数或字符串就能包含你需要的所有信息时,为什么还要额外创建一个类呢?在这个矩阵中,位置是隐含的,而每个方块的值可以用整数来表示(0表示空,1表示第一玩家,2表示第二玩家)或者用字符串。

matrix = [[0 for y in range(3)] for x in range(3)]

其实就这么简单。

撰写回答