Tavla‑1.6K 🎲

A real, trained backgammon (tavla) value network with 1,601 parameters. TD‑Gammon style: it taught itself by playing against itself, on a CPU, in numpy, in 95 minutes. The whole model is 6.6 KB. It fits in a tweet's attachment, or in a very long tweet.

▶ Play it in your browser: https://tiny-models.anil-oz.workers.dev/tavla (ONNX Runtime Web; tr/de/es/fr under /xx/tavla) 💻 Site source: https://github.com/hocestnonsatis/coinflip-ai

Model

Input 198 features, Tesauro encoding (per point and side: ≥1, ≥2, ≥3, (n−3)/2 · bar/2 · off/15 · 2 turn units)
Hidden 8 sigmoid units
Output 1 sigmoid: P(win) for the player who just moved
Parameters 1,601 = 198·8 + 8 + 8·1 + 1
ONNX tavla-1.6k.onnx, 6,786 bytes, opset 17, input x [N,198] → output p [N,1]

Move selection is 1‑ply: generate every legal play, encode each resulting position, score them all in one session.run, play the argmax. No gammon outputs, no doubling cube.

Training

  • TD(λ) self‑play, λ = 0.7, learning rate linearly 0.2 → 0.02, weights init N(0, 0.1²), seed 4
  • 381,954 self‑play games in 95 minutes on one CPU core (pure numpy, no GPU harmed)
  • 8 hyper‑parameter configs were trained in parallel for 95 min each. Checkpoints were screened against a heuristic bot, and the final checkpoint of this run won.
  • Rules engine (train/bg.py): bar entry, hitting, bearing off (including higher‑die bear‑off from the highest point), must‑use‑both‑dice / larger‑die rule, doubles. The site's TypeScript port produces identical legal‑move sets on 1,500 random positions.

Evaluation

Held-out evaluation with fresh seeds (not the seeds used for selection), 5,000 games per opponent. The first player is chosen at random:

Opponent Wins Win rate
Random legal‑move player 4,986 / 5,000 99.7%
Pip‑count heuristic bot (race + blots + made points) 3,766 / 5,000 75.3%

These are single‑game wins. Gammons are not counted. It has never met a human at a coffee house. Results there may vary.

Usage

pip install onnxruntime numpy
python example.py
import onnxruntime as ort, numpy as np, sys
sys.path.insert(0, 'train'); from bg import start, legal, encode_batch
sess = ort.InferenceSession('tavla-1.6k.onnx')
plays = legal(start(), 3, 1)                       # {resulting board: steps}
p = sess.run(None, {'x': encode_batch(list(plays))})[0][:, 0]
print(list(plays.values())[int(np.argmax(p))])     # → 8/5 6/5, the textbook 3‑1

Boards are always seen from the side to move: b[0..23] are points (mine > 0, opponent < 0, I move toward index 0), b[24]/b[25] are my/opponent's bar, and b[26]/b[27] are borne off.

Files

  • tavla-1.6k.onnx: the model
  • tavla-1.6k.safetensors, tavla-1.6k.npz: the same weights (W1 198×8, b1 8, W2 8×1, b2 1)
  • example.py: encode → win probability → pick a move, plus a self‑play game
  • train/: bg.py (rules + encoding), net.py, td.py (TD(λ) trainer: python td.py d 0.2 0.02 0.7 4 95), eval.py (vs random / heuristic), players.py, play.py, fixtures.py (cross-check data), export_onnx.py

Limitations

  • No doubling cube, no match play, no gammon/backgammon outputs.
  • 1‑ply search with 8 hidden units: solid against casual play, not expert level (TD‑Gammon used 40–80 hidden units plus deeper search).
  • Evaluation is only against a random player and a simple heuristic bot. There is no GNU Backgammon benchmark.

Türkçe

Tavla‑1.6K, 1.601 parametreli, gerçekten eğitilmiş bir tavla ağı: 198 girdi (Tesauro kodlaması) → 8 sigmoid nöron → 1 çıktı (kazanma olasılığı). TD(λ=0,7) ile kendine karşı 381.954 oyun oynayarak, tek CPU çekirdeğinde 95 dakikada öğrendi. Rastgele oyuncuya karşı %99,7 (4986/5000), pip sayan sezgisel bota karşı %75,3 (3766/5000) kazanıyor. Katlama küpü yok, usta değil, ama hamlesini milisaniyede yapar. Tarayıcıda oyna: https://tiny-models.anil-oz.workers.dev/tr/tavla

License

MIT · © Anıl ÖZ

Downloads last month

-

Downloads are not tracked for this model. How to track
Video Preview
loading