Finished
44//
55
66/**
7 * @param {string[]} board
8 * @returns {string}
7 * Determines the state of a Tic-Tac-Toe game based on the given board.
8 *
9 * @param {string[]} board - An array of 3 strings, each representing a row of the 3x3 board.
10 * Each character is either 'X', 'O', or ' ' (empty space).
11 * @returns {string} - Returns one of: 'ongoing', 'win', 'draw'
12 * @throws {Error} - Throws an error for invalid board states with specific messages:
13 * - 'Wrong turn order: O started' if O plays first
14 * - 'Wrong turn order: X went twice' if X plays twice in a row
15 * - 'Impossible board: game should have ended after the game was won' if play continues after a win
916 */
1017export const gamestate = (board) => {
11 throw new Error('Remove this line and implement the function');
12};
18 // Validate board structure
19 if (!Array.isArray(board) || board.length !== 3) {
20 throw new Error('Invalid board: must be an array of 3 strings');
21 }
22
23 for (let i = 0; i < 3; i++) {
24 if (typeof board[i] !== 'string' || board[i].length !== 3) {
25 throw new Error('Invalid board: each row must be a string of length 3');
26 }
27 for (let j = 0; j < 3; j++) {
28 const char = board[i][j];
29 if (char !== 'X' && char !== 'O' && char !== ' ') {
30 throw new Error('Invalid board: contains invalid characters');
31 }
32 }
33 }
34
35 // Count X's and O's
36 let xCount = 0;
37 let oCount = 0;
38
39 for (let i = 0; i < 3; i++) {
40 for (let j = 0; j < 3; j++) {
41 if (board[i][j] === 'X') xCount++;
42 if (board[i][j] === 'O') oCount++;
43 }
44 }
45
46 // Edge Case: Invalid number of moves (X must be equal to or one more than O)
47 if (xCount < oCount || xCount > oCount + 1) {
48 if (oCount > xCount) {
49 throw new Error('Wrong turn order: O started');
50 } else {
51 throw new Error('Wrong turn order: X went twice');
52 }
53 }
54
55 // Check for wins
56 const winConditions = [
57 // Rows
58 [[0,0], [0,1], [0,2]],
59 [[1,0], [1,1], [1,2]],
60 [[2,0], [2,1], [2,2]],
61 // Columns
62 [[0,0], [1,0], [2,0]],
63 [[0,1], [1,1], [2,1]],
64 [[0,2], [1,2], [2,2]],
65 // Diagonals
66 [[0,0], [1,1], [2,2]],
67 [[0,2], [1,1], [2,0]]
68 ];
69
70 let xWins = false;
71 let oWins = false;
72
73 for (const condition of winConditions) {
74 const [a, b, c] = condition;
75 const valA = board[a[0]][a[1]];
76 const valB = board[b[0]][b[1]];
77 const valC = board[c[0]][c[1]];
78
79 if (valA !== ' ' && valA === valB && valB === valC) {
80 if (valA === 'X') xWins = true;
81 if (valA === 'O') oWins = true;
82 }
83 }
84
85 // Edge Case: Both players win (impossible in valid games)
86 if (xWins && oWins) {
87 throw new Error('Impossible board: game should have ended after the game was won');
88 }
89
90 // Edge Case: Game continued after a win
91 if (xWins && oCount >= xCount) {
92 throw new Error('Impossible board: game should have ended after the game was won');
93 }
94
95 // Edge Case: Game continued after a win
96 if (oWins && xCount > oCount) {
97 throw new Error('Impossible board: game should have ended after the game was won');
98 }
99
100 // Determine game state
101 if (xWins || oWins) {
102 return 'win';
103 }
104
105 // Edge Case: Board is full with no winner (draw)
106 if (xCount + oCount === 9) {
107 return 'draw';
108 }
109
110 // Edge Case: Game is not finished yet (ongoing)
111 return 'ongoing';
112
113 // Handled Edge Cases:
114 // - Invalid board structure
115 // - Invalid characters on board
116 // - Wrong turn order (O started)
117 // - Wrong turn order (X went twice)
118 // - Both players winning
119 // - Game continued after a win
120 // - Board is full with no winner
121 // - Game is not finished yet
122};
Test NameStatus
Finished game where X won via left column victory
Pass
Finished game where X won via middle column victory
Pass
Finished game where X won via right column victory
Pass
Finished game where O won via left column victory
Pass
Finished game where O won via middle column victory
Pass
Finished game where O won via right column victory
Pass
Finished game where X won via top row victory
Pass
Finished game where X won via middle row victory
Pass
Finished game where X won via bottom row victory
Pass
Finished game where O won via top row victory
Pass
Finished game where O won via middle row victory
Pass
Finished game where O won via bottom row victory
Pass
Finished game where X won via falling diagonal victory
Pass
Finished game where X won via rising diagonal victory
Pass
Finished game where O won via falling diagonal victory
Pass
Finished game where O won via rising diagonal victory
Pass
Finished game where X won via a row and a column victory
Pass
Finished game where X won via two diagonal victories
Pass
Draw
Pass
Another draw
Pass
Ongoing game: one move in
Pass
Ongoing game: two moves in
Pass
Ongoing game: five moves in
Pass
Invalid board: X went twice
Pass
Invalid board: O started
Pass
Invalid board: X won and O kept playing
Pass
Invalid board: players kept playing after a win
Pass

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