Salvo · Aliment pentru gândire
Sub simplul gest de a da clic pe celule se află un motor determinist care modelează flote ascunse, raționament ponderat probabilistic și duelul clasic dintre ascundere și descoperire. 3
Scris și editat în limba engleză. Această versiune în română a fost produsă prin traducere automată; acolo unde precizia contează, originalul în engleză este autoritatea. Citiți originalul în engleză →
În inima jocului se află o pereche de obiecte Board, unul reprezentând poziția dumneavoastră ascunsă, iar celălalt poziția ascunsă a adversarului. Fiecare tablă poartă o flotă de nave așezate pe o grilă liniată, dar amplasamentele rămân ascunse față de partea cealaltă. Dumneavoastră trageți în grila inamică, în timp ce AI-ul trage în a dumneavoastră, iar fiecare lovitură fie nimerește o navă, fie cade în apă goală. Această arhitectură cu două table stabilește asimetria informațională fundamentală a duelului flotelor ascunse: fiecare parte își cunoaște complet propria tablă, dar poate deduce configurația celeilalte doar din tiparul loviturilor sale. 3
Simetria acestei configurații este cea care dă jocului caracterul său. Niciuna dintre părți nu vede direct navele celeilalte. În schimb, ambele părți trebuie să-și construiască un model mental al grilei ascunse din feedbackul rar al nimeririlor și ratărilor. Fiecare lovitură devine o informație, fiecare nimerire restrânge posibilitățile, iar fiecare ratare elimină teritoriu din calcul. Coordonatorul de joc al motorului gestionează aceste două table, asigurându-se că loviturile sunt înregistrate, că nimeririle sunt atribuite corect și că jocul se încheie doar atunci când întreaga flotă a uneia dintre părți a fost scufundată. 3
Înainte de începerea jocului, motorul apelează randomFleet pentru a așeza navele AI-ului într-un mod aleatoriu. Această aleatorietate nu este arbitrară; ea pornește de la o sămânță, ceea ce înseamnă că o anumită valoare a sămânței va produce întotdeauna aceeași așezare. Acest determinism bazat pe sămânță este o alegere de proiectare care face jocul reproductibil și testabil. Dacă rulați jocul cu aceeași sămânță, veți obține aceleași plasări ale navelor, aceeași secvență de decizii ale AI-ului și același rezultat. Această proprietate este valoroasă pentru depanare și pentru înțelegerea modului în care se comportă AI-ul în condiții diferite. 3
Odată ce flota este așezată, regulile care guvernează jocul sunt fixe și deterministe. AI-ul nu aruncă zaruri, iar motorul nu introduce aleatorietate în timpul partidei. Fiecare decizie pe care o ia AI-ul decurge din modelul probabilistic pe care îl întreține, iar fiecare lovitură pe care o trageți este înregistrată și analizată. Singura sursă de variație este sămânța care determină plasarea inițială a flotei. Aceasta înseamnă că jocul este, în ultimă instanță, un puzzle: date fiind constrângerile regulilor și feedbackul loviturilor, puteți deduce configurația ascunsă înainte ca AI-ul să o deducă pe a dumneavoastră? 3
Când trageți o lovitură, motorul o înregistrează pe tabla-țintă și verifică dacă lovitura a nimerit sau a ratat. Acest lucru se face prin funcția fire, care actualizează starea tablei și stabilește rezultatul. O nimerire marchează celula ca fiind ocupată de o navă, în timp ce o ratare o marchează ca apă goală. Motorul verifică apoi dacă nava care conține acea celulă a fost scufundată complet, examinându-i toate celulele. Dacă toate celulele unei nave au fost lovite, nava este scufundată, iar această informație este comunicată ambelor părți. 3
Condiția de victorie este simplă, dar cu consecințe. O parte câștigă atunci când toate navele adversarului sunt scufundate. Acest lucru se verifică prin funcția allSunk, care examinează dacă fiecare navă de pe tabla adversarului a fost lovită complet. Jocul se încheie imediat ce această condiție este îndeplinită. Natura de tip totul-sau-nimic a condiției de victorie înseamnă că fiecare lovitură contează și că presiunea de a scufunda navele rapid este contrabalansată de nevoia de a nu vă dezvălui propria configurație. 3
Adversarul din acest joc nu este un simplu trăgător aleatoriu. Este un AI cu țintire probabilistică, care cântărește cât de probabil este ca fiecare celulă ascunsă să conțină o navă. AI-ul întreține un model probabilistic al grilei inamice, actualizându-l pe măsură ce se trag lovituri și se primește feedback. Celulele care nu pot conține nave din cauza constrângerilor de plasare ale navelor rămase sunt marcate ca improbabile, în timp ce celulele care trebuie să conțină nave pentru a permite plasările rămase sunt marcate ca probabile. AI-ul trage apoi în celula cu cea mai mare probabilitate, transformând ghicitul orb într-o căutare informată. 3
Acest model probabilistic se întemeiază pe matematica verosimilității, în care evenimentele sunt descrise prin numere cuprinse între zero și unu 2. O probabilitate de zero înseamnă că un eveniment nu poate avea loc, în timp ce o probabilitate de unu înseamnă că trebuie să aibă loc. AI-ul folosește aceste descrieri numerice pentru a-și ghida loviturile, preferând celulele în care probabilitatea de a găsi o navă este cea mai mare. Această abordare este cea care deosebește AI-ul de un trăgător pur aleatoriu și îi dă comportamentul său caracteristic de vânătoare.
Comportamentul AI-ului poate fi descris în două faze: vânătoarea și țintirea. În faza de vânătoare, AI-ul caută nave trăgând în celulele în care este cel mai probabil să se afle navele nedescoperite. Aceasta este o căutare largă, care urmărește stabilirea primului contact cu navele inamice. Odată înregistrată o nimerire, AI-ul trece în faza de țintire, în care se concentrează asupra celulelor învecinate nimeririi pentru a termina de scufundat acea navă. Această abordare în două faze oglindește felul în care jucătorii umani abordează jocul: mai întâi găsesc navele, apoi le scufundă. 3
Trecerea de la vânătoare la țintire este determinată de faptul că ultima lovitură a fost o nimerire sau o ratare. Dacă ultima lovitură a ratat, AI-ul revine în modul de vânătoare și caută celulele cu cea mai mare probabilitate. Dacă ultima lovitură a nimerit, AI-ul intră în modul de țintire și trage în celulele învecinate nimeririi. Această regulă simplă, combinată cu modelul probabilistic, creează o strategie coerentă, care echilibrează explorarea și exploatarea. AI-ul explorează grila pentru a găsi nave și exploatează informația unei nimeriri pentru a scufunda eficient acea navă. 3
AI-ul are trei niveluri de dificultate care îi reglează comportamentul. Aceste niveluri influențează felul în care AI-ul cântărește probabilitățile și ia decizii. La nivelurile mai joase, AI-ul poate face mai multe greșeli sau poate fi mai puțin agresiv în țintire. La nivelurile mai înalte, AI-ul este mai consecvent în calculele sale probabilistice și mai necruțător în țintire. Această varietate de niveluri le permite jucătorilor să găsească un grad de provocare care li se potrivește, de la joaca relaxată până la competiția serioasă.
Implementarea exactă a acestor niveluri se află în componenta de AI a motorului, clasa SalvoAI. Nivelurile de dificultate modifică felul în care AI-ul interpretează modelul probabilistic și cum echilibrează explorarea cu exploatarea. Această proiectare permite AI-ului să fie deopotrivă accesibil pentru jucătorii ocazionali și provocator pentru cei experimentați, fără a schimba mecanica fundamentală a jocului. 3
Peste regulile clasice se așază o noutate: pingul sonar. Această abilitate permite unei părți să dezvăluie o citire 3×3 a grilei inamice, cu prețul loviturii din acea tură. Pingul sonar dezvăluie dacă fiecare celulă din zona 3×3 conține o navă sau este apă goală. Această informație poate fi neprețuită pentru restrângerea locului în care se află navele, dar vine cu prețul pierderii loviturii pentru acea tură. 3
Decizia de a folosi pingul sonar este una strategică. Când merită informația prețul plătit? Dacă vă chinuiți să găsiți nave, pingul sonar vă poate oferi străpungerea de care aveți nevoie. Dacă sunteți aproape de a scufunda o navă, prețul pierderii loviturii ar putea fi prea mare. Pingul sonar adaugă jocului un strat de gestionare a resurselor, obligându-i pe jucători să cântărească valoarea informației față de valoarea acțiunii. 3
O altă noutate față de regulile clasice este repoziționarea permisă o singură dată pe joc. Fiecare parte își poate muta una dintre propriile nave o dată în cursul partidei. Această eschivă defensivă nu costă o tură, ceea ce înseamnă că puteți repoziționa și totuși trage o lovitură în tura dumneavoastră. Abilitatea de repoziționare vă permite să scoateți o navă din pericol atunci când este amenințată sau să o mutați într-un loc mai ușor de apărat. 3
Abilitatea de repoziționare este o opțiune de unică folosință, ceea ce o face prețioasă. Când ar trebui să o folosiți? Dacă o navă este pe cale să fie scufundată, repoziționarea o poate salva. Dacă aveți încredere în poziția actuală, repoziționarea ar putea fi o risipă. Decizia de a repoziționa este una strategică, ce cere o analiză atentă a stării curente a jocului și a acțiunilor probabile ale adversarului. 3
La baza tuturor acestor mecanici stă regula clasică a unei singure lovituri pe tură. Fiecare parte trage exact o lovitură pe tură, alternând una cu cealaltă. Această regulă stabilește ritmul jocului și asigură ambelor părți șanse egale de a acționa. Regula unei lovituri pe tură este cea care face din joc un duel al minții, nu o cursă de viteză. 3
Această regulă clasică este cea care ancorează jocul în tradiția Bătăliei navale, un joc de ghicire de tip strategic pentru doi jucători, jucat pe grile liniate, în care flota fiecărui jucător este ascunsă față de adversar 1. Regula unei lovituri pe tură este cea care face din joc un test de deducție și probabilitate, nu un test de reflexe. Este o regulă simplă, dar una care dă jocului caracterul și provocarea sa.
Motorul este pur și determinist pe bază de sămânță, condus de propriul său generator de numere aleatoare cu sămânță. Aceasta înseamnă că fiecare aspect al jocului este determinat de valoarea sămânței furnizate la început. Dată fiind aceeași sămânță, jocul va produce întotdeauna aceeași secvență de evenimente, de la plasarea inițială a flotei până la ultima lovitură. Această proprietate face jocul testabil, întrucât același scenariu poate fi reprodus și examinat. 3
Determinismul bazat pe sămânță are implicații și pentru înțelegerea jocului. Dacă doriți să înțelegeți cum se comportă AI-ul într-un anumit scenariu, puteți rula jocul cu o sămânță anume și observa rezultatul. Dacă doriți să testați o anumită strategie, puteți rula jocul de mai multe ori cu aceeași sămânță și vedea cum se descurcă. Această reproductibilitate este o trăsătură valoroasă atât pentru jucători, cât și pentru dezvoltatori.
Board with a hidden fleet, the human fires at the enemy fleet and the AI at the human's, one shot per turn (classic rules), fire records a hit or miss, and a side wins when the opponent's ships are all sunk (allSunk); the opponent is a probability-targeting SalvoAI with three difficulty strengths that "hunts" for ships by favouring the cells where an undiscovered ship is most likely to sit and then "targets" the neighbours of a hit to finish it; two twists sit on the classic rules, a sonar ping reveals a 3×3 ship/empty readout but costs that turn's shot, and each side may reposition one of its own ships once per game (a dodge that does not cost the turn); and the engine is pure and seeded-deterministic.