Commit graph

35 commits

Author SHA1 Message Date
e648ab6d29 Add plugin config.json for Cardinal deployment 2026-02-23 23:29:05 +00:00
bdf14a7c58 Add integration screenshots and screenshot tooling
Screenshots generated via Playwright showing key game states:
- 01_midgame_properties_owned: Properties with colored owner indicators
- 02_houses_built: Houses/hotels rendered on properties
- 03_after_trade: Board state after a property trade
- 04_baltic_mortgaged: Mortgaged property display
- 05_bob_bankrupt: Bankrupt player with skull/opacity/strikethrough
- 06_game_over: Game over with winner confetti

Also includes earlier QA screenshots:
- single_player_joined: Lobby with one player registered
- player_bankrupt_game_over: Bankrupt endgame state

Tools: screenshot_states.py (synthetic states) and
screenshot_integration.py (integration test scenarios)
2026-02-21 20:01:57 +00:00
66412a5c67 Add comprehensive integration test exercising all fixed bugs
test_integration_bugs.py: single-game flow covering:
- Bug #1: Trade property transfer (Reading RR bob→charlie)
- Bug #5: Resign-to-bank clears properties (bob's B&O unowned)
- Bug #6: Resign-to-player transfers properties (alice's Baltic→charlie)
- Bug #7: Property owner renumbering after resign
- Bug #9: phase field always emitted (playing/over)
- Bug #10: Trade/resign log timestamps
- Bug #11: House counts from rent lines
- House sub-parser: buy 9 houses on lightblue
- Holdings display resync
- GOJF card command
- Mortgage/unmortgage tracking
- State JSON structure validation

All 1551 checkpoints + 100 unit tests passing.
2026-02-21 19:52:13 +00:00
ea99d36657 Add house buying/selling sub-parser with full integration
New file: house_parser.py — self-contained state machine for the interactive
house buy/sell dialog. Parses:
- Property prompts ('PropName (N): ') to capture current house count
- Player responses (how many to buy/sell)
- Auto-skipped prompts (hotel during buy, 0 houses during sell)
- Error retries ('spread too wide', 'too many')
- Confirmation ('Is that ok?' → y/n)

Returns a result dict with {action, changes: {sq_id: new_count}, cost}
when the dialog completes.

Integration: monop_parser feeds every line (bot + player) to HouseParser.
On result, applies house count changes to property_houses.

Tests:
- test_house_parser.py (18 tests): buy/sell basics, hotel, error retry,
  real log replay (lines 59, 354, 4386)
- test_parser_commands.py: 4 new integration tests (buy, sell, reject,
  real log verification)

This closes the last tracking gap — house counts are now accurate at
purchase time, not just when rent is later charged.
2026-02-21 19:43:03 +00:00
22e98794d3 Parse player commands and holdings displays for full state tracking
Player command tracking:
- .card: detect GOJF card usage in jail (previously invisible)
- .mortgage/.mor: set property_mortgaged flag using cost+name disambiguation
- .unmortgage/.unm: clear property_mortgaged flag using cost+name disambiguation
- Command context (_command_context) disambiguates 'That cost you $X' between
  jail pay and unmortgage

Holdings display parsing:
- Parse 'NAME's (N) holdings' header, then printsq-format property lines
- Full resync of property_owner, property_mortgaged, property_houses
- Reuses resolve_trade_property() for name matching
- Holdings end on any non-property line (checkpoint, command prompt, etc.)

13 new tests in test_parser_commands.py:
- GOJF card (4): exit jail, no card, not in jail, log entry
- Unmortgage (2): unique property, disambiguation with user input
- Mortgage (1): flag set correctly
- Holdings (5): ownership, mortgage, houses, stale clearing, real log replay
- Real log (1): unmortgage at line 36-41

All 1551 checkpoints + 80 unit tests passing.
2026-02-21 19:30:21 +00:00
1aadcddabe Add docs/BUGS_AND_FIXES.md — regression reference for all fixed bugs 2026-02-21 19:15:16 +00:00
a08fd86bf2 Update house counts from rent lines
When 'with N houses, rent is X' or 'with a hotel, rent is X' is seen,
update property_houses for the current player's location. This partially
fixes stale house data in the UI — houses are synced when rent is charged,
though not at the moment of purchase.
2026-02-21 19:01:08 +00:00
1cb6da257f Fix 7 bugs: trade property transfer, UI owner colors, resign edge cases, spec flag, phase field, timestamps
Bug fixes:
- #1: Trade now transfers properties (parse printsq-format lines in trade summaries)
- #2: UI owner indicator uses player number lookup instead of raw array index
- #3: Mid-stream game pickup sets _first_player_idx
- #4: Resign with unresolved target clears properties (bank fallback)
- #6: spec flag cleared after rent payment (matches C's get_card cleanup)
- #13: get_state() always emits phase field (setup/playing/over)
- #16: Resign and trade log entries include timestamps

Also:
- Bankrupt players tracked with bankrupt flag, shown in UI with skull/dashed border
- 19 resignation tests (test_parser_resign.py)
- 10 bug-specific tests (test_parser_bugs.py)
- All 1551 parser checkpoints + 67 unit tests passing
2026-02-21 18:52:10 +00:00
9c47bac33a Fix setup registration: names appear as each player joins
Parser: detect name registration from user input during setup
(sender == name constraint prevents false matches on gameplay messages).

Bridge: extract _process_buffer() to handle leftover lines after
_wait_for_players returns, preventing messages from being stuck.

Player bots: proactively send name on join (not just first player
sending count) so they respond even if they missed the 'say me' prompt.

All tests pass (1551/1553 parser checkpoints, 38 player unit tests).
2026-02-21 11:54:53 +00:00
6d055c68a2 Fix setup visibility: bridge waits for players, observer sees registration
Bridge changes:
- Wait for at least one user to JOIN before starting monop
- Ensures observer is in channel to see all setup messages

Parser changes:
- Handle 'Player N, say me' even without prior 'How many players?'
- Infer num_players_expected from highest player number seen
- Emit state during setup phase

run_game.py changes:
- 3s stagger between bot joins so setup is visible in web UI
- Observer connects before bots to catch all registration messages
2026-02-21 11:33:28 +00:00
72d996cb4b Show players during setup: empty slots and registration progress
Parser changes:
- Track num_players_expected from user input after 'How many players?'
- Create placeholder players ('Player N') on 'say me please' prompts
- Replace placeholder names when real names appear in roll lines
- Emit state during setup phase (was returning None)
- Include phase and numPlayersExpected in state JSON

UI changes:
- Empty slots shown as dashed/dimmed panels with '?' token
- Placeholder players shown as 'Registering...'
- Registered players shown with checkmark and ,500
- Status bar shows 'Setting up · 2/3 players registered'
2026-02-21 11:24:49 +00:00
435b24bfb8 Replace disconnected overlay with slim banner matching stale style
Same top-banner pattern as the stale indicator but with red accent
and 'Connection lost — retrying every 2s...' message. Page gets
subtle greyscale/dim instead of a blocking overlay.
2026-02-21 11:15:18 +00:00
dd4787615d Add stale data banner when game state hasn't updated in 20s
Subtle top banner with dimmed page (not a blocking overlay like the
full disconnect state). Shows elapsed time since last update.
Separate from the hard disconnect which triggers after 3 fetch failures.

Debug panel: added 'Stale' button to test.
2026-02-21 11:13:19 +00:00
34a4f47402 Add zero state, disconnected overlay, game over confetti, and debug panel
- Zero state: bouncing dice + message when no game exists
- Disconnected: greyed overlay after 3 consecutive fetch failures,
  with retry countdown
- Game over: gold banner with winner name + confetti animation,
  detected from log ('WINS!') or single remaining player
- Debug panel: Ctrl+Shift+D toggles hidden panel with buttons to
  test all four states (zero, playing, gameover, disconnected, reset)
- Also fixed player panel to use p.number for current-turn matching
  and property ownership display
2026-02-21 11:08:06 +00:00
19fc56d982 Emit players in turn order, not registration order
The C code picks a starting player via dice roll but doesn't reorder
the player array. The parser now tracks _first_player_idx and rotates
the players list in get_state() so the UI shows them in actual turn
order.
2026-02-21 11:02:22 +00:00
7a4346a53f Fix trade race condition: move trade/roll decision to -- Command: handler
The root cause: checkpoint handler queued .trade via say_delayed, but
monop sends '-- Command:' before processing the trade. The old handler
reset in_trade and queued .roll, so both commands got sent.

Fix: checkpoint handler no longer sends commands. The -- Command:
prompt is where the bot decides to trade or roll, matching how monop
actually works (-- Command: is the interactive prompt).

Also: no trades while in jail (jail has no -- Command: before roll).

Updated all tests to reflect the new flow.
2026-02-21 10:55:33 +00:00
8bbadba7d9 Fix trade-in-jail bug: jail handler must not roll during active trade
Added guard in jail turn handler to skip rolling when in_trade is True.
The roll happens later when '-- Command:' arrives after trade completes.

Added 5 regression tests for the exact failing sequence.
2026-02-21 10:45:15 +00:00
d31a09e754 Fix trade logic in player bots
- Handle 'Which player do you wish to trade with?' prompt when
  in_trade is True (was silently returning, causing bot to roll
  during an active trade prompt)
- Simplify property trade offers to always say 'done' (cash-only
  trades) to avoid getting stuck on property list prompts
2026-02-21 10:42:57 +00:00
d2bd66ba78 Add game log to parser output for web viewer
Parser now accumulates log entries for key game events:
- Turn starts (checkpoint lines)
- Rolls, movement, passing GO
- Rent payments
- Card draws (with card text)
- Auctions, trades, resignations
- Jail (triple doubles, GO TO JAIL)
- Game start and winner

Log is capped at 100 entries in GameState, last 30 emitted in
get_state() to match what index.html expects.

Also synced plugin's monop_parser.py copy.
2026-02-21 10:30:53 +00:00
cceec64a7c Add ARCHITECTURE.md developer guide
Covers system goals, component design, directory structure,
testing strategies, and key design decisions for future agents.
2026-02-21 10:20:01 +00:00
7dadd1f37f Organize directory structure
- cardinal-plugin/ → plugins/ (matches Cardinal's plugin dir convention)
- index.html + game-state.json → site/
- OUTPUT_CATALOG.md → docs/
- Core Python files and tests stay flat (no import changes needed)
2026-02-21 10:16:49 +00:00
c8e5a83010 Add unit tests for autopilot players (32 tests), fix trade force=True and duplicate handler 2026-02-21 09:53:09 +00:00
0af3184590 Add random trading (~10% chance per turn, 50/50 accept/reject) 2026-02-21 09:46:29 +00:00
cab39ec2b2 Add autopilot test logs (2162 lines, successful 2-player game) 2026-02-21 09:39:17 +00:00
775bbde030 Fix mortgage flow: send ? for property list, done when solvent 2026-02-21 09:23:33 +00:00
2ffd7c3845 Add Cardinal player plugin + fix autopilot: force setup responses, suppress out-of-turn rolls, fix tax input, fix double-roll from -- Command handler 2026-02-21 09:17:42 +00:00
5aa96d2163 Add standalone autopilot players script 2026-02-21 08:57:10 +00:00
44b9ed1ab1 Fix: property ownership now tracked on buy and auction
- Direct buy: set property_owner when buy confirmed via checkpoint
- Auction: set property_owner when 'It goes to' parsed
- Historical log replay still passes (1551/1553)
2026-02-21 04:14:49 +00:00
2b022f15c3 Add Cardinal plugin for monop state tracking
- Watches channel messages via @event('irc.privmsg')
- Feeds to MonopParser, writes game-state.json on state change
- Commands: .monop [status|players|board|owned]
- Bundled monop_parser.py in plugin dir
- Standalone test passes
2026-02-21 03:54:59 +00:00
e604a32233 Add integration test - parser matches monop state perfectly (7/7 checks pass) 2026-02-21 03:50:08 +00:00
57aae01e1b Add monop parser and test suite - 1551/1553 checkpoints pass 2026-02-21 03:10:53 +00:00
ba4463dcc8 Re-add test data and reference files after reboot 2026-02-21 02:37:37 +00:00
6fae024a7c Add complete monop output catalog from C source 2026-02-21 01:42:51 +00:00
299c8bfa64 Fix game-state schema to match monop-irc 2026-02-21 01:37:59 +00:00
653308817d Initial: monop-board site files 2026-02-21 01:35:37 +00:00