You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python CLI版围棋游戏落子验证逻辑错误导致无限循环求助

CLI版围棋游戏无限要求白方落子问题排查

我出于兴趣用Python开发了一款无UI的CLI版围棋游戏,希望实现落子位置是否为空的验证逻辑:棋盘空交点用' * '表示,黑棋为'0',白棋为'1',当轮到黑方落子时,若目标位置为空则改为'0',否则要求黑方重新落子;白方规则同理。但当前程序运行时会无限要求白方落子,以下是完整代码及运行现象,请问我哪里出错了?

完整代码

class GoGame:
    board: list
    _PLAYER_BLACK = " 0 "
    _PLAYER_WHITE = " 1 "
    _black_move_done = False
    _white_move_done = False

    def __init__(self, board):
        self.board = board

    def display_board(self, board):
        for i in range(len(self.board)):
            for j in range(len(self.board)):
                print(board[i][j], end='')
            print()

    def black_move(self):
        i, j = input("Black to move: ").split()
        self.board[int(i)][int(j)] = self._PLAYER_BLACK
        self.display_board(self.board)
        self._black_move_done = True

    def white_move(self):
        i, j = input("White to move: ").split()
        self.board[int(i)][int(j)] = self._PLAYER_WHITE
        self.display_board(self.board)
        self._white_move_done = True

    def play(self):
        while True:
            for i in range(len(self.board)):
                for j in range(len(self.board)):
                    if not self._black_move_done and self.board == ' * ':
                        self.black_move()
                        self._black_move_done = False
                    self.white_move()
                    self._white_move_done = False


board = [
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '],
    [' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ', ' * ']
]

go = GoGame(board)
go.display_board(sim.board)
go.play()

运行现象

*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
White to move: 0 0

 1  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 
White to move:

错误分析与修正方案

核心错误点

  1. play方法逻辑完全混乱

    • 嵌套的两层棋盘遍历循环完全多余,且每次循环都会无条件调用white_move(),导致程序一启动就无限触发白方落子。
    • 判断条件self.board == ' * '错误:self.board是二维列表,不可能等于单个字符串,完全无法触发黑方落子逻辑。
    • 标志位_black_move_done逻辑矛盾:调用black_move()后立刻设为False,等于没有起到回合控制作用。
  2. 落子无合法性验证

    • black_move()和white_move()直接修改棋盘,未检查目标位置是否为空,也未验证坐标是否在棋盘范围内,会引发索引错误或覆盖棋子的问题。
  3. 初始化调用错误

    • 最后一行go.display_board(sim.board)中的sim未定义,应改为go.display_board(go.board),或者修改display_board方法直接使用实例的self.board。

修正后的代码

class GoGame:
    _PLAYER_BLACK = " 0 "
    _PLAYER_WHITE = " 1 "
    _EMPTY = ' * '

    def __init__(self, board_size=19):
        # 简化棋盘初始化,避免手动写重复列表
        self.board = [[self._EMPTY for _ in range(board_size)] for _ in range(board_size)]

    def display_board(self):
        # 直接使用实例的board,无需传参
        for row in self.board:
            print(''.join(row))

    def _validate_move(self, i, j):
        # 验证坐标是否合法且位置为空
        board_size = len(self.board)
        if 0 <= i < board_size and 0 <= j < board_size:
            return self.board[i][j] == self._EMPTY
        return False

    def black_move(self):
        while True:
            try:
                i, j = input("Black to move: ").split()
                i, j = int(i), int(j)
                if self._validate_move(i, j):
                    self.board[i][j] = self._PLAYER_BLACK
                    self.display_board()
                    break
                else:
                    print("Invalid move: position is occupied or out of bounds. Try again.")
            except ValueError:
                print("Invalid input: enter two integers separated by space. Try again.")

    def white_move(self):
        while True:
            try:
                i, j = input("White to move: ").split()
                i, j = int(i), int(j)
                if self._validate_move(i, j):
                    self.board[i][j] = self._PLAYER_WHITE
                    self.display_board()
                    break
                else:
                    print("Invalid move: position is occupied or out of bounds. Try again.")
            except ValueError:
                print("Invalid input: enter two integers separated by space. Try again.")

    def play(self):
        # 黑白交替落子的核心逻辑
        self.display_board()
        while True:
            self.black_move()
            self.white_move()

# 启动游戏
if __name__ == "__main__":
    go = GoGame()
    go.play()

内容的提问来源于stack exchange,提问作者user19801425

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 03:55:20