Skip to content

Created move-maker.js and jest test #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
69 changes: 65 additions & 4 deletions __tests__/board-printer.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,67 @@
import { checkIfNoMovesLeft } from "../board-printer";
import { printBoard, checkIfNoMovesLeft } from "../board-printer"

test("checkIfNoMovesLeft should return true if there are no moves left", () => {
const board = [];
expect(checkIfNoMovesLeft(board)).toBe(true);
describe("printBoard", () => {
test("should print the formatted tic-tac-toe board correctly", () => {
const board = [
["X", "_", "_"],
["_", "X", "_"],
["O", "O", "X"],
];
const expectedOutput =
" X | | \n=================\n | X | \n=================\n O | O | X \n";

expect(printBoard(board)).toBe(expectedOutput);
});

test("should return an empty board when provided with an empty board", () => {
const board = [];
const expectedOutput =
" | | \n============= \n | | \n============= \n | | ";

expect(printBoard(board)).toBe(expectedOutput);
});

test("should handle a partially filled board", () => {
const board = [
["X", "_", "O"],
["_", "_", "_"],
["X", "O", "X"],
];
const expectedOutput =
" X | | O \n=================\n | | \n=================\n X | O | X \n";

expect(printBoard(board)).toBe(expectedOutput);
});
});

describe("checkIfNoMovesLeft", () => {
test("should return true if no moves are left", () => {
const board = [
["X", "O", "X"],
["O", "X", "O"],
["X", "O", "X"],
];
expect(checkIfNoMovesLeft(board)).toBe(true);
});

test("should return false if there are moves left", () => {
const board = [
["X", "_", "X"],
["O", "X", "O"],
["X", "O", "_"],
];
expect(checkIfNoMovesLeft(board)).toBe(false);
});

test("should throw an error if the board is not an array of arrays", () => {
const invalidBoard1 = "invalid format";
const invalidBoard2 = ["X", "O", "_"]; // Not an array of arrays

expect(() => checkIfNoMovesLeft(invalidBoard1)).toThrow(
"Invalid board format. Expected an array of arrays."
);
expect(() => checkIfNoMovesLeft(invalidBoard2)).toThrow(
"Invalid board format. Expected an array of arrays."
);
});
});
47 changes: 47 additions & 0 deletions __tests__/move-maker.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { makeMove } from "../move-maker";

let board;

beforeEach(() => {
// Reset the board before each test
board = [
['_', '_', '_'],
['_', '_', '_'],
['_', '_', '_']
];
});

test('allows a valid move and updates the board', () => {
const result = makeMove(board, '1,1', 'X');
expect(result).toBe(true);
expect(board[0][0]).toBe('X'); // Zero-based index for row and column
});

test('rejects a move outside the board boundaries', () => {
expect(makeMove(board, '4,1', 'X')).toBe(false); // Row out of bounds
expect(makeMove(board, '0,1', 'X')).toBe(false); // Row out of bounds
expect(makeMove(board, '1,4', 'X')).toBe(false); // Column out of bounds
expect(makeMove(board, '1,0', 'X')).toBe(false); // Column out of bounds
});

test('rejects a move in an occupied space', () => {
board[0][0] = 'X'; // Pre-occupy a cell
const result = makeMove(board, '1,1', 'O'); // Try to overwrite
expect(result).toBe(false);
expect(board[0][0]).toBe('X'); // Ensure the board didn't change
});

test('rejects invalid move formats', () => {
expect(makeMove(board, 'invalid', 'X')).toBe(false); // Non-numeric input
expect(makeMove(board, '1-1', 'X')).toBe(false); // Wrong delimiter
expect(makeMove(board, '1,', 'X')).toBe(false); // Missing column
expect(makeMove(board, ',1', 'X')).toBe(false); // Missing row
});

test('allows moves on the edges of the board', () => {
expect(makeMove(board, '1,3', 'O')).toBe(true); // Top-right corner
expect(board[0][2]).toBe('O'); // Check board update

expect(makeMove(board, '3,1', 'X')).toBe(true); // Bottom-left corner
expect(board[2][0]).toBe('X'); // Check board update
});
64 changes: 64 additions & 0 deletions __tests__/status-checker.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

import { isGameOver } from "../status-checker";
let board;
beforeEach(() => {
board = [
['_', '_', '_'],
['_', '_', '_'],
['_', '_', '_']
];
});


test('Player X wins on a row', () => {
board = [
['X', 'X', 'X'],
['_', '_', '_'],
['O', 'O', '_']
];
expect(isGameOver(board)).toBe(true); // X has won the game!
});
test('Player X wins on a row', () => {
board = [
['X', 'X', 'X'],
['_', '_', '_'],
['O', 'O', '_']
];
expect(isGameOver(board)).toBe(true); // X has won the game!
});

test('Game is a draw!', () => {
board = [
['O', '_', '_'],
['X', '_', 'O'],
['X', '_', 'O']
];
expect(isGameOver(board)).toBe(false); // Game is a draw!
});

test('Player X wins on a diagonal', () => {
board = [
['X', '_', 'O'],
['_', 'X', '_'],
['O', '_', 'X']
];
expect(isGameOver(board)).toBe(true); // X has won the game!
});

test('Tie game', () => {
board = [
['X', 'O', 'X'],
['O', 'X', 'O'],
['O', 'X', 'X']
];
expect(isGameOver(board)).toBe(true); // Game Over - It's a tie!
});

test('Game is not over yet', () => {
board = [
['X', '_', 'O'],
['_', '_', '_'],
['O', '_', '_']
];
expect(isGameOver(board)).toBe(false); // Game is still ongoing
});
38 changes: 38 additions & 0 deletions board-printer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,50 @@
Test your function by calling it with an example tic-tac-toe board.
*/
export function printBoard(board) {
if (Array.isArray(board) && board.length === 0) {
return ` | |
=============
| |
=============
| | `;
}

let result = "";

for (let i = 0; i < board.length; i++) {
let row = board[i].map((cell) => (cell === "_" ? " " : cell)).join(" | ");
result += ` ${row} \n`;
if (i < board.length - 1) {
result += "=================\n";
}
}

return result;
}

console.log(
printBoard([
["X", "_", "_"],
["_", "X", "_"],
["O", "O", "X"],
])
);


/*
Given a tic-tac-toe board (an array of arrays),
- return true if there are no moves left to make (there are no more '_' values)
- return false if there are still moves that can be made
*/
export function checkIfNoMovesLeft(board) {
if (!Array.isArray(board) || board.some((row) => !Array.isArray(row))) {
throw new Error("Invalid board format. Expected an array of arrays.");
}

for (let i = 0; i < board.length; i++) {
if (board[i].includes("_")) {
return false;
}
}
return true;
}
24 changes: 22 additions & 2 deletions move-maker.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,18 @@
];
*/
function validateMove(move, board) {
// Implement this at the end if you have time, otherwise you can help your teammates!
const [row, col] = move.split(',').map(Number);
if (isNaN(row) || isNaN(col) || row < 1 || row > 3 || col < 1 || col > 3) {
console.log('Try again...');
return false;
}
const rowIndex = row - 1;
const colIndex = col - 1;

if (board[rowIndex][colIndex] !== '_') {
console.log('Try again...');
return false;
}
return true;
}

Expand All @@ -32,5 +43,14 @@ function validateMove(move, board) {
- Return true
*/
export function makeMove(board, move, player) {
return false;
if (!validateMove(move, board)) {
return false;
}
const [row, col] = move.split(',').map(Number);
const rowIndex = row - 1;
const colIndex = col - 1;

board[rowIndex][colIndex] = player;

return true;
}
Loading