import { GomokuGame } from './game-instance'; import { expect, test, describe } from 'bun:test'; describe('GameInstance', () => { test('should initialize with correct default state', () => { const game = new GomokuGame(); expect(game.id).toBeDefined(); expect(game.board.length).toBe(15); expect(game.board[0].length).toBe(15); expect(game.currentPlayer).toBeNull(); expect(game.status).toBe('waiting'); expect(game.winner).toBeNull(); expect(game.players).toEqual({}); }); test('should add players correctly', () => { const game = new GomokuGame(); const player1 = 'player1-uuid'; const player2 = 'player2-uuid'; // First player joins as black const joined1 = game.addPlayer(player1); expect(joined1).toBe(true); // Second player joins as white const joined2 = game.addPlayer(player2); expect(joined2).toBe(true); // Game should now be in playing state expect(game.status).toBe('playing'); expect(game.currentPlayer).toBe('black'); expect(game.players.black).toBe(player1); expect(game.players.white).toBe(player2); }); test('should prevent more than two players from joining', () => { const game = new GomokuGame(); const player1 = 'player1-uuid'; const player2 = 'player2-uuid'; const player3 = 'player3-uuid'; game.addPlayer(player1); game.addPlayer(player2); // Third player tries to join (should fail) const joined = game.addPlayer(player3); expect(joined).toBe(false); // Players object should remain unchanged, only two players should be present expect(game.players.black).toBe(player1); expect(game.players.white).toBe(player2); expect(Object.values(game.players).length).toBe(2); }); test('should validate moves correctly', () => { const game = new GomokuGame(); const player1 = 'player1-uuid'; const player2 = 'player2-uuid'; game.addPlayer(player1); game.addPlayer(player2); // Player black makes first move const move1 = game.makeMove(player1, 7, 7); expect(move1.success).toBe(true); // Same player tries to move again (should fail) const move2 = game.makeMove(player1, 7, 8); expect(move2.success).toBe(false); // White player makes a move const move3 = game.makeMove(player2, 7, 8); expect(move3.success).toBe(true); // Try to place on occupied cell (should fail) const move4 = game.makeMove(player2, 7, 7); expect(move4.success).toBe(false); // Try to place out of bounds (should fail) const move5 = game.makeMove(player2, 15, 15); expect(move5.success).toBe(false); }); test('should detect win conditions', () => { const game = new GomokuGame(); const player1 = 'player1-uuid'; const player2 = 'player2-uuid'; game.addPlayer(player1); game.addPlayer(player2); // Create a horizontal win for black for (let col = 0; col < 5; col++) { game.makeMove(player1, 7, col); // Switch to other player for next move if (col < 4) game.makeMove(player2, 8, col); } expect(game.winner).toBe('black'); expect(game.status).toBe('finished'); }); test('should detect draw condition', () => { const game = new GomokuGame(); const player1 = 'player1-uuid'; const player2 = 'player2-uuid'; game.addPlayer(player1); game.addPlayer(player2); // Create a pattern that doesn't result in a win but fills the board // We'll use a simple alternating pattern for (let row = 0; row < 15; row++) { for (let col = 0; col < 15; col++) { const currentPlayer = game.currentPlayer!; const playerId = game.players[currentPlayer]!; // Make move const result = game.makeMove(playerId, row, col); // If we can't make a move, it means someone won already if (!result.success) { expect(game.winner).not.toBeNull(); return; } } } expect(game.winner).toBe('draw'); expect(game.status).toBe('finished'); }); });