From 4dc2df2513dc225399c593c8f8ca405d2b2a4eb9 Mon Sep 17 00:00:00 2001 From: Quintine <15965533+Quintine@users.noreply.github.com> Date: Wed, 28 Oct 2026 00:16:04 +1100 Subject: [PATCH] Add random faction deal and prediction draft --- README.md | 7 + app/page.tsx | 6 +- components/faction-allocation.tsx | 70 ++++++++++ components/two-player-controls.tsx | 22 ++-- docs/CURRENT_STATUS.md | 11 ++ docs/FACTION_ALLOCATION.md | 38 ++++++ docs/IMPLEMENTATION_STATUS.md | 11 ++ docs/RULE_DECISIONS.md | 10 ++ game/engine.ts | 100 ++++++++++++++ game/faction-draft.ts | 119 +++++++++++++++++ game/reference.ts | 3 +- tests/faction-allocation-controls.test.tsx | 88 +++++++++++++ tests/faction-allocation-engine.test.ts | 146 +++++++++++++++++++++ tests/faction-allocation-http.test.ts | 108 +++++++++++++++ tests/faction-draft.test.ts | 81 ++++++++++++ tests/two-player-controls.test.ts | 11 ++ 16 files changed, 819 insertions(+), 12 deletions(-) create mode 100644 components/faction-allocation.tsx create mode 100644 docs/FACTION_ALLOCATION.md create mode 100644 game/faction-draft.ts create mode 100644 tests/faction-allocation-controls.test.tsx create mode 100644 tests/faction-allocation-engine.test.ts create mode 100644 tests/faction-allocation-http.test.ts create mode 100644 tests/faction-draft.test.ts diff --git a/README.md b/README.md index 2986a9b8..06792e07 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,13 @@ npm run dev -- --host 0.0.0.0 Open `http://localhost:3000`. Create a room, share its eight-character invitation, and add human or AI seats. The host can configure Easy, Medium, Hard and Brutal AI opponents. Current calibration demonstrates a substantially weaker Easy policy; it does not yet demonstrate a consistent ordering among the upper three levels. +In the lobby, the host may deal random factions or start a prediction-card +faction draft. Draft picks proceed from the highest drawn number, and the new +factions are assigned together after every seat chooses. AI seats choose +automatically. Both methods clear human readiness; direct selection remains +available. Consensual faction swaps are not yet implemented. See +[faction allocation](docs/FACTION_ALLOCATION.md). + For the provisional two-person setup, the host enables **Two players, two factions each** in the lobby. Each person joins with one faction, then adds a second and uses **Active faction** to switch seats. Ready each faction before diff --git a/app/page.tsx b/app/page.tsx index 44d20352..fb9d3fb7 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -7,6 +7,7 @@ import { SeatConfirmation, type SeatConfirmationKind } from '@/components/seat-c import { RoomEntryConfirmation } from '@/components/room-entry-confirmation'; import { RulesetControls } from '@/components/ruleset-controls'; import { TwoPlayerControls } from '@/components/two-player-controls'; +import { FactionAllocation } from '@/components/faction-allocation'; import { randomId } from '@/lib/random-id'; import { SeatHandoverSetup, @@ -855,6 +856,7 @@ export default function Home() { {!roomUnavailable &&
Players can choose their own factions. The host can also randomly deal factions or start a prediction-card draft.
+ {isHost && <> +Random dealing changes the current choices immediately. Draft choices replace the current factions only after everyone has picked. Either option clears human readiness.
+ {game.players.length < 2 &&At least two faction seats are needed to allocate factions.
} +Highest prediction card chooses first. Existing factions remain in place until every seat has picked; other lobby changes wait for the draft to finish.
+Choose one of the remaining factions. Each faction can be chosen only once.
+Waiting for {seatName(next.player)} to choose a faction{game.players.find((player) => player.id === next.player)?.bot ? '; the AI will choose automatically' : ''}.
} + {isHost && } +