#!/usr/bin/env python3
"""Turn a battle.json produced by blackjack.py into a static website.
Usage:
python3 build_site.py --battle battle.json --out site
"""
import argparse
import json
import shutil
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path(__file__).resolve().parent
HTML = r"""
__TITLE__
21d1 × d1 對戰實驗室
載入對戰資料中…
"""
README = """---
title: d1demo
emoji: 🃏
colorFrom: green
colorTo: yellow
sdk: static
pinned: false
license: mit
---
# d1 × d1 21 點對戰實錄
兩個 **LiquidAI d1-3B** 決策模型,各自跑在一個 llama.cpp server 上,在同一張 21 點牌桌上對打。每一次下注、補牌、停牌、加倍,都是模型輸出的機率分佈;這頁把每一步整理成可回放的視覺化紀錄。
- 模型:`LiquidAI/d1-3B-GGUF` (Q8_0),llama.cpp b11786
- API:`POST /v1/systemone`(d1 是 decision model,不是文字生成模型)
- 賽制:破產對決,注碼為當前資金的 50% / 70% / 100%,無補充籌碼,直到兩邊都歸零
- 莊家:規則操作,S17,6 副牌,BJ 3:2
- 內容:對戰時間軸、決策機率、風險評分、信心度、延遲、資金曲線、破產統計
- 原始碼:`source/blackjack.py`(對戰 + 記錄)、`source/build_site.py`(靜態網頁編譯)
- 原始資料:`battle.json`
頁面是靜態的,所有資料都在 `battle.json`;`build_site.py` 可重新編譯整站。
"""
def build(battle_path, out_dir):
data = json.loads(Path(battle_path).read_text(encoding="utf-8"))
out = Path(out_dir)
out.mkdir(parents=True, exist_ok=True)
(out / "source").mkdir(exist_ok=True)
(out / "battle.json").write_text(
json.dumps(data, ensure_ascii=False, indent=1), encoding="utf-8"
)
shutil.copy(battle_path, out / "battle.json")
for name in ("blackjack.py", "build_site.py", "run_demo.sh"):
src = ROOT / name
if src.exists():
shutil.copy(src, out / "source" / name)
inline = "window.BATTLE_DATA = " + json.dumps(data, ensure_ascii=False) + ";"
html = HTML.replace("__TITLE__", data["meta"]["title"]).replace(
"__SUBTITLE__", data["meta"]["subtitle"]
)
html = html.replace('