solver support for 3x4/4x3 boards

main
Inga 🏳‍🌈 2 days ago
parent 4d13d2b1a4
commit d6f2d6e407
  1. 4
      src/shared/gameplay/solver.ts
  2. 17
      src/shared/integration-tests/tictactoe-all.test.ts
  3. 13
      src/shared/integration-tests/tictactoe-three.test.ts

@ -60,7 +60,9 @@ export const getPreferredNextOutcome = (
}; };
export const computeAllSolutions = (rows: number, columns: number, rules: GameRules) => { export const computeAllSolutions = (rows: number, columns: number, rules: GameRules) => {
if (rows * columns > 9) { if (rows * columns > 12) {
// Even for 3x5 board computing all solutions takes 20 seconds on my computer.
// There are probably many opportunities for optimization, but they're outside of the scope for now.
throw new Error("Board is too large, solving requires too many computational resources"); throw new Error("Board is too large, solving requires too many computational resources");
} }

@ -0,0 +1,17 @@
import t from "tap";
import { tictactoeThreeRules } from "../game-variants/tictactoe/tictactoe-three-rules.ts";
import { checkSolutionsIncomplete } from "./test-helpers.ts";
const rules = tictactoeThreeRules;
void t.test("computeAllSolutions", async (t) => {
// These numbers are not checked, but at least these tests will help us catch possible changes
void t.test("number of combinations for 3x4 board", async (t) => {
checkSolutionsIncomplete(t, rules, 3, 4, 111973, {});
});
void t.test("number of combinations for 4x3 board", async (t) => {
checkSolutionsIncomplete(t, rules, 4, 3, 111973, {});
});
});

@ -4,12 +4,12 @@ import { FinalOutcome, Player } from "../datatypes/types.ts";
import { createOpponent } from "../gameplay/opponent.ts"; import { createOpponent } from "../gameplay/opponent.ts";
import { computeAllSolutions } from "../gameplay/solver.ts"; import { computeAllSolutions } from "../gameplay/solver.ts";
import { tictactoeThreeRules } from "../game-variants/tictactoe/tictactoe-three-rules.ts"; import { tictactoeThreeRules } from "../game-variants/tictactoe/tictactoe-three-rules.ts";
import { checkNextMove, checkSolutionsComplete } from "./test-helpers.ts"; import { checkNextMove, checkSolutionsComplete, checkSolutionsIncomplete } from "./test-helpers.ts";
const rules = tictactoeThreeRules; const rules = tictactoeThreeRules;
void t.test("computeAllSolutions", async (t) => { void t.test("computeAllSolutions", async (t) => {
// smallest possible board where X can win void t.test("1x5, smallest possible board where X can win", async (t) => {
checkSolutionsComplete(t, rules, 1, 5, { checkSolutionsComplete(t, rules, 1, 5, {
_____: { finalOutcome: FinalOutcome.Draw, movesLeft: 5 }, _____: { finalOutcome: FinalOutcome.Draw, movesLeft: 5 },
@ -112,6 +112,15 @@ void t.test("computeAllSolutions", async (t) => {
OXOXX: { finalOutcome: FinalOutcome.Draw, movesLeft: 0 }, OXOXX: { finalOutcome: FinalOutcome.Draw, movesLeft: 0 },
OOXXX: { finalOutcome: FinalOutcome.WinX, movesLeft: 0 }, OOXXX: { finalOutcome: FinalOutcome.WinX, movesLeft: 0 },
}); });
});
void t.test("number of combinations for 3x4 board", async (t) => {
checkSolutionsIncomplete(t, rules, 3, 4, 111973, {});
});
void t.test("number of combinations for 4x3 board", async (t) => {
checkSolutionsIncomplete(t, rules, 4, 3, 111973, {});
});
}); });
void t.test("createOpponent", async (t) => { void t.test("createOpponent", async (t) => {

Loading…
Cancel
Save