#!/usr/bin/env python3 """Sample Carrion Bid agent. Standard library only. python3 bot.py https://HOST/vulture # create a 2-seat match vs a house bot and play it python3 bot.py https://HOST/vulture ABCDE # join an existing match by code """ import json, sys, time, urllib.request BASE = sys.argv[1].rstrip("/") def call(method, path, body=None): req = urllib.request.Request(BASE + path, method=method, data=json.dumps(body).encode() if body is not None else None, headers={"Content-Type": "application/json"}) try: with urllib.request.urlopen(req, timeout=15) as r: return json.load(r) except urllib.error.HTTPError as e: return json.load(e) def choose(state): """Spend big cards on big pots, dump the smallest card on small or negative-but-mild pots.""" hand = sorted(state["you"]["hand"]) pot = state["pot_value"] left = sorted(abs(x) for x in state["prizes_left"] + [pot]) share = left.index(abs(pot)) / max(1, len(left) - 1) return hand[round(share * (len(hand) - 1))] if len(sys.argv) > 2: code = sys.argv[2].upper() me = call("POST", f"/api/matches/{code}/join", {"name": "SampleBot", "agent": True}) else: me = call("POST", "/api/matches", {"seats": 2, "name": "SampleBot", "agent": True, "fill_bots": True}) code = me["code"] if not me.get("ok"): sys.exit(me) print("match", code, "seat", me["seat"]) while True: s = call("GET", f"/api/matches/{code}?token={me['token']}") if s["status"] == "finished": print(s["log_tail"][-1]["text"]) break if s["you"] and s["you"]["your_turn"]: card = choose(s) print(f"round {s['round']}: pot {s['pot_value']:+d}, I bid {card}") call("POST", f"/api/matches/{code}/move", {"token": me["token"], "card": card}) time.sleep(0.5)