monop-state/screenshot_integration.py

235 lines
8.6 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
Take screenshots at key moments during a synthetic game that exercises all fixed bugs.
Writes game-state.json at each step and captures the UI.
"""
import json, os, sys, time, subprocess
from datetime import datetime, timezone
from playwright.sync_api import sync_playwright
sys.path.insert(0, os.path.dirname(__file__))
from monop_parser import MonopParser, BOARD
SITE_DIR = os.path.join(os.path.dirname(__file__), "site")
STATE_PATH = os.path.join(SITE_DIR, "game-state.json")
SCREENSHOTS_DIR = os.path.join(os.path.dirname(__file__), "screenshots")
os.makedirs(SCREENSHOTS_DIR, exist_ok=True)
_t = [0]
def ts():
_t[0] += 1
return f"2026-01-01 00:{_t[0]//60:02d}:{_t[0]%60:02d}"
def feed(p, lines):
for line in lines:
p.parse_line(f"{ts()}\t{line}")
def write_state(p):
state = p.get_state()
state["lastUpdated"] = datetime.now(timezone.utc).isoformat()
with open(STATE_PATH, "w") as f:
json.dump(state, f, indent=2)
def screenshot(page, name, wait=3000):
page.wait_for_timeout(wait)
path = os.path.join(SCREENSHOTS_DIR, f"{name}.png")
page.screenshot(path=path, full_page=True)
print(f"[screenshot] {name}")
def main():
server = subprocess.Popen(
[sys.executable, "-m", "http.server", "9998", "--directory", SITE_DIR],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
)
time.sleep(1)
try:
with sync_playwright() as pw:
browser = pw.chromium.launch()
page = browser.new_page(viewport={"width": 1280, "height": 1600})
p = MonopParser()
# === Setup: 3-player game ===
feed(p, [
"monop\tHow many players? ",
"monop\tPlayer 1, say 'me' please.",
"monop\talice (1) rolls 3",
"monop\tPlayer 2, say 'me' please.",
"monop\tbob (2) rolls 5",
"monop\tPlayer 3, say 'me' please.",
"monop\tcharlie (3) rolls 9",
"monop\tcharlie (3) goes first",
"monop\tcharlie (3) (cash $1500) on === GO ===",
"monop\t-- Command: ",
])
# charlie buys Mediterranean + Oriental, gets lightblue monopoly
feed(p, [
"charlie\t.",
"monop\troll is 1, 0",
"monop\tThat puts you on Mediterranean ave. (P)",
"monop\tThat would cost $60",
"monop\tDo you want to buy? ",
"charlie\t.y",
"monop\talice (1) (cash $1500) on === GO ===",
"monop\t-- Command: ",
])
g = p.game
g.property_owner[6] = 3 # Oriental
g.property_owner[8] = 3 # Vermont
g.property_owner[9] = 3 # Connecticut
# alice buys Baltic, bob buys Reading RR + B&O RR
feed(p, [
"alice\t.",
"monop\troll is 1, 2",
"monop\tThat puts you on Baltic ave. (P)",
"monop\tThat would cost $60",
"monop\tDo you want to buy? ",
"alice\t.y",
"monop\tbob (2) (cash $1500) on === GO ===",
"monop\t-- Command: ",
"bob\t.",
"monop\troll is 2, 3",
"monop\tThat puts you on Reading RR",
"monop\tThat would cost $200",
"monop\tDo you want to buy? ",
"bob\t.y",
"monop\tcharlie (3) (cash $1440) on Mediterranean ave. (P)",
"monop\t-- Command: ",
])
g.property_owner[25] = 2 # B&O RR for bob
# === Screenshot 1: Mid-game with properties owned ===
write_state(p)
page.goto("http://localhost:9998")
screenshot(page, "01_midgame_properties_owned")
# === charlie buys houses (House sub-parser) ===
feed(p, [
"charlie\t.buy",
"monop\tOriental ave. (L) (0) Vermont ave. (L) (0) Connecticut ave. (L) (0) ",
"monop\tHouses will cost $50",
"monop\tHow many houses do you wish to buy for",
"monop\tOriental ave. (L) (0): ",
"charlie\t.3",
"monop\tVermont ave. (L) (0): ",
"charlie\t.3",
"monop\tConnecticut ave. (L) (0): ",
"charlie\t.3",
"monop\tYou asked for 9 houses for $450",
"monop\tIs that ok? ",
"charlie\t.y",
"monop\tcharlie (3) (cash $990) on Mediterranean ave. (P)",
"monop\t-- Command: ",
])
# === Screenshot 2: Houses visible on board ===
write_state(p)
page.reload()
screenshot(page, "02_houses_built")
# === Trade: bob gives Reading RR to charlie for $300 ===
feed(p, [
"monop\talice (1) (cash $1440) on Baltic ave. (P)",
"monop\t-- Command: ",
"alice\t.",
"monop\troll is 2, 1",
"monop\tThat puts you on Oriental ave. (L)",
"monop\tOwned by charlie",
"monop\twith 3 houses, rent is 90",
"monop\tbob (2) (cash $1300) on Reading RR",
"monop\t-- Command: ",
"monop\tPlayer bob (2) gives:",
"monop\t Reading RR 2 200 1",
"monop\tPlayer charlie (3) gives:",
"monop\t $300",
"monop\tcharlie, is the trade ok? ",
"charlie\t.y",
"monop\tTrade is done!",
"monop\tbob (2) (cash $1600) on Reading RR",
"monop\t-- Command: ",
])
# === Screenshot 3: After trade — Reading RR now charlie's ===
write_state(p)
page.reload()
screenshot(page, "03_after_trade")
# === alice mortgages Baltic ===
feed(p, [
"bob\t.",
"monop\troll is 1, 2",
"monop\tThat puts you on Vermont ave. (L)",
"monop\tOwned by charlie",
"monop\twith 3 houses, rent is 90",
"monop\talice (1) (cash $1350) on Oriental ave. (L)",
"monop\t-- Command: ",
"alice\t.mor",
"monop\tWhich property do you want to mortgage? ",
"alice\t.baltic",
"monop\tThat got you $30",
"monop\talice (1) (cash $1380) on Oriental ave. (L)",
"monop\t-- Command: ",
])
# === Screenshot 4: Baltic mortgaged ===
write_state(p)
page.reload()
screenshot(page, "04_baltic_mortgaged")
# === bob resigns to bank ===
feed(p, [
"alice\t.",
"monop\troll is 1, 3",
"monop\tThat puts you on Connecticut ave. (L)",
"monop\tOwned by charlie",
"monop\twith 3 houses, rent is 90",
"monop\tbob (2) (cash $1510) on Vermont ave. (L)",
"monop\t-- Command: ",
"bob\t.resign",
"monop\tWho do you wish to resign to? ",
"bob\t.bank",
"monop\tDo you really want to resign? ",
"bob\t.y",
"monop\tresigning to bank",
"monop\tcharlie (1) (cash $1380) on Mediterranean ave. (P)",
"monop\t-- Command: ",
])
# === Screenshot 5: Bob bankrupt ===
write_state(p)
page.reload()
screenshot(page, "05_bob_bankrupt")
# === alice resigns to charlie — game over ===
feed(p, [
"charlie\t.",
"monop\troll is 2, 3",
"monop\tThat puts you on Oriental ave. (L)",
"monop\tYou own it.",
"monop\talice (1) (cash $1260) on Connecticut ave. (L)",
"monop\t-- Command: ",
"monop\tYou would resign to charlie",
"monop\tDo you really want to resign? ",
"alice\t.y",
"monop\tresigning to player",
"monop\tTrade is done!",
"monop\tThen charlie WINS!!!!!",
])
# === Screenshot 6: Game over ===
write_state(p)
page.reload()
screenshot(page, "06_game_over")
browser.close()
print("\nAll screenshots captured!")
finally:
server.terminate()
server.wait()
if __name__ == "__main__":
main()