Skip to content

[BUG] TicTacToe check_fork_opportunities() corrupts board state #4

@galpt

Description

@galpt

Bug Description

In cog/games.py#L302-L320, the check_fork_opportunities() function corrupts the board state when it finds a fork opportunity.

def check_fork_opportunities(self):
    fork_candidates = []
    for idx in empty:
        self.board[idx] = bot_mark  # <-- corrupts board
        win_count = 0
        for i in range(self.size * self.size):
            if self.board[i] == bot_mark:
                continue
            self.board[i] = bot_mark  # <-- corrupts board
            if self.check_winner(bot_mark):
                win_count += 1
            self.board[i] = " "  # Resets but...
        if win_count >= 2:
            fork_candidates.append((win_count, idx))
        self.board[idx] = " "  # Only resets idx, not line 310 corruption
    if fork_candidates:
        return max(fork_candidates)[1]  # Returns early without full cleanup!
    return None

Impact: When the function returns early (when fork_candidates is non-empty), the board is left with extra bot marks. Subsequent strategy checks (check_block_fork, get_corner_strategy, etc.) operate on corrupted board state, leading to incorrect bot decisions.


How to Fix

Track ALL modified cells and restore them:

def check_fork_opportunities(self):
    fork_candidates = []
    for idx in empty:
        self.board[idx] = bot_mark
        win_count = 0
        modified = [idx]  # Track all modified cells
        for i in range(self.size * self.size):
            if self.board[i] == bot_mark:
                continue
            self.board[i] = bot_mark
            modified.append(i)
            if self.check_winner(bot_mark):
                win_count += 1
            self.board[i] = " "
        if win_count >= 2:
            fork_candidates.append((win_count, idx))
        for m in modified:  # Restore ALL modified cells
            self.board[m] = " "
    if fork_candidates:
        return max(fork_candidates)[1]
    return None

Severity

Critical - Causes incorrect bot AI decisions after fork detection

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions