Files
Pete/internal/web/templates/games.html
prosolis 79c857023f games: a table of bots you have to beat to the last card
UNO, played for chips. You stake once, sit down against one to three bots,
and going out first pays the table: 2.2x heads up, 3.6x against a full house.
Anybody else going out first takes the stake. The table size is the tier,
because it is the only dial UNO has.

The bots move inside ApplyMove. A game with opponents is normally where you
reach for a socket, and the plan says solo UNO must not — so one request plays
your move and every bot turn behind it, and hands back the whole lap as a
script the felt plays in order.

The RNG is in the state rather than an argument to it: the bots choose and a
spent deck reshuffles, so the engine needs randomness mid-game, and there is no
generator alive across requests to pass in. The seed rides in the state and each
step derives its own. The game still replays exactly as it fell.

The zero value of Color is Wild, and that is the whole point of it: a wild
played with the colour field missing from the JSON must be refused, not
quietly played as a red one. It was red for an hour.

The browser never sees a bot's card — not the deck, not a hand, not the face of
a card a bot drew, which is most of the deck. Seats cross the wire as a name and
a count.

The multiples are measured, not guessed: playing the first legal card you hold
wins 43/32/27% of the time against these bots, so the tiers price that to lose
about 8% a game and leave good play worth roughly the house's edge.

PeteFX.flyNode is the throw with the chip taken out of it, so a card can be
thrown across the felt the same way. fly() is now that with a chip in it.

Not yet driven in a browser, which in this room means not yet finished.

Claude-Session: https://claude.ai/code/session_013M5nD7PgUboJXoDcYHzpuJ
2026-07-14 07:07:17 -07:00

140 lines
7.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{define "title"}}{{.Room.Name}}{{end}}
{{define "main"}}
<div class="space-y-8">
<section class="rounded-3xl bg-[color:var(--card)] p-6 sm:p-8 shadow-pete border-2 border-[color:var(--ink)]/10">
<div class="flex flex-wrap items-start justify-between gap-4">
<div class="min-w-0">
<h1 class="font-display text-3xl sm:text-4xl font-bold">Welcome in 🎲</h1>
<p class="mt-2 max-w-xl text-[color:var(--ink)]/70">
Real euros, from the same wallet as everything else. Chips are one euro each,
and whatever you don't spend goes straight back when you cash out.
</p>
</div>
<div class="hidden shrink-0 sm:flex items-end gap-1.5" aria-hidden="true">
<span class="cs-stack" data-chip="5"></span>
<span class="cs-stack" data-chip="100" style="--stack:3"></span>
<span class="cs-stack" data-chip="25" style="--stack:2"></span>
</div>
</div>
</section>
{{template "_chipbar" .}}
<section>
<h2 class="font-display text-2xl font-bold mb-4">The tables</h2>
<div class="grid gap-4 sm:grid-cols-2">
<a href="/games/blackjack"
class="group rounded-3xl bg-[color:var(--card)] p-6 shadow-pete border-2 border-[color:var(--ink)]/10 hover:-translate-y-0.5 hover:shadow-pete-lg transition">
<div class="flex items-center gap-3">
<span class="grid h-12 w-12 shrink-0 place-items-center rounded-2xl bg-[color:var(--accent)]/25 text-2xl">🃏</span>
<div class="min-w-0">
<h3 class="font-display text-xl font-bold">Blackjack</h3>
<p class="text-sm text-[color:var(--ink)]/60">Six decks, blackjack pays 3:2.</p>
</div>
<span class="ml-auto shrink-0 rounded-full bg-theme-gaming px-3 py-1 text-xs font-bold uppercase tracking-wider text-white">Open</span>
</div>
<p class="mt-4 text-sm text-[color:var(--ink)]/70">
The dealer stands on 17 and hits a soft one. House takes {{.RakePct}}% of what you win,
and nothing at all when you lose or push.
</p>
</a>
<a href="/games/hangman"
class="group rounded-3xl bg-[color:var(--card)] p-6 shadow-pete border-2 border-[color:var(--ink)]/10 hover:-translate-y-0.5 hover:shadow-pete-lg transition">
<div class="flex items-center gap-3">
<span class="grid h-12 w-12 shrink-0 place-items-center rounded-2xl bg-[color:var(--accent)]/25 text-2xl">🪢</span>
<div class="min-w-0">
<h3 class="font-display text-xl font-bold">Hangman</h3>
<p class="text-sm text-[color:var(--ink)]/60">Guess the phrase, keep the multiple.</p>
</div>
<span class="ml-auto shrink-0 rounded-full bg-theme-gaming px-3 py-1 text-xs font-bold uppercase tracking-wider text-white">Open</span>
</div>
<p class="mt-4 text-sm text-[color:var(--ink)]/70">
Short phrases pay up to 2.6×. You get {{.MaxWrong}} lives, and every wrong guess
takes a tenth off what a win is worth.
</p>
</a>
<a href="/games/solitaire"
class="group rounded-3xl bg-[color:var(--card)] p-6 shadow-pete border-2 border-[color:var(--ink)]/10 hover:-translate-y-0.5 hover:shadow-pete-lg transition">
<div class="flex items-center gap-3">
<span class="grid h-12 w-12 shrink-0 place-items-center rounded-2xl bg-[color:var(--accent)]/25 text-2xl">🂡</span>
<div class="min-w-0">
<h3 class="font-display text-xl font-bold">Solitaire</h3>
<p class="text-sm text-[color:var(--ink)]/60">Buy the deck, win it back a card at a time.</p>
</div>
<span class="ml-auto shrink-0 rounded-full bg-theme-gaming px-3 py-1 text-xs font-bold uppercase tracking-wider text-white">Open</span>
</div>
<p class="mt-4 text-sm text-[color:var(--ink)]/70">
Vegas rules. Your stake buys the deck and doesn't come back — every card you
get home pays a slice of it in. Cash the board whenever you like.
</p>
</a>
<a href="/games/trivia"
class="group rounded-3xl bg-[color:var(--card)] p-6 shadow-pete border-2 border-[color:var(--ink)]/10 hover:-translate-y-0.5 hover:shadow-pete-lg transition">
<div class="flex items-center gap-3">
<span class="grid h-12 w-12 shrink-0 place-items-center rounded-2xl bg-[color:var(--accent)]/25 text-2xl">🧠</span>
<div class="min-w-0">
<h3 class="font-display text-xl font-bold">Trivia</h3>
<p class="text-sm text-[color:var(--ink)]/60">Climb the ladder, or take the money.</p>
</div>
<span class="ml-auto shrink-0 rounded-full bg-theme-gaming px-3 py-1 text-xs font-bold uppercase tracking-wider text-white">Open</span>
</div>
<p class="mt-4 text-sm text-[color:var(--ink)]/70">
{{.Rungs}} questions, and every right answer multiplies what you're holding. A wrong
one loses the lot. Answer fast: the multiple decays as the clock runs.
</p>
</a>
<a href="/games/uno"
class="group rounded-3xl bg-[color:var(--card)] p-6 shadow-pete border-2 border-[color:var(--ink)]/10 hover:-translate-y-0.5 hover:shadow-pete-lg transition">
<div class="flex items-center gap-3">
<span class="grid h-12 w-12 shrink-0 place-items-center rounded-2xl bg-[color:var(--accent)]/25 text-2xl">🎴</span>
<div class="min-w-0">
<h3 class="font-display text-xl font-bold">UNO</h3>
<p class="text-sm text-[color:var(--ink)]/60">Go out first, take the table.</p>
</div>
<span class="ml-auto shrink-0 rounded-full bg-theme-gaming px-3 py-1 text-xs font-bold uppercase tracking-wider text-white">Open</span>
</div>
<p class="mt-4 text-sm text-[color:var(--ink)]/70">
One to three bots, and the more of them there are the more it pays: up to 3.6× for
beating a full table. Anybody else going out first takes your stake.
</p>
</a>
{{range .Soon}}
<div class="rounded-3xl bg-[color:var(--card)]/60 p-6 shadow-pete border-2 border-dashed border-[color:var(--ink)]/15">
<div class="flex items-center gap-3">
<span class="grid h-12 w-12 shrink-0 place-items-center rounded-2xl bg-[color:var(--ink)]/5 text-2xl grayscale">{{.Emoji}}</span>
<div class="min-w-0">
<h3 class="font-display text-xl font-bold text-[color:var(--ink)]/50">{{.Name}}</h3>
<p class="text-sm text-[color:var(--ink)]/40">{{.Blurb}}</p>
</div>
<span class="ml-auto shrink-0 rounded-full border-2 border-[color:var(--ink)]/10 px-3 py-1 text-xs font-bold uppercase tracking-wider text-[color:var(--ink)]/40">Soon</span>
</div>
</div>
{{end}}
</div>
</section>
<section class="rounded-3xl bg-[color:var(--card)] p-6 shadow-pete border-2 border-[color:var(--ink)]/10">
<h2 class="font-display text-xl font-bold mb-2">House rules</h2>
<ul class="space-y-1.5 text-sm text-[color:var(--ink)]/70">
<li>· A chip is a euro. Nothing is worth more here than it is out there.</li>
<li>· You can have {{.Cap}} chips in front of you at most. That's the limit for one sitting.</li>
<li>· The house takes {{.RakePct}}% of your winnings. Never your stake: a push hands your bet straight back.</li>
<li>· Walk away for half an hour and the house cashes you out for you, so your euros never sit in limbo.</li>
<li>· Every hand is logged with the seed it was dealt from, so any hand can be dealt again exactly as it fell.</li>
</ul>
</section>
</div>
{{end}}
{{define "scripts"}}<script src="/static/js/games.js" defer></script>{{end}}