Čtyři kritické body, které mi u kanasty daly nejvíc zabrat, a které
by se daly použít i v jiných real-time herních systémech.
1. Zamrzlý balík a vícekrokové vykládání
Problém: Kanasta povolí vzít celý odhazovací
balík, pokud z něj umíš vyložit slohu s pomocí vrchní karty.
Když je balík zamrzlý, hráč musí mít v ruce 2 přirozené karty
stejné hodnoty jako vrchní karta. A pak z převzatého balíku
často skládá víc sloh najednou.
Řešení: takeDiscardPileWithMelds()
přijme víc sloh naráz a všechny ověří před tím, než
něco změní. Kontroluje, že má hráč karty v ruce, každá
sloha je legální, sedí požadavek zamrzlého balíku a první sloha
týmu má dost bodů. Buď projdou všechny kontroly, nebo se nic
nezmění.
2. Minimum bodů pro první slohu podle týmového skóre
Problém: Bodový práh pro první slohu závisí
na aktuálním skóre týmu: záporné skóre → 15 b., do 1 500 →
50 b., do 3 000 → 90 b., do 5 000 → 120 b., nad 5 000 →
150 b. Nelze mít fixní hodnotu.
Řešení: Práh se počítá pokaždé znovu
z aktuálního skóre týmu. Volá se všude, kde tým může vyložit
první slohu, i při každé aktualizaci UI pro hráče.
3. Privátní stav pro každého hráče přes Socket.io
Problém: Server posílá plný stav, ale klient
nemá vidět ruce soupeřů.
Řešení: getStateForPlayer(playerId)
projde stav před každým odesláním klientovi a zamaskuje cizí ruce, místo karet posílá jen jejich počet.
4. Validace ukončení kola a bodování
Problém: Hráč může ukončit kolo jen pokud jeho
tým má alespoň jednu kanastu. Bodování musí spočítat body za
slohy, odečíst penalizaci za karty v ruce, přičíst bonusy za
červené trojky a kanasty, a rozhodnout o konci hry při 10 000.
Řešení: calculateRoundScores(goOutTeam)
v jednom průchodu spočítá body pro oba týmy naráz.
Klíčová nuance: pokud tým nemá kanastu, jeho slohy se počítají
jako záporné body (a bonus 800 za všechny 4
červené trojky se stane penalizací -800). Tým skončí kolo
v mínusu i s kartami na stole. Až pak porovnání s 10 000
a rozhodnutí o konci hry nebo pokračování dalším kolem.