Finished
44//
55
66export class Board {
7 constructor() {
8 throw new Error('Remove this line and implement the function');
7 constructor(board) {
8 // Edge Case: Handle empty or null board input
9 if (!board || board.length === 0) {
10 this.board = [];
11 this.height = 0;
12 this.width = 0;
13 return;
14 }
15
16 // Parse the board into a 2D array
17 this.board = board.map(row => row.split('').filter(char => char !== ' '));
18 this.height = this.board.length;
19 this.width = this.height > 0 ? this.board[0].length : 0;
920 }
1021
1122 winner() {
12 throw new Error('Remove this line and implement the function');
23 // Edge Case: Handle empty board
24 if (this.height === 0 || this.width === 0) {
25 return '';
26 }
27
28 // Check if O (top to bottom) has won
29 if (this.checkWinner('O', true)) {
30 return 'O';
31 }
32
33 // Check if X (left to right) has won
34 if (this.checkWinner('X', false)) {
35 return 'X';
36 }
37
38 return '';
39 }
40
41 checkWinner(player, topToBottom) {
42 // Edge Case: Handle boards with invalid dimensions
43 if (this.height === 0 || this.width === 0) {
44 return false;
45 }
46
47 const visited = Array(this.height).fill().map(() => Array(this.width).fill(false));
48 const queue = [];
49
50 if (topToBottom) {
51 // For O: check top row for starting positions
52 for (let col = 0; col < this.width; col++) {
53 if (this.board[0][col] === player) {
54 queue.push([0, col]);
55 visited[0][col] = true;
56 }
57 }
58 } else {
59 // For X: check left column for starting positions
60 for (let row = 0; row < this.height; row++) {
61 if (this.board[row][0] === player) {
62 queue.push([row, 0]);
63 visited[row][0] = true;
64 }
65 }
66 }
67
68 // Edge Case: No starting positions for the player
69 if (queue.length === 0) {
70 return false;
71 }
72
73 // BFS to find a path
74 while (queue.length > 0) {
75 const [row, col] = queue.shift();
76
77 // Check if we've reached the target side
78 if (topToBottom) {
79 // For O: check if we reached bottom row
80 if (row === this.height - 1) {
81 return true;
82 }
83 } else {
84 // For X: check if we reached right column
85 if (col === this.width - 1) {
86 return true;
87 }
88 }
89
90 // Check all 6 hexagonal neighbors
91 const directions = [
92 [-1, 0], [-1, 1], // top neighbors
93 [0, -1], [0, 1], // side neighbors
94 [1, -1], [1, 0] // bottom neighbors
95 ];
96
97 for (const [dr, dc] of directions) {
98 const newRow = row + dr;
99 const newCol = col + dc;
100
101 // Edge Case: Check bounds
102 if (newRow >= 0 && newRow < this.height &&
103 newCol >= 0 && newCol < this.width &&
104 !visited[newRow][newCol] &&
105 this.board[newRow][newCol] === player) {
106
107 visited[newRow][newCol] = true;
108 queue.push([newRow, newCol]);
109 }
110 }
111 }
112
113 return false;
13114 }
14115}
116
117// Handled Edge Cases: empty board, null board, boards with invalid dimensions, no starting positions for a player, out of bounds access
Test NameStatus
an empty board has no winner
Pass
X can win on a 1x1 board
Pass
O can win on a 1x1 board
Pass
only edges does not make a winner
Pass
illegal diagonal does not make a winner
Pass
nobody wins crossing adjacent angles
Pass
X wins crossing from left to right
Pass
O wins crossing from top to bottom
Pass
X wins using a convoluted path
Pass
X wins using a spiral path
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.