Initial commit: Hold'em engine, bots, and simulation harness
Kotlin Multiplatform engine (JVM target only for now; androidTarget and iosArm64 slot in without touching commonMain). Core: - HandEvaluator: single-pass 5-7 card evaluation, ~24M evals/sec. Verified exhaustively against published frequencies for all 2,598,960 five-card hands. - Equity: Monte Carlo with ties split. PreflopChart ranks the 169 starting hands using all-in equity plus an explicit playability adjustment, so looseness means "plays the top N%". - Table: no-limit betting rounds, side pots, odd-chip splits, uncalled-bet refunds, and incomplete (short all-in) raises that correctly do not reopen betting. Bots: - SkillLevel and PlayStyle are orthogonal axes. Skill drives decision quality (rollout accuracy, pot-odds discipline, position awareness, error rate); style drives bluffing, sandbagging, aggression, tightness. - BotMood gives tilt that persists between hands and decays. - OpponentModel lets Advanced/Expert exploit habitual bettors. - MathBot emits a DecisionTrace of the numbers behind each decision, which the coach will later hand to an LLM to narrate. The LLM never does poker maths. Simulator: - 2,200-3,400 hands/sec. Deck RNG is separate from bot RNGs so rollout counts cannot shift the deal. - Controlled skill-ladder test asserts the difficulty gradient is monotonic: 73.9 / 53.9 / 27.6 / -155.4 bb/100 over 50k hands. Assets: 52 CC0 English-pattern card faces plus generated backs. Tests: 30 passing (evaluator, table rules, pre-flop chart). Known open: win-rate magnitudes ~10x realistic and several profiles looser than their labels. Tuning, not correctness. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="1.1" width="360" height="540" viewBox="0 0 360 540">
|
||||
<defs>
|
||||
<!-- Interlocking lattice, rotated 45deg for the classic diagonal weave -->
|
||||
<pattern id="lattice" width="36" height="36" patternUnits="userSpaceOnUse"
|
||||
patternTransform="rotate(45 0 0)">
|
||||
<rect width="36" height="36" fill="#a81d24"/>
|
||||
<path d="M 18,0 L 18,36 M 0,18 L 36,18" stroke="#c9545b"
|
||||
stroke-width="1.5" fill="none"/>
|
||||
<circle cx="18" cy="18" r="6" fill="none" stroke="#c9545b" stroke-width="1.5"/>
|
||||
<circle cx="18" cy="18" r="1.8" fill="#c9545b"/>
|
||||
<g fill="#c9545b">
|
||||
<circle cx="0" cy="0" r="3.2"/><circle cx="36" cy="0" r="3.2"/>
|
||||
<circle cx="0" cy="36" r="3.2"/><circle cx="36" cy="36" r="3.2"/>
|
||||
</g>
|
||||
</pattern>
|
||||
|
||||
<!-- Centre glow so the medallion sits on a lit field -->
|
||||
<radialGradient id="vignette" cx="50%" cy="50%" r="62%">
|
||||
<stop offset="0%" stop-color="#c4353d" stop-opacity="0.85"/>
|
||||
<stop offset="55%" stop-color="#c4353d" stop-opacity="0.20"/>
|
||||
<stop offset="100%" stop-color="#8f1218" stop-opacity="0.75"/>
|
||||
</radialGradient>
|
||||
|
||||
<clipPath id="panelClip">
|
||||
<rect x="16" y="16" width="328" height="508" rx="19" ry="19"/>
|
||||
</clipPath>
|
||||
|
||||
<g id="spade"><path d="M 0,-19 C -5,-9 -18,-3 -18,6 C -18,12 -13,15.5 -8.5,15.5 C -5,15.5 -2,13.5 0,10 C 2,13.5 5,15.5 8.5,15.5 C 13,15.5 18,12 18,6 C 18,-3 5,-9 0,-19 Z"/><path d="M -1,8 C -1,14 -4,18 -7.5,19.5 L 7.5,19.5 C 4,18 1,14 1,8 Z"/></g>
|
||||
<path id="heart" d="M 0,19 C -5,12 -18,3 -18,-7 C -18,-14.5 -12,-18.5 -7,-18.5 C -3,-18.5 -0.5,-15.5 0,-12 C 0.5,-15.5 3,-18.5 7,-18.5 C 12,-18.5 18,-14.5 18,-7 C 18,3 5,12 0,19 Z"/>
|
||||
<path id="diamond" d="M 0,-20 C 4,-10 9,-4 14,0 C 9,4 4,10 0,20 C -4,10 -9,4 -14,0 C -9,-4 -4,-10 0,-20 Z"/>
|
||||
<g id="club">
|
||||
<circle cx="0" cy="-9" r="9"/><circle cx="-10" cy="5" r="9"/>
|
||||
<circle cx="10" cy="5" r="9"/><path d="M -1.2,4 C -1.2,11 -4,16 -7.5,19 L 7.5,19 C 4,16 1.2,11 1.2,4 Z"/>
|
||||
</g>
|
||||
|
||||
<!-- Corner ornament: a small gold lozenge cluster -->
|
||||
<g id="ornament" fill="#e3c179">
|
||||
<path d="M 0,-9 L 5,0 L 0,9 L -5,0 Z"/>
|
||||
<circle cx="0" cy="-13.5" r="2"/><circle cx="0" cy="13.5" r="2"/>
|
||||
<circle cx="-9" cy="0" r="2"/><circle cx="9" cy="0" r="2"/>
|
||||
</g>
|
||||
</defs>
|
||||
|
||||
<!-- Card body: identical geometry to the face cards -->
|
||||
<rect x="0.5" y="0.5" width="359" height="539" rx="29.944447" ry="29.944447"
|
||||
fill="#ffffff" stroke="#000000" stroke-width="1"/>
|
||||
|
||||
<!-- Patterned panel -->
|
||||
<g clip-path="url(#panelClip)">
|
||||
<rect x="16" y="16" width="328" height="508" fill="#8f1218"/>
|
||||
<rect x="16" y="16" width="328" height="508" fill="url(#lattice)"/>
|
||||
<rect x="16" y="16" width="328" height="508" fill="url(#vignette)"/>
|
||||
</g>
|
||||
|
||||
<!-- Gold double frame -->
|
||||
<rect x="16" y="16" width="328" height="508" rx="19" ry="19"
|
||||
fill="none" stroke="#e3c179" stroke-width="2.5"/>
|
||||
<rect x="24" y="24" width="312" height="492" rx="13" ry="13"
|
||||
fill="none" stroke="#e3c179" stroke-width="1" opacity="0.75"/>
|
||||
|
||||
<!-- Corner ornaments -->
|
||||
<use xlink:href="#ornament" x="0" y="0" transform="translate(52,64)"/>
|
||||
<use xlink:href="#ornament" x="0" y="0" transform="translate(308,64)"/>
|
||||
<use xlink:href="#ornament" x="0" y="0" transform="translate(52,476)"/>
|
||||
<use xlink:href="#ornament" x="0" y="0" transform="translate(308,476)"/>
|
||||
|
||||
<!-- Central medallion -->
|
||||
<g>
|
||||
<ellipse cx="180" cy="270" rx="86" ry="104" fill="#8f1218" opacity="0.55"/>
|
||||
<ellipse cx="180" cy="270" rx="80" ry="98" fill="#faf4e6"
|
||||
stroke="#e3c179" stroke-width="3"/>
|
||||
<ellipse cx="180" cy="270" rx="72" ry="90" fill="none"
|
||||
stroke="#e3c179" stroke-width="1" opacity="0.8"/>
|
||||
|
||||
<!-- Four suits in a diamond arrangement -->
|
||||
<use xlink:href="#spade" transform="translate(180,206) scale(0.82)" fill="#1a1a1a"/>
|
||||
<use xlink:href="#diamond" transform="translate(180,334) scale(0.82)" fill="#c8102e"/>
|
||||
<use xlink:href="#heart" transform="translate(130,270) scale(0.82)" fill="#c8102e"/>
|
||||
<use xlink:href="#club" transform="translate(230,270) scale(0.82)" fill="#1a1a1a"/>
|
||||
|
||||
<!-- Tiny centre pip to tie the arrangement together -->
|
||||
<circle cx="180" cy="270" r="4.5" fill="#e3c179"/>
|
||||
<circle cx="180" cy="270" r="1.8" fill="#8f1218"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
Reference in New Issue
Block a user