Feature: Map size configuration
This commit is contained in:
@@ -1222,9 +1222,246 @@ describe('Multiple AI Bots Turn Chain', () => {
|
||||
// Check the pattern repeats correctly
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const expectedPlayer = (i % 4) + 1;
|
||||
assert.strictEqual(gameUI.aiTurnsCompleted[i], expectedPlayer,
|
||||
assert.strictEqual(gameUI.aiTurnsCompleted[i], expectedPlayer,
|
||||
`Turn ${i + 1} should be player ${expectedPlayer}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('AIBot - Different Map Sizes', () => {
|
||||
describe('AI works on 10x10 map', () => {
|
||||
it('should find valid moves on 10x10 map', () => {
|
||||
const map = new HexMap(10);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
// Clear map
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 2, 2, 1, 8);
|
||||
setupPlayerCell(map, 2, 1, 2, 4);
|
||||
|
||||
const playerCells = map.getPlayerCells(1);
|
||||
const moves = bot.findPossibleMoves(playerCells);
|
||||
|
||||
assert.ok(moves.length > 0, 'Should find moves on 10x10 map');
|
||||
});
|
||||
|
||||
it('should respect boundaries on 10x10 map', () => {
|
||||
const map = new HexMap(10);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 0, 0, 1, 8);
|
||||
map.getCell(0, 1).type = CELL_TYPES.EMPTY;
|
||||
map.getCell(1, 0).type = CELL_TYPES.EMPTY;
|
||||
|
||||
const playerCells = map.getPlayerCells(1);
|
||||
const moves = bot.findPossibleMoves(playerCells);
|
||||
|
||||
moves.forEach(move => {
|
||||
assert.ok(move.to.q >= 0 && move.to.q < 10, 'Target q should be in bounds');
|
||||
assert.ok(move.to.r >= 0 && move.to.r < 10, 'Target r should be in bounds');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('AI works on 15x15 map', () => {
|
||||
it('should find valid moves on 15x15 map', () => {
|
||||
const map = new HexMap(15);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 5, 5, 1, 8);
|
||||
setupPlayerCell(map, 5, 4, 2, 4);
|
||||
|
||||
const playerCells = map.getPlayerCells(1);
|
||||
const moves = bot.findPossibleMoves(playerCells);
|
||||
|
||||
assert.ok(moves.length > 0, 'Should find moves on 15x15 map');
|
||||
});
|
||||
|
||||
it('should respect boundaries on 15x15 map', () => {
|
||||
const map = new HexMap(15);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 14, 14, 1, 8);
|
||||
map.getCell(13, 14).type = CELL_TYPES.EMPTY;
|
||||
map.getCell(14, 13).type = CELL_TYPES.EMPTY;
|
||||
|
||||
const playerCells = map.getPlayerCells(1);
|
||||
const moves = bot.findPossibleMoves(playerCells);
|
||||
|
||||
moves.forEach(move => {
|
||||
assert.ok(move.to.q >= 0 && move.to.q < 15, 'Target q should be in bounds');
|
||||
assert.ok(move.to.r >= 0 && move.to.r < 15, 'Target r should be in bounds');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('AI works on 20x20 map', () => {
|
||||
it('should find valid moves on 20x20 map', () => {
|
||||
const map = new HexMap(20);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 10, 10, 1, 8);
|
||||
setupPlayerCell(map, 10, 9, 2, 4);
|
||||
|
||||
const playerCells = map.getPlayerCells(1);
|
||||
const moves = bot.findPossibleMoves(playerCells);
|
||||
|
||||
assert.ok(moves.length > 0, 'Should find moves on 20x20 map');
|
||||
});
|
||||
|
||||
it('should respect boundaries on 20x20 map', () => {
|
||||
const map = new HexMap(20);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 19, 19, 1, 8);
|
||||
map.getCell(18, 19).type = CELL_TYPES.EMPTY;
|
||||
map.getCell(19, 18).type = CELL_TYPES.EMPTY;
|
||||
|
||||
const playerCells = map.getPlayerCells(1);
|
||||
const moves = bot.findPossibleMoves(playerCells);
|
||||
|
||||
moves.forEach(move => {
|
||||
assert.ok(move.to.q >= 0 && move.to.q < 20, 'Target q should be in bounds');
|
||||
assert.ok(move.to.r >= 0 && move.to.r < 20, 'Target r should be in bounds');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('AI works on 25x25 map', () => {
|
||||
it('should find valid moves on 25x25 map', () => {
|
||||
const map = new HexMap(25);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 12, 12, 1, 8);
|
||||
setupPlayerCell(map, 12, 11, 2, 4);
|
||||
|
||||
const playerCells = map.getPlayerCells(1);
|
||||
const moves = bot.findPossibleMoves(playerCells);
|
||||
|
||||
assert.ok(moves.length > 0, 'Should find moves on 25x25 map');
|
||||
});
|
||||
|
||||
it('should respect boundaries on 25x25 map', () => {
|
||||
const map = new HexMap(25);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 24, 24, 1, 8);
|
||||
map.getCell(23, 24).type = CELL_TYPES.EMPTY;
|
||||
map.getCell(24, 23).type = CELL_TYPES.EMPTY;
|
||||
|
||||
const playerCells = map.getPlayerCells(1);
|
||||
const moves = bot.findPossibleMoves(playerCells);
|
||||
|
||||
moves.forEach(move => {
|
||||
assert.ok(move.to.q >= 0 && move.to.q < 25, 'Target q should be in bounds');
|
||||
assert.ok(move.to.r >= 0 && move.to.r < 25, 'Target r should be in bounds');
|
||||
});
|
||||
});
|
||||
|
||||
it('should calculate move priorities correctly on large map', () => {
|
||||
const map = new HexMap(25);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 12, 12, 1, 10);
|
||||
// Weak enemy
|
||||
setupPlayerCell(map, 12, 11, 2, 3);
|
||||
// Strong enemy
|
||||
setupPlayerCell(map, 11, 12, 2, 9);
|
||||
// Empty cell
|
||||
map.getCell(13, 12).type = CELL_TYPES.EMPTY;
|
||||
|
||||
const playerCells = map.getPlayerCells(1);
|
||||
const moves = bot.findPossibleMoves(playerCells);
|
||||
moves.sort((a, b) => bot.movePriority(b) - bot.movePriority(a));
|
||||
|
||||
// Best move should be attack on weak enemy
|
||||
assert.strictEqual(moves[0].type, 'attack');
|
||||
assert.strictEqual(moves[0].defenseStrength, 3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('AI playTurn works on different map sizes', () => {
|
||||
it('should complete turn on 10x10 map', async () => {
|
||||
const map = new HexMap(10);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 2, 2, 1, 8);
|
||||
setupPlayerCell(map, 2, 1, 2, 2);
|
||||
|
||||
bot.thinkingTime = 0;
|
||||
|
||||
await bot.playTurn();
|
||||
|
||||
assert.strictEqual(gameUI.turnEnded, true);
|
||||
});
|
||||
|
||||
it('should complete turn on 25x25 map', async () => {
|
||||
const map = new HexMap(25);
|
||||
const gameUI = new MockGameUI();
|
||||
const bot = new AIBot(1, map, gameUI);
|
||||
|
||||
map.cells.forEach(cell => {
|
||||
cell.type = CELL_TYPES.EMPTY;
|
||||
});
|
||||
|
||||
setupPlayerCell(map, 12, 12, 1, 8);
|
||||
setupPlayerCell(map, 12, 11, 2, 2);
|
||||
|
||||
bot.thinkingTime = 0;
|
||||
|
||||
await bot.playTurn();
|
||||
|
||||
assert.strictEqual(gameUI.turnEnded, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user