| 1 | | |
| 2 | 1 | class ConnectGame: |
| 3 | 2 | def __init__(self, board): |
| 4 | | pass |
| 3 | # Edge Case: Empty board |
| 4 | if not board: |
| 5 | self.board = [] |
| 6 | self.height = 0 |
| 7 | self.width = 0 |
| 8 | return |
| 9 | |
| 10 | # Parse the board, removing spaces and handling jagged arrays |
| 11 | self.board = [] |
| 12 | for row in board.split('\n'): |
| 13 | # Edge Case: Rows with only whitespace |
| 14 | cleaned_row = ''.join(row.split()) |
| 15 | if cleaned_row: # Only add non-empty rows |
| 16 | self.board.append(list(cleaned_row)) |
| 17 | |
| 18 | self.height = len(self.board) |
| 19 | # Edge Case: Board with no valid rows |
| 20 | self.width = len(self.board[0]) if self.height > 0 else 0 |
| 21 | |
| 22 | # Edge Case: Jagged array - pad shorter rows with empty spaces |
| 23 | for i in range(self.height): |
| 24 | while len(self.board[i]) < self.width: |
| 25 | self.board[i].append(' ') |
| 5 | 26 | |
| 6 | 27 | def get_winner(self): |
| 7 | | pass |
| 28 | # Edge Case: Empty board or board with no columns |
| 29 | if self.height == 0 or self.width == 0: |
| 30 | return "" |
| 31 | |
| 32 | # Check for O winner (top to bottom) |
| 33 | visited_o = set() |
| 34 | for j in range(self.width): |
| 35 | if self.board[0][j] == 'O' and (0, j) not in visited_o: |
| 36 | if self._dfs(0, j, 'O', visited_o, True): |
| 37 | return 'O' |
| 38 | |
| 39 | # Check for X winner (left to right) |
| 40 | visited_x = set() |
| 41 | for i in range(self.height): |
| 42 | if self.board[i][0] == 'X' and (i, 0) not in visited_x: |
| 43 | if self._dfs(i, 0, 'X', visited_x, False): |
| 44 | return 'X' |
| 45 | |
| 46 | return "" |
| 47 | |
| 48 | def _dfs(self, row, col, player, visited, is_o_player): |
| 49 | # Check bounds |
| 50 | if row < 0 or row >= self.height or col < 0 or col >= self.width: |
| 51 | return False |
| 52 | |
| 53 | # Check if cell is not player's or already visited |
| 54 | if self.board[row][col] != player or (row, col) in visited: |
| 55 | return False |
| 56 | |
| 57 | # Check win condition |
| 58 | if is_o_player and row == self.height - 1: # O player reached bottom |
| 59 | return True |
| 60 | if not is_o_player and col == self.width - 1: # X player reached right |
| 61 | return True |
| 62 | |
| 63 | # Mark as visited |
| 64 | visited.add((row, col)) |
| 65 | |
| 66 | # Explore neighbors (hexagonal connectivity) |
| 67 | directions = [ |
| 68 | (-1, 0), (1, 0), # Up, Down |
| 69 | (0, -1), (0, 1), # Left, Right |
| 70 | (-1, 1), (1, -1) # Diagonals |
| 71 | ] |
| 72 | |
| 73 | for dr, dc in directions: |
| 74 | new_row, new_col = row + dr, col + dc |
| 75 | if self._dfs(new_row, new_col, player, visited, is_o_player): |
| 76 | return True |
| 77 | |
| 78 | return False |
| 79 | |
| 80 | # Handled Edge Cases: Empty board, board with no valid rows, jagged arrays, rows with only whitespace |