Table of Contents

Prolog: Jocul Carcassonne

Obiective

Observații preliminare

Tema propune implementarea câtorva mecanisme din mecanica jocului de societate Carcassonne.

Tema este împărțită în 2 etape:

Deadline-ul depinde de semigrupa în care sunteți repartizați. Restanțierii care refac tema și nu refac laboratorul beneficiază de ultimul deadline, și anume în zilele de 19.05, respectiv 26.05.

Rezolvările tuturor etapelor pot fi trimise până în ziua laboratorului 12 (deadline hard pentru toate etapele) (o săptămână după laboratorul 12 pentru seria CB). Orice exercițiu trimis după un deadline soft se punctează la jumătate. Cu alte cuvinte, nota finală pe etapă se calculează conform formulei: n = (n1 + n2) / 2 (n1 = nota obținută înainte de deadline; n2 = nota obținută după deadline). Când toate submisiile preced deadline-ul, nota pe ultima submisie constituie nota finală (întrucât n1 = n2).

În fiecare etapă, veți valorifica ce ați învățat în săptămâna anterioară și veți avea la dispoziție un schelet de cod, cu toate că rezolvarea se bazează în mare măsură pe etapele anterioare. Enunțul caută să ofere o imagine de ansamblu atât la nivel conceptual, cât și în privința aspectelor care se doresc implementate, în timp ce detaliile se găsesc direct în schelet.

Perspectivă generală

Carcassonne (după orașul din sudul Franței) este un joc de societate (boardgame) în care jucătorii își construiesc propriile teritorii, folosind piese pătrate ce conțin pe ele drumuri, cetăți, și pajiști. Jucătorii adună puncte în funcție de cum au plasat piesele și pe ce piese au plasat omuleți. Un joc de Carcassonne în desfășurare arată ca mai jos. Pentru o introducere succintă în esența jocului, vedeți aici - mai ales pasul 1 din partea a 2-a.

În această temă ne vom ocupa în principal de:

Pentru simplitate, în temă vom lucra doar cu o parte din piese față de jocul standard adevărat. Vom lucra cu aceste 16 piese:

Piesa 1: Piesa 1 Piesa 2: Piesa 2 Piesa 3: Piesa 3 Piesa 4: Piesa 4

Piesa 5: Piesa 5 Piesa 6: Piesa 6 Piesa 7: Piesa 7 Piesa 8: Piesa 8

Piesa 9: Piesa 9 Piesa 10: Piesa 10 Piesa 11: Piesa 11 Piesa 12: Piesa 12

Piesa 13: Piesa 13 Piesa 14: Piesa 14 Piesa 15: Piesa 15 Piesa 16: Piesa 16

[imaginile de la https:%%//%%wikicarpedia.com/index.php/Base_game_(1st_edition) ]

Astfel, vom avea următoarele restricții față de jocul adevărat:

Etapa 1

În etapa 1 ne interesează reprezentarea pieselor, rotirea pieselor, și potrivirea unei piese.

Veți lucra numai în fișierul ccs.pl.

Reprezentare

Ne interesează să putem reprezenta cele 16 piese de mai sus. Reprezentarea este la alegerea voastră, ea va fi accesată prin diversele predicate pe care le aveți de implementat. Este doar necesar ca:

  1. fiecare piesă să aibă o reprezentare diferită, și
  2. reprezentarea piesei să nu fie direct derivată din numărul ei;
  3. să puteți reprezenta și fiecare rotație a unei piese, dacă produce o configurație diferită de poziția originală (de exemplu, la piesa 16, toate rotațiile produc aceeași configurație).

Puteți alege ce reprezentare doriți, folosind liste, tupluri, sau alți compuși, acestea putând fi și imbricate, dacă doriți.

Aveți de implementat următoarele predicate în Prolog, documentate și în sursă:

Veți putea testa implementarea predicatelor tile, at, atL și ccw, pe lângă teste, și folosind predicatul printTile din utils.pl. De exemplu, puteți apela interogarea

tile(5, T), printTile(T).

Predicatul printTile produce o reprezentare text a unei piese, folosind simbolul + pentru cetate, linii pentru drumuri, simbolul O pentru intersecții de drumuri, și . pentru colțurile libere ale unei piese.

De exemplu, pentru o implementare corectă până acum, pentru piesa 9, afișarea arată astfel:

.+++.
  +  
-    
 \   
. | .

Piesa 9

Pentru piesa 3:

.++++
  +++
  +++
    +
.   .

Piesa 3

Și pentru piesa 16:

. | .
  |  
--O--
  |  
. | .

Piesa 16

Rotire

Trebuie să putem roti piesele pentru a avea mai multe variante de plasare a lor pe tablă. Rotirea unei piese va produce o reprezentare diferită, ca și cum ar fi o piesă nouă. De exemplu, pentru piesa 2 avem următoarele rotiri în sens trigonometric:

Piesa 2 originală: Piesa 2 Piesa rotită 1 dată: Piesa 2 rot 1

Piesa rotită de 2 ori: Piesa 2 rot 2 Piesa rotită de 3 ori: Piesa 2 rot 3

La rotirea unei piese, reprezentarea trebuie să se schimbe corespunzător. De exemplu, dacă la piesa 2 original aveam drum spre sud și cetate în rest, piesa 2 rotită de 3 ori în sens trigonometric va avea drumul spre vest și va fi afișată ca:

.++++
  +++
- +++
  +++
.++++

Trebuie implementate predicatele:

Potrivire

Pentru ca două piese (eventual rotite) plasate una lângă alta să se potrivească, trebuie ca pe muchia lor comună să aibă aceeași entitate – cetate, drum, sau pajiște. Atunci când o piesă este plasată în joc, trebuie să se potrivească cu toate piesele cu care se învecinează la nord, est, sud, sau vest.

Trebuie implementate predicatele:

Etapa 2

În etapa 2 ne vom concentra pe reprezentarea și lucrul cu o tablă de joc și pe plasarea pieselor în joc. Veți lucra tot în fișierul ccs.pl, unde trebuie să existe deja predicatele din prima etapă.

Jocul Carcassonne începe cu plasarea unei piese undeva pe masă, și apoi cu plasarea altor piese. În afară de prima piesă, orice altă piesă trebuie plasată lângă (având o muchie comună) una sau mai multe piese deja plasate pe masă, și trebuie să se potrivească cu toate piesele vecine deja plasate pe masă. Vedeți acest clip, cu mențiunea că noi ne vom ocupa doar de plasarea pieselor, nu și de plasarea omuleților sau de calculul punctelor.

Reprezentarea tablei

Trebuie să vă construiți o reprezentare pentru starea tablei de joc. Această reprezentare trebuie să conțină piesele aflate pe masă (în reprezentarea construită la etapa 1) și pozițiile lor, în coordonate carteziene.

În predicatele de mai jos, pozițiile vor fi perechi (X, Y). Notați că pozițiile sunt relative la o piesă arbitrară, și putem avea și coordonate negative.

Aveți de implementat predicatele de mai jos, cu observația că trebuie să implementați cel puțin primele 3 predicate pentru a putea testa:

Hint: ca să puteți testa parțial tema, implementați inițial boardSet fără verificarea validității mutării.

Ca să puteți verifica predicatele de mai sus, puteți folosi printBoard/1 din utils.pl, folosind interogări de tipul (vedeți predicatul boardTiles/2 din testing.pl pentru valori de indecși):

boardSetTest(Index, Board), printBoard(Board).

Predicatul printBoard/1 afișează și coordonatele pe margini, cu coordonatele x mai mici în dreapta și cu coordonatele y mai mici în jos. De exemplu, pentru tabla cu indexul 1 în teste – corespunzând cu zona din centru-dreapta în imaginea de mai sus, afișarea este:

  -1    0    1    2       
                         
                         
          .+++.          
            +            
                      1  
            +            
          .+++.          
.   ..   .+++++.   .     
    ++   +++++++         
  +++++++++++++++     0  
  ++++   ++   ++         
.++++.   .. | ..   .     
.+++.     . | .          
  +          \           
-----         -       -1  
                         
.   .     .   .          

Plasarea pieselor

Pentru plasarea corectă a pieselor pe tablă, trebuie implementate predicatele:

Testare

Pentru testare folosiți predicatele check sau vmcheck.

Testele se află în fișierul testing.pl. Tipurile testelor sunt descrise succint la începutul fișierului. Pentru a verifica un test, puteți face interogarea în consolă cu scopurile plasate (de obicei) între ghilimele în primul argument.

Pentru rezultate mai detaliate ale testării, puteți decomenta linia %detailed_mode_disabled :- !, fail. din fișierul testing.pl. Atenție! În acest caz, este posibil ca punctarea să fie diferită decât rezultatul de pe vmchecker, unde linia este comentată.

Resurse

Changelog