This is an old revision of the document!
Tema este împărțită în 2 etape:
Așa cum se poate observa, ziua deadline-ului variază în funcție de semigrupa în care sunteți repartizați. Restanțierii care refac tema și nu refac laboratorul beneficiază de ultimul deadline (deci vor avea deadline-uri în zilele de 23.05, 30.05).
Rezolvările tuturor etapelor pot fi trimise până în ziua laboratorului 12 (deadline hard pentru toate etapele). Orice exercițiu trimis după un deadline soft se punctează cu jumătate din punctaj. 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 sunt înainte de deadline, nota pe ultima submisie este și nota finală (întrucât n1 = n2).
În fiecare etapă, veți folosi ce ați învățat în săptămâna anterioară pentru a dezvolta aplicația.
Veți implementa în Prolog anumite componente dintr-un joc de Ultimate Tic-Tac-Toe. Vom utiliza aceste reguli. Puteți juca jocul aici. Vom numi jocul de Ultimate Tic Tac Toe “UTTT” și un joc obișnuit de Tic-Tac-Toe (X și 0) “TTT”.
Pe scurt, tabla de UTTT (o vom mai numi și “U-board”) este formată 9 table obișnuite de TTT (numită în cod “board”). O mutare a unui jucător va fi o mutare obișnuită de TTT pe una dintre tablele disponibile pentru mutări (despre asta mai târziu). Câștigarea unei table individuale de TTT reprezintă o mutare (un X sau 0) pe tabla mare de UTTT. Când un jucător câștigă pe tabla mare de UTTT, este câștigător al jocului și jocul se termină. Tablele de TTT și tabla de UTTT se câștigă după regulile obișnuite din X și 0.
Vom identifica tablele individuale, ca și pozițiile din tablele individuale, prin “pozițiile” (în ordinea parcurgerii de la stânga la dreapta și de sus în jos): NW, N, NE, W, C, E, SW, S, SE.
Tabla sau tablele individuale de TTT pe care poate muta un jucător se decid(e) astfel:
În această etapă vom implementa câteva predicate simple care lucrează cu liste. Trebuie implementate construcția și accesul la o stare a jocului și efectuare unei mutări în joc. Pentru bonus, se vor implementa două strategii foarte simple.
Reprezentarea concretă a unei stări este la alegerea fiecăruia. Puteți folosi liste, perechi, sau structuri (compounds).
Vom avea 3 grupuri de predicate (ordinea recomandată de implementare a predicatelor este cea din fișierul sursă):
initialState
construiește reprezentarea stării inițiale a jocului.buildState
construiește reprezentarea unei stări pe baza configurației tablei de joc și pe baza poziției în care a mutat jucătorul anterior.getBoards
, getBoard
, getPos/3
, getPos/4
obțin informații despre tablele de joc individuale. Tablele individuale sunt văzute ca liste de 9 celule, puse în ordinea pozițiilor dată mai sus. Fiecare celulă poate avea ca valoare atomul (literalul) x
, numărul 0
, sau atomul vid ''
.getUBoard
obține configurația tablei de UTTT, văzută ca o tablă individuală. În plus față de tablele individuale, tabla de UTTT poate avea și celule cu valoarea r
, pentru tablele individuale remizate.getNextPlayer
obține jucătorul care urmează la rând (x
sau 0
). Acesta poate fi determinat numărând celulele cu x
și cu 0
din tablele individuale. Primul jucător este x
.getAvailableBoards
obține tablele individuale (ca poziții în tabla de UTTT) disponibile pentru următoarea mutare.getBoardResult
obține rezultatul pentru configurația unei table individuale. Rezultatul poate fi x
, 0
, r
, sau ''
, acesta din urmă pentru cazul în care jocul pe această tablă individuală continuă.(UPos, Pos)
între poziția tablei individuale (în cadrul U-board) unde se va face mutarea, și poziția din tablă unde se va pune x sau 0.validMove
verifică validitatea unei mutări.makeMove
determină starea următoare după efectuarea unei mutări.Pentru BONUS în această etapă se vor implementa două strategii foarte simple:
dummy_first
, care alege întotdeauna prima (în ordinea pozițiilor) mutare disponibilădummy_last
, care alege întotdeauna ultima (în ordinea pozițiilor) mutare disponibilăPe parcursul implementării temei, veți găsi foarte utile predicatele nth0/3 și nth0/4.
Pentru a afișa o stare a jocului, folosiți predicatul printBoards/1
, iar pentru a afișa o tablă individuală folosiți predicatul printBoard/1
. De exemplu, pentru a vizualiza starea inițială (odată ce ați implementat construcția sa), puteți folosi introgarea:
initialState(S), printBoards(S).
Iar pentru a afișa o stare utilizată în teste, puteți folosi, de exemplu (odată ce ați implementat predicatul buildState
:
uttt(2, S), printBoards(S).
Testele sunt disponibile în fișierul checker.pl
, iar jocurile și listele de mutări folosite în teste sunt disponibile în fișierul input.pl
.
uttt.pl
vmcheck.
)detailed_mode_disabled :- !, fail.
din fișierul checker.pl
. Modul detaliat (unde este posibil să primiți câteva puncte în plus cu implementările implicite) nu este cel folosit pe vmchecker, dar în acest mod testerul oferă mai mult detalii despre testele eșuate.