Audamir

časť 22

Skóre, ktoré nevedelo, ako dlho hra trvá

Hra o 199 kôl vyniesla 108 bodov, hra o 6 kôl 121. Záznam jednej partie ukázal, že skóre meralo ťažkosť, nie námahu. Ako sa zmerala dĺžka hier, prečo má ručné rozmiestnenie kociek −41 bodov a čo ostáva otvorené.

· 11 min čítania

Dňa 26. októbra 2026 vznikol záznam jednej partie z voľnej hry (súbor .awr.json, o formáte záznamu je článok o zázname a analýze) a k nemu moja poznámka: hra bola veľmi dlhá a náročná, a pritom iné hry na voľných mapách, kde kocky rozmiestňujem ručne, vyhrávam na strednej mape zhruba za desať ťahov. Kalibrácia a body sa majú zlepšiť.

Záznam sa dá prehrať na dnešnom kóde, takže sa nemusí veriť pocitu: hra mala 199 kôl, 633 útokov hráča, 108 bodov a žiadny bonus. Hra, ktorá sa vyhrá za 6 až 10 kôl, pritom dostane celý bonus za rýchle víťazstvo: 97 × 1,25 = 121 bodov. Ak sa dĺžka hry prepočíta časovým modelom nástroja tools/xp.js (3 + 0,5 × kolá minút), vychádza to na približne 16-krát viac bodov za hodinu za ľahkú hru. Skóre hry zrejme nedokázalo povedať, že dve hry nestoja rovnako veľa času.

Tento článok je záznam toho, ako sa to preverilo, čo sa našlo (a nebolo to to, čo sa čakalo) a čo sa v skóre zmenilo. Je to ten istý druh práce ako v článkoch o prvom ťahu a o kalibrácii: nerozhoduje pocit, hrá AI.

Najprv: nebola to smola

Prvá otázka je vždy tá najlacnejšia: nebola to náhoda? AI úrovne 3 vyhrá presne toto nastavenie (veľká štvorcová mapa, súostrovie, polovica políčok ako posily, najviac 36 kociek na políčku, bonus obrancu 2, štart ako posledný, mlha, traja zmiešaní súperi) s mediánom 183 kôl, 90. percentil je 322 kôl. Hra zo záznamu je teda typická, nie výnimočne zlá.

Dlhé hry nerobí jedno nastavenie, ale súčin troch. Podľa merania z 26. 10. 2026 predlžuje hru:

NastavenieDĺžka hry
reinforce half (posily len na polovicu políčok)×2
maxDice 36 (strop kociek na políčku)×1,7
typ mapy súostrovie (proti AI úrovne 3)×3
move half (presúva sa len polovica kociek)bez zmeny (rovnaké nastavenie so všetkými kockami trvá tiež okolo 190 kôl)

Zaujímavý je posledný riadok. Pri move half sa dalo čakať, že hru predlžuje, a meranie to nepotvrdilo. Skóre mu pritom dávalo 0 bodov oproti 2 bodom pôvodného pravidla, čo je len zvláštnosť, nie chyba.

Skutočný nález: „Rozmiestním ich sám“ je zneužiteľné

Druhá časť poznámky bola o ručnom rozmiestnení kociek. Pravidlo „I place them“ znamená, že nové kocky na konci ťahu hráč rozdelí sám, nie automaticky. Kalibrácia (pozri článok 08) dávala tomuto pravidlu +2 body, teda ho považovala za mierne sťažujúce. To bol na pohľad nesmysel.

Dôvod je v tom, čo robí AI ľudského sedadla. Umelá inteligencia rozdeľuje nové kocky po jednej na políčko, kde šanca na zisk najviac stúpne. Človek robí niečo iné: naleje všetky kocky do najväčšieho stohu na fronte a ten potom prerazí. Merania hrali dvaja AI súperi proti sebe v rovnakých podmienkach, a preto kalibrácia tento rozdiel nikdy nevidela: AI ľudského sedadla rozmiestňovala kocky rovnako ako súperi, takže pravidlo nemalo čo pridať.

Pridala sa preto AI, ktorá stohuje (AI.placeStacked: stoh s najviac kockami medzi políčkami na fronte, pri remíze ten, čo susedí s najslabším nepriateľom; rovnaký plán používa stohovač v AI minihier, podľa DESIGN §12). Výsledky z 26. 10. 2026:

Základné nastavenie, spôsob rozmiestneniaVýhry AIMedián dĺžky
stohuje (placeStacked)99 %6 kôl
rozmiestnenie ako AI35 %10 kôl
náhodné rozmiestnenie34 %34 kôl

A v nastavení zo záznamu: stohujúca AI vyhráva 90 % hier v 28 kolách, náhodné rozmiestnenie 16 % v 248 kolách.

Dôležité je aj to, čo sa tu nemeralo. Súperi v hre rozmiestňujú kocky stále ako AI, a nie ako človek. Pravidlo je teda silné aj preto, že súperi proti nemu nemajú protiťah. To je slabá stránka pravidla a vráti sa v časti o otvorených otázkach.

Čo sa rozhodlo a postavilo

Päť commitov z 26. 10. 2026 (a verzia 0.50.11 po zlúčení) mení tieto veci:

  1. AI ľudského sedadla vie stohovať. Voľba humanPlace: 'stack' v Engine.playGame ho zapne, ale iba v kalibrácii a v kontrole modelu (tools/score-model.js). Samotná hra a všetky ostatné nástroje sa nemenia, takže node tools/baseline.js ostal rovnaký a calibrate.js --verify hlásil „identical“ (podľa pracovných poznámok, pozri zdroje).
  2. Ručné rozmiestnenie má záporné body. Hodnota placement: manual v js/core/score-data.js je −41 (meria sa proti referenčnej hodnote random). AI vyhráva okolo 98 % a miera sa ohraničuje, takže skutočný rozdiel je väčší. Súčet bodov nastavenia nikdy nepadne pod 0; ponuka ukazuje „−41 pts“ pri voľbe a okno pravidiel vysvetľuje prečo.
  3. Meria sa dĺžka hry. Tie isté hry, ktoré merajú šancu na výhru, zapisujú aj medián koncového kola hier, ktoré AI neprehrala (l50). Zároveň sa strop kôl pri meraní zvýšil zo 120 na 400, lebo dlhé nastavenia sa dovtedy orezávali. Každá hodnota nastavenia má teda okrem bodov aj člen dĺžky (logaritmus pomeru očakávaných kôl) a členy sa sčítajú.
  4. Faktor námahy. Skóre voľnej hry a dennej výzvy sa násobí číslom (očakávané kolá nastavenia / kolá predvoleného nastavenia s rovnakými súpermi) ^ 0,6, ohraničeným na 0,25 až 4. Výpočet skóre ukazuje riadok „Dĺžka nastavenia (asi N kôl) ×f“ a ponuka má čip s tým istým číslom. Rýchlostný bonus sa posúva rovnakým pomerom, lebo jeho pôvodná norma poznala len veľkosť mapy a súperov.
  5. Rebríček sa raz prepočíta. Záznam bez príznaku nového vzorca dostane pri načítaní nové body nastavenia a dĺžku (zvyšok pôvodného súčtu, teda nápovedy, výhra na body a rýchle víťazstvo, ostáva v pomere pôvodného súčtu k pôvodnému základu). Kniežatstvá[1] a denná výzva si čísla nechávajú. Skúsenosti a Zlaté kocky, ktoré sa už vyplatili, sa nevracajú ani nepripisujú znova.

Čo skóre po zmene platí:

NastavenieBody nastaveniaOčakávané koláFaktorVýhra platí
predvolené96221,0096
predvolené s ručným rozmiestnením5540,3519
nastavenie zo záznamu1093604,00 (strop; bez neho 5,3)436
to isté s ručným rozmiestnením68641,89129
veľká mapa, polovica políčok, 36 kociek98912,33228

Prečo exponent 0,6 a prečo zvláštnosť Kniežatstiev

Dá sa namietať: ak hra trvá dvakrát dlhšie, má platiť dvakrát viac. Pri exponente 1 by hodina hry platila vždy rovnako. Skóre úmerné dĺžke by ale odmeňovalo aj nastavenie, ktoré je dlhé len preto, že je únavné, a dalo by sa „farmiť“: nastavenie, ktoré sa nikdy neskončí (reinforce fixed má člen +2,48, AI sa zastaví na strope), by platilo bez hraníc. Preto 0,6. Hra dvakrát dlhšia platí ×1,52 (trvá ×1,8 viac minút) a horný strop 4 sa dosiahne pri pomere dĺžok okolo 10. Hodnota 0,6 sa nemerala, je to rozhodnutie. Dá sa ladiť v mods v score-data.js a overí sa node tools/xp.js --check.

Kniežatstvá faktor nemajú. Ich skóre ostáva do bodu rovnaké (volanie Score.finalize(game, { mode: 'classic' }); test porovnáva všetky počty hráčov) a ostávajú aj Zlaté kocky, na ktorých sa merala ekonomika hry. Vzorec sa dotýka len voľnej hry a dennej výzvy. Z rovnakého dôvodu sa norma rýchleho víťazstva už nefituje pri plnom meraní.

Ako dobrý je model

Faktor námahy stojí na modeli dĺžky: očakávané kolá nastavenia sú exp(lenBase + Σ členy). Členy sa merali po jednom nastavení proti základnému, takže model je presný pre základné nastavenie a horší pre každé ďalšie nastavenie zmenené naraz. Overuje ho node tools/score-model.js --configs 120 --games 300: 120 náhodných nastavení, kde si každé bodované nastavenie ponechá predvolenú hodnotu s pravdepodobnosťou 60 %, obaja AI súperi po 300 hier.

sklon (meranie / model)koreláciarozptyl rozdielu
logaritmus kôl0,820,88±12 % kôl pri najviac 3 zmenených nastaveniach, ±45 % pri 4 až 9
logaritmus šance na výhru (body)0,580,78±10 bodov

Body sa sčítavajú horšie ako dĺžky (vždy to tak bolo). Šanca sa ohraničuje na 2 a 98 %, takže nastavenie, ktoré AI vyhrá skoro vždy, má menej ako súčet svojich častí. Najväčšie odchýlky dĺžky: súostrovie sa v zmesi nastavení preceňuje o 49 %, spojenectvo dvoch o 38 %, bonus obrancu 4 a handicap −2 sa podceňujú o približne 40 %. Kontrola --check zlyhá, keď sklon alebo korelácia klesnú pod hranice; zachytí zhoršenie modelu, nepovie, že je presný.

Plné meranie kalibrácie je ťažké: 180 meraní po 2 400 hier trvá asi 45 minút na 16 vláknach (údaj z pracovných poznámok k tejto zmene, nie z dokumentu hry; v dokumentoch je len počet hier).

Pasce

Tri veci stojí za zapamätanie, lebo sa vrátia pri ďalšej zmene skóre:

  • Migračné nástroje porovnávajú profil s dátami starého kódu. Voľná hra a denná výzva sa teraz skórujú novým vzorcom, takže Zlaté kocky, skúsenosti a najlepšie skóre sú iné než v starom kóde a nemajú byť rovnaké. Zmena z 26. 10. 2026 (hra 0.50.8) preto z porovnania vyradila skórové polia hier okrem Kniežatstiev; pre ostatné polia profilu porovnanie platí ďalej. Súvisiaci prístup k testom je v článku o testovaní.
  • Úspechy podľa najlepšieho skóre. Reťaz „Skóre“ zbiera totals.bestScore a jej prahy sú 100, 150, 180 a 210 (js/data/achievement-chains.js). Faktor môže skóre jednej výhry zdvihnúť až štvornásobne, takže dlhé nastavenie by mohlo prahy dosiahnuť jednou výhrou. Z kódu to takto vyplýva; v hre sa to neskúšalo a je to otvorený bod.
  • Aj dobrá zmena mení čísla, ktoré už raz niekto dostal. Preto sa skúsenosti a Zlaté kocky už vyplatené nepreratúvajú. Čo sa v rebríčku mení, je skóre; to, čo hráč z hry vyťažil, ostáva.

Čo je otvorené

  • Súperi nestohujú. Pravidlo, ktoré má −41 bodov, je pravidlo, proti ktorému súperi nič nerobia. Súper, ktorý nalieva kocky do stohu tak ako človek, by z „rozmiestnim ich sám“ urobil skutočnú voľbu. Je to zmena umelej inteligencie, teda nová verzia pravidiel, nový základ merania a plné meranie. Zapísané v pláne (ROADMAP).
  • Model dĺžky má ±45 % pri nastaveniach s veľa zmenami. Cesta k lepšiemu je fit členov na náhodných nastaveniach (ridge regresia smerom k členom meraným po jednom) a členy pre dvojice (súostrovie × veľkosť, rozmiestnenie × posily). Faktor je ohraničený na 4, takže chyba stojí najviac jeden násobok.
  • Časový model pre ručné rozmiestnenie (0,75 minúty na kolo, lebo každá kocka je klik) je odhad, nie meranie.
  • Zámerne sa nezmenilo: body ostatných nastavení (posunuli sa o 1 až 2 body tam, kde strop 400 kôl ukázal dlhšiu hru), prahy hodnotenia 70, 115 a 145 a verzia pravidiel (RULES_VERSION ostáva 2, lebo sa nezmenilo žiadne pravidlo a záznam sa prehráva ako predtým).
  • V hre zatiaľ nemám potvrdené, že nové čísla zodpovedajú môjmu pocitu z dlhých hier. Merania dokazujú, že model sedí na AI súperoch, nie že sedí na ľuďoch.

Čo si z toho odnášam

  • Záznam jednej hry našiel to, čo 2 400 hier na hodnotu nenašlo. Merania boli dôkladné, ale AI hrala tak, ako sa hrať nemá nikto, kto chce vyhrať skratkou. Človek je tu jediný, kto stohuje. Hodnotu, ktorú zmerala len AI, treba aspoň raz porovnať s hrou človeka, a najlepšie sa to dá zo záznamu.
  • Skóre bez času je skóre bez jednotky. Obtiažnosť (aká je šanca na výhru) a námaha (koľko kôl a minút) sú dve veličiny, a kým sa spájali do jednej, jedna z nich sa dala obísť.
  • Záporné body sú čestnejšie ako nula. Pravidlo, ktoré hru zjednodušuje, má byť v ponuke vidieť ako zjednodušenie. „−41“ povie hráčovi viac než „0“ a viac než chýbajúca voľba.
  • Rozhodnutia a merania patria do rôznych stĺpcov. Exponent 0,6 sa nikdy nezmeria; dá sa len zdôvodniť a ladiť. Keď sa to zapíše vedľa seba, nikto si nemyslí, že za ním stojí viac, než stojí.

Zdroje a poznámky

  • Dokumenty hry: docs/DESIGN.md §51 (podnet a rozhodnutia; moja poznámka je v článku prerozprávaná, nie doslovná) a docs/TUNING.md §3.9 (merania, tabuľky, vzorec a model), obe z 26. 10. 2026.
  • Hodnoty v kóde: js/core/score-data.js (−41, člen dĺžky manual −1,73, effortAlpha, effortMin a effortMax v mods).
  • Zmeny: z git log hry (vtedy auda-wars).

Čo sa nepodarilo overiť: nové čísla sa nehrali v hre s hráčom a score-model.js a calibrate.js sa pri písaní nespúšťali (čísla sú z dokumentov a z score-data.js). Výsledok calibrate.js --verify, baseline.js a údaj o 45 minútach merania sú z pracovných poznámok, nie z dokumentov hry. „16-krát viac za hodinu“ je z DESIGN §51.1, nie z nezávislého merania, a časový model ručného rozmiestnenia (0,75 minúty na kolo, §51.3) je odhad. Že dlhé nastavenie dosiahne prahy reťaze Skóre jednou výhrou, je odvodené z kódu a v hre sa to neskúšalo.

Poznámky

  1. Do verzie 0.65.6 z 31. októbra 2026 sa volal Klasik. ↩︎