Initial commit: 酒桌派对 / 大话骰 multiplayer drinking-game hub
- server.py: zero-dependency stdlib backend (HTTP + WebSocket /ws), 大话骰 rule engine, server-driven bots - live.html: real MVP frontend wired to the backend over WebSocket - index.html/app.js/style.css: older static prototype - deploy/: systemd unit + Nginx reverse proxy + Let's Encrypt setup.sh - test_*.py: standalone HTTP / in-process test scripts Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
52
test_multi_result.py
Normal file
52
test_multi_result.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import json, urllib.request
|
||||
base='http://127.0.0.1:8765'
|
||||
def post(path, data):
|
||||
req=urllib.request.Request(base+path, data=json.dumps(data).encode(), headers={'Content-Type':'application/json'})
|
||||
try: return json.loads(urllib.request.urlopen(req, timeout=5).read())
|
||||
except Exception as e:
|
||||
body=e.read().decode() if hasattr(e,'read') else str(e)
|
||||
return json.loads(body) if body.startswith('{') else {'ok':False,'error':body}
|
||||
def get_room(code): return json.loads(urllib.request.urlopen(base+'/api/room?code='+code).read())['room']
|
||||
|
||||
# 4 人局:房主 + 3 机器人,房主开三家直接结算
|
||||
r=post('/api/create', {'game':'dice','name':'小鱼','playerId':'p-host'})
|
||||
code=r['room']['code']
|
||||
for _ in range(3): post('/api/add-bot', {'code':code,'playerId':'p-host'})
|
||||
post('/api/start', {'code':code})
|
||||
post('/api/call', {'code':code,'playerId':'p-host','count':4,'point':1})
|
||||
for _ in range(3): post('/api/bot-turn', {'code':code,'playerId':'p-host'})
|
||||
|
||||
res=post('/api/multi-open3', {'code':code,'playerId':'p-host'})
|
||||
assert res['ok'], '开三家失败: '+str(res.get('error'))
|
||||
lr=res['room']['lastResult']
|
||||
players=[p['name'] for p in res['room']['players']]
|
||||
|
||||
print('text:', lr['text'])
|
||||
print('winners:', lr.get('winners'))
|
||||
print('drinks :', lr.get('drinks'))
|
||||
print('calls :', lr.get('calls'))
|
||||
|
||||
# 1) 结构完整:winners/drinks/calls 都存在
|
||||
assert 'winners' in lr and 'drinks' in lr, '缺少 winners/drinks 字段'
|
||||
# 0) 叫点明细:每个被开的参与者都带 count/point/mode 与实际数
|
||||
calls=lr.get('calls') or []
|
||||
assert calls, '缺少 calls 叫点明细'
|
||||
assert len(calls)==3, '开三家应有 3 家叫点明细'
|
||||
for c in calls:
|
||||
assert c.get('count') and c.get('point') and c.get('mode'), f"叫点明细缺字段: {c}"
|
||||
assert c.get('actual') is not None, f"开三家应有实际数: {c}"
|
||||
assert isinstance(c.get('win'), bool), f"开三家应有成立判定: {c}"
|
||||
assert {c['name'] for c in calls}==set(players)-{'小鱼'}, '开三家叫点明细应为发起者外的 3 名叫骰人'
|
||||
drink_names=[d['name'] for d in lr['drinks']]
|
||||
# 2) 每个喝酒的人杯数 > 0
|
||||
assert all(d['cups']>0 for d in lr['drinks']), '存在 0 杯的喝酒项'
|
||||
# 3) 赢家与喝酒者不重叠,且二者并集覆盖全部 4 名参与者(不再只显示一个人)
|
||||
assert set(lr['winners']) & set(drink_names)==set(), '赢家与喝酒者重叠'
|
||||
assert set(lr['winners']) | set(drink_names)==set(players), '赢家+喝酒者未覆盖全部参与者'
|
||||
# 4) 喝酒明细与各玩家 cups 增量一致
|
||||
cups_by_name={p['name']:p['cups'] for p in res['room']['players']}
|
||||
for d in lr['drinks']:
|
||||
assert cups_by_name[d['name']]>=d['cups'], f"{d['name']} 杯数不一致"
|
||||
|
||||
print(f"参与者 {len(players)} 人 -> 赢家 {len(lr['winners'])} · 喝酒 {len(drink_names)}")
|
||||
print('PASS: 多家结算输出完整的赢家/各人喝杯明细,覆盖全部参与者')
|
||||
Reference in New Issue
Block a user