Responsabili Proiect

Regulament proiect 2023

Tema proiectului de anul acesta din cadrul materiei Proiectarea Algoritmilor va fi realizarea unui program capabil să joace o versiune de șah, numită Crazyhouse. Această versiune a jocului conține patru modificări față de regulile jocului de șah clasic:

  • o piesă care este capturată își schimbă culoarea și poate fi pusă înapoi pe un loc liber oricând este rândul jucătorului care a capturat-o, în loc de a face o mutare normală.
  • un pion nu poate fi pus înapoi pe rândul 1 sau 8
  • doar un pion pus pe rândul 2 se poate deplasa două pătrățele
  • când o piesă care a promovat este capturată, ea devine pion în mâna adversarului.

Proiectul se va realiza în echipe de câte 2-4 studenți (minim 2, maxim 4 studenți pe echipă) și se va desfășura pe parcursul a 4 etape. Se va folosi platforma XBoard pentru a interfața, vizualiza, înregistra și reda partidele jucate între aplicațiile realizate în cadrul proiectului. Dacă vreți să testați pe Windows, puteți folosi varianta WinBoard, pe care o puteți descărca de aici sau puteți folosi WSL împreună cu un XServer (în secțiunea FAQs există un mic tutorial pentru această opțiune).

In cazuri deosebite acceptam ca proiectul sa fie realizat individual. Pentru asta, va trebui sa trimiteti un mail echipei de proiect in care sa motivati decizia. Nu recomandam acest lucru, avand in vedere ca volumul de lucru este gandit pentru 2-4 studenti!

Reguli de upload: Vom folosi pentru proiect repository-urile din cadrul platformei GitHub Classroom. Căpitanul echipei va trebui să intre pe assignment-ul corespunzător proiectului (https://classroom.github.com/a/HQbmZPA0) și să creeze echipa. Ceilalți membri vor intra ulterior pe același link și se vor înscrie în aceeași echipă. Repository-ul va fi creat automat și va fi privat, singurii care îl vor putea accesa fiind membrii echipei și responsabilii de proiect din echipa de PA. La fiecare etapă (în afară de etapa 0) veți salva în repository-ul vostru o arhivă zip, numită “EtapaX.zip” (unde X reprezintă numărul etapei: e.g. “Etapa1.zip”)

Arhiva va conține:

  • Codul sursă (toate sursele folosite)
  • Makefile
  • README

Pentru notare, toate arhivele vor fi descărcate automat - asigurați-vă că arhiva există în repository, este numită corect și este completă.

Makefile:

Boții vor fi evaluați pe un sistem Linux/GNU pe 64 biți, deci este foarte important să verificați că aveți un makefile care funcționează corect pe Linux, chiar dacă lucrați pe Windows sau MacOS. Scriptul de testare va “make clean”, “make build” pentru compilare, apoi “make run” pentru rulare. Makefile-ul trebuie să se afle în rădăcina arhivei pentru a putea fi rulat. Asigurați-vă că fișierul Makefile nu conține path-uri absolute (să poată fi rulat și pe alt sistem).

La fiecare push în repository, GitHub va verifica automat dacă există o arhivă cu numele corect și dacă cele 3 acțiuni din Makefile pot fi rulate. Puteți ignora erorile înainte de trimiterea finală a arhivei.

Fișierul Readme va respecta următoarea structură:

  • Instrucțiuni de compilare.
  • Detalii despre structura proiectului.
  • Detalii despre abordarea algoritmică a etapei: ce algoritmi ați folosit, cum i-ați combinat, de ce, complexități, etc.
  • Surse de inspirație
  • Responsabilitatea fiecărui membru al echipei.
  • Documentația valorează 10% din punctajul proiectului.

Atenție! Deadline-urile la proiect sunt hard, deci nu se permit întârzieri. Dacă s-a ratat deadline-ul la o etapă, se poate lucra în continuare pentru celelalte etape, dar punctajul se va pierde pentru respectiva etapă.

Etapa 0

Etapa 0 presupune formarea unor echipe de câte 2-4 persoane. Echipele se pot forma între oricare 2-4 studenți din aceeași serie. Studenții restanțieri pot participa cu colegi de la orice serie.

Fiecare echipă va desemna un membru al acesteia cu rolul de căpitan. Căpitanul va avea, printre altele, sarcina de crea echipa pe GitHub Classroom. Ceilalţi membri ai echipei se vor conecta în echipa deja creată.

Pentru înscriere, accesați acest link.

Deadline-ul acestei etape este marți, 28 martie 2023, ora 23:55.

Etapa 1

Se va realiza reprezentarea internă a tablei de joc și a pieselor de joc, precum și o interfațare cu programul XBoard.

Interfațarea va presupune posibilitatea de a interpreta și interacționa cu următoarele comenzi ale XBoard (cele cu steluță * sunt opționale, dar recomandate): xboard, protover N*, feature*, new, force, go, quit, resign, move. Documentația oficială pentru xboard o puțeți găsi aici. Chiar dacă nu aveți nevoie neapărat de tot ce este acolo, recomandarea noastră este să parcurgeți toată pagina. Veți înțelege mai bine cum funcționează XBoard în general.

Interacțiunea cu această aplicație se va face prin intermediul stdin-ului și stdout-ului: Xboard va scrie comenzi/mutări programului vostru la stdin, iar voi îi veți răspunde scriind la stdout. Comenzile menționate mai sus au următoarele roluri și trebuie să vă asigurați că funcționează pentru a primi punctajul aferent acestora:

  • xboard - este comanda de început data de către Xboard programului vostru pentru a-l informa că este conectat la.. xboard.
  • protover N - în ultimele versiuni de Xboard această comandă este dată imediat după comanda “xboard” și anunță engine-ul ce fel de protocol va fi folosit. Mai multe detalii veți putea găsi în documentație, dar, în general, protocolul nu ar trebui să vă înfluențeze, cu o singură observație importantă: Xboard-ul se așteaptă ca voi să răspundeți cu comanda feature (detaliată în cele ce urmează) imediat după ce primiți “protover N”.
  • feature - prin această comandă puteți să îi spuneți Xboard-ului anumite configurări. Aveți aici documentația. Noi vă recomandăm următoarele feature-uri să fie trimise dintre care sigint este cel mai recomandat existând probleme din cauza lui în trecut:
    1. ! sigint - Xboard trimite semnale de întrerupere din diferite motive care vă pot afecta engine-ul. Vă recomandăm să îl dezactivați folosind “sigint=0”.
    2. san - exemplu: “san=0” sau “san=1”. Dacă san este 0 atunci veți primi mutările în formatul “e2e4” care înseamnă că mutarea făcută este “mută piesa care se află pe câmpul e2 la câmpul e4”. Dacă san este 1 atunci veți primi mutările în formatul “Nf3” care se traduce în move Knight to f3. Această ultimă variantă vine cu o un plus de complexitate în cazul în care, de exemplu, există doi cai care pot ajunge pe aceeași căsuță. Recomandarea noastră este să trimiteți “san” de fiecare dată pentru a vă asigura că primiți mutările în formatul dorit de voi și să îl puneți pe 0 pentru ușurință.
    3. name - trimiteți acest feature dacă doriți să vă numiți engine-ul într-un anumit fel.
  • new - reinițializează poziția/partida și setează engine-ul vostru să fie cu negru.
  • force - această comandă vă pune botul “pe pauză” în sensul că el nu va mai gândi și nici nu va mai trimite mutări. Această comandă va fi folosită de către utilizator când vrea “să se joace singur” și să modifice poziția. Xboard-ul vă va spune fiecare mutare făcută pe care voi trebuie să o înregistrați și să o faceți și voi pe tabla voastră. Există posibilitatea ca după “force” să vină comanda “new” (vezi mai sus) sau “go” (vezi mai jos).
  • go - obligă engine-ul vostru să înceapă să gândească și eventual să facă o mutare cu partea care este la mutare în acel moment.
  • quit - xboardul trimite această comandă înainte de a se închide.
  • resign - trimiteți voi această comandă dacă/când vreți să cedați partida.
  • move - trimiteți voi această comandă când vreți să mutați. Formatul o să fie specificat de acel feature “san”. Exemplu: “move e2e4”.

De asemenea, programul va trebui să primească mișcări de la XBoard și să trimită mișcări legale.

Programul vostru va trebui să fie capabil să joace un joc de șah complet. Acest lucru implică interpretarea tuturor mișcărilor legale din jocul de Crazyhouse. Pentru a decide următoarea mutare este suficient să aveți o strategie aleatorie, dar dacă doriți să implementați ceva mai inteligent sunteți invitații noștri.

Modalități de testare:

  • Comanda new (1): botul vostru va primi când se conectează prima dată cu xboard-ul comanda new. După finalizarea primei partide, vom da și noi new game prin “File → New Game”.
  • Comanda go (1): după “new game”, vom da comanda “Mode → Machine White”. În acest moment botul vostru va primi comanda “go” și va trebui să joace cu albul. La fel și aici, pionul trebuie mutat corect.
  • Comanda new (2): new game din nou, nimic spectaculos.
  • Comanda force: imediat după “new game” vom intra în modul editare prin “Mode → Edit Game”. În acest moment botul vostru va primit comanda “force” și trebuie să-și actualizeze poziția în timp ce noi (ca oameni) mutăm atât cu albul cât și cu negru.
  • Comanda go (2): la un moment dat vom da “Mode → Machine _cine_este_la_mutare_”. Atunci botul vostru va primi comanda go și trebuie să mute corect din poziția curentă până la final.

Pentru a face debug și pentru a vedea ce primiți de la xboard/ce trimiteți la xboard puteți rula xboard în modul debug:

> xboard -fcp "make run" -debug

Presupunând că “make run” pornește engine-ul vostru (asta ar și trebui să facă) atunci comanda de mai sus va crea un fișier xboard.debug în care va scrie tot ce se întâmplă. Dacă vreți să aveți un exemplu inițial, puteți juca cu un bot deja existent care vine instalat odată cu xboard prin comanda:

> xboard -fcp "fairymax" -debug

Această etapă va avea 4 săptămâni. Punctajul alocat acestei etape este de 0.6 puncte.

Deadline-ul acestei etape este 30 aprilie 2023, 23:55.

Testare

Testarea se va realiza manual folosind atât funcția “force” (Edit Game), cât și prin joc “normal”. Scenariile pe care va trebui să le implementați și care vor fi și testate sunt următoarele:

  1. Mutări normale de șah - botul vostru trebuie să fie capabil să primească mutări, să-și actualizeze tabla și să răspundă cu o altă mutare. Toate piesele trebuie să știe să efectueze mutări
  2. Șah - în cazul în care primiți șah, botul vostru trebuie să se apere într-un fel și să nu facă mutări invalide
  3. Promovări - un pion care ajunge pe ultima linie trebuie să se poată promova într-un dintre piesele: Damă (Regină), Turn, Cal, Nebun
  4. Rocadă mică + Rocadă Mare
  5. Regulile de imposibilitate pentru efectuarea rocadei https://en.wikipedia.org/wiki/Castling#Requirements:
    • Dacă regele se află în șah, nu se poate efectua rocada
    • Dacă regele a fost mutat înainte de momentul actual, nu se poate efectua rocada
    • Dacă turnul care ar putea fi folosit pentru rocadă a fost mutat înainte de momentul actual, nu se poate efectua rocada
    • Dacă regele trece prin șah, nu se poate efectua rocada
    • Dacă regele ajunge în șah prin rocadă, nu se poate efectua rocada

Pentru a putea testa ultima regulă (cea cu rocada) de mai sus trebuie ca strategia voastră de a muta să aleagă să facă rocada dacă acest lucru este posibil. Dacă ambele rocade sunt disponibile puteți să alegeți pe oricare dintre ele. În rest, mutările voastre pot fi aleatorii.

Ce nu vom testa, dar va fi nevoie de ele pentru etapa următoare vor fi condițiile de terminare a partidei:

  1. repetiție de 3 ori a aceeași poziție cu aceeași culoare la mutare → remiză
  2. 50 de mutări fără captură și fără mutări de pioni → remiză
  3. pat → remiză
  4. mat → victorie

Orice mutare invalidă/regulă care nu este respectată va aduce depunctări în funcție de gravitatea și frecvența cu care ea apare.

Etapa 2

Această etapă este dedicată implementării unor algoritmi avansați pentru a crește calitatea jocului prestat de program. Punctajul pe această etapă poate fi obținut în urma unor meciuri cu boți puși la dispoziție de către noi. Recomandăm implementarea algoritmului alpha-beta și a cel putin două tehnici avansate/euristici pentru a putea calcula cât mai multe mutări în față. Administrarea timpului rămas este o componentă foarte importantă acestei etape.

TODO Această etapă va avea 5 săptămâni. Punctajul alocat acestei etape este de 0.6 puncte.

TODO Deadline-ul acestei etape este 31 mai 2023, ora 23:55.

Testare

Pentru testare ne vom folosi de engine-ul Fairy-Stockfish disponibil aici. Acesta poate fi instalat direct din surse folosind aceste instrucțiuni. Comenzile de mai jos sunt rulate presupunand ca executabilul “stockfish” se află în directorul curent, vor trebui adaptate în funcție de locația executabilului de pe sistemul vostru. În funcție de caz, capabilitățile sale vor fi limitate, folosind opțiunea Skill level cu valorile -20, -10 sau -5. Acest lucru îl va face să joace progresiv mai bine.

Testarea se va face automat într-o mașină virtuală linux cu 1 singur procesor. Comenzile care vor fi rulate pentru testare vor arăta (foarte) asemănător cu comenzile de mai jos. Iar prin “foarte asemănător” înțelegem că această comandă va fi dată xboardului să pornească jocul cu engine-ul vostru, dar mai pot diferi numele fișierului în care se salvează partidele și/sau va fi pusă într-un script.

xboard -variant crazyhouse -fcp ”./stockfish” -firstOptions “Skill Level=-20,Slow Mover=10,Use NNUE=false” -fn “Stockfish Easy” -scp “make run” -tc 5 -inc 2 -autoCallFlag true -mg 4 -sgf partide.txt -reuseSecond false

xboard -variant crazyhouse -fcp ”./stockfish” -firstOptions “Skill Level=-10,Slow Mover=10,Use NNUE=false” -fn “Stockfish Medium” -scp “make run” -tc 5 -inc 2 -autoCallFlag true -mg 4 -sgf partide.txt -reuseSecond false

xboard -variant crazyhouse -fcp ”./stockfish” -firstOptions “Skill Level=-5,Slow Mover=10,Use NNUE=false” -fn “Stockfish Hard” -scp “make run” -tc 5 -inc 2 -autoCallFlag true -mg 4 -sgf partide.txt -reuseSecond false

Explicarea parametrilor:

  • xboard - aplicația pe care o folosim :-D poate fi atât xboard cât și winboard, dar checkerul va rula pe linux deci vom folosi xboard.
  • -scp “make run” - setează al doilea engine ca fiind engine-ul vostru. Vă reamintim că “make run” ar trebui doar să vă pornească engine-ul, nu și xboard-ul.
  • -tc 5 -inc 2 - setează timpul de joc la 5 minute (timpul de start pentru fiecare jucător), iar la fiecare mutare jucătorul care a efectuat-o va primi încă 2 secunde. Observație: Este indicată gestionarea timpului (dar nu obligatoriu). Acest timp, împreună cu următorul parametru(-autoCallFlag true) previne situația în care voi ați da un depth prea mare engine-ului vostru și acesta ar sta foarte mult să se gândească și situația în care engine-ul vostru intră într-o buclă infinită și nu mai mută.
  • -autoCallFlag true - setează xboard-ul ca atunci când i se termină timpul unuia din jucători să atribuie victoria celuilalt.
  • -mg 4 - numărul de partide jucate va fi 4 pentru teste. Automat se vor juca 2 cu albul și 2 cu negru. Voi puteți modifica parametrul sau chiar să îl scoateți pentru teste mai mici.
  • -sgf partide.txt - în acest fișier se vor salva partidele jucate.
  • -reuseSecond false - acest parametru îi specifică lui xboard să reîncarce engine-ul vostru după fiecare partidă. Dacă nu este prezent se va da “new game”. Puteți să-l vedeți ca pe o plasă de siguranță: dacă cumva engine-ul vostru se “strică” în timpul unei partide, el se va reseta la următoarea deci teoretic eroarea nu se va propaga.

Punctare

Punctajul de 0.6 puncte se va acorda în felul următor:

  • 0.2 puncte obținerea a 2 puncte (orice combinație de remize + victorii) din 4 partide vs Stockfish Easy
  • 0.2 puncte obținerea a 2 puncte (orice combinație de remize + victorii) din 4 partide vs Stockfish Medium
  • 0.2 puncte obținerea a 2 puncte (orice combinație de remize + victorii) din 4 partide vs Stockfish Hard

Punctele se vor acorda după următoarea formulă:

punctaj_etapă = min(0.2, 0.2 * (număr_puncte_din_meci_vs_easy / 2)) +
                min(0.2, 0.2 * (număr_puncte_din_meci_vs_medium / 2)) +
                min(0.2, 0.2 * (număr_puncte_din_meci_vs_hard / 2))

Turneu

În cadrul turneului se realizeaza un concurs între proiectele realizate, actualizat permanent. Punctajul aferent acestei etape este de 0.8 puncte și se va acorda după următorul algoritm:

  • Locul 1 va primi 0.8 puncte
  • Locul 2 va primi 0.7 puncte
  • Locul 3 va primi 0.6 puncte
  • Restul proiectelor vor primi în funcție de locul în clasament între 0 și 0.55 puncte, marja între două proiecte consecutive fiind de 0.55/(numar_proiecte_finaliste-3)

FAQs

De ce șah?

Didactic, este o idee de proiect bună din mai multe puncte de vedere (provocări de implementare, înțelegerea unor concepte de algoritmi avansați, provocări de time management, abilitatea de autodocumentare, abilitatea de a lucra în echipă, etc). Șahul a fost ales datorită rezonanței sale ca joc. Din experientă vă spunem că un motor de șah decent făcut dă bine la un interviu.

De ce Xboard? Nu pierdem timp stând să implementam nu știu ce protocol în loc să implementam algoritmi?

Winboard/Xboard a devenit un program standard de interfațare între diferitele motoare existente în momentul de față. Fiecare motor minimalist existent știe să lucreze cu acest program. Ușurarea lucrului de mediere a unui joc justifică implementarea sa, precum și faptul că proiectul realizat va putea juca cu orice alt motor cât de cât performant de pe net. Cât despre timpul pierdut, interfațarea minimalistă cerută in etapa 1 se poate realiza în aproximativ o oră. La ce chestii vor fi de implementat la protocoale de comunicații, asta vi se va părea floare la ureche :-).

Nu exista deja o droaie de algoritmi pe net despre sah? Dar proiectele din anii precedenți?

Da, exista multe surse de documentație pe net despre cum să implementezi un joc de șah. Dar de la vorbe la fapte e cale lungă. Doar pentru că există mulți algoritmi nu inseamnă că oricine va ști să-i implementeze și să o facă și bine. Implementarea corectă și eficientă presupune mai mult decât copy paste de pe net. Cât despre proiectele de anii trecuți, ele există in posesia echipei de PA, și cele de anul acesta vor fi verificate contra celor precedente pentru a nu avea cazuri de fraudă. De asemenea, tipul de șah “crazyhouse” este diferit de șahul normal astfel că un engine care joacă șah normal va pierde destul de sigur împotriva unuia specializat. Dacă se constată o tentativă de fraudă din partea oricărei echipe, toți membrii echipei vor avea restanță la Proiectarea Algoritmilor și vor pierde punctajul aferent proiectului.

Cum imi aleg coechipierii?

Cum vrei, pe baza oricăror criterii crezi tu că sunt importante.

Nu toți membrii echipei lucrează la fel de mult. What’s up with that?

Din experiența anilor trecuți, niciodată nu se intamplă ca toți membrii echipei să lucreze la fel de mult. Acest fapt se intamplă din varii motive: fie nu toți pot, fie unul sau doi acaparează toata munca și nu le dau celorlalți o șansă (nu râdeți, s-a intamplat :P), fie <insert another reason here>. Fiecare echipă va avea un căpitan care va avea, printre altele, datoria de a comunica echipei de PA (asistentului de laborator, titularului de curs etc) orice neregulă din cadrul propriei echipe. In afară de asta și de a vorbi puțin individual cu membrii fiecarei echipe nu există altă soluție. Depinde de prioritățile fiecărui membru de echipă și a echipei per ansamblu.

In ce limbaj de programare avem voie sa realizam proiectul?

In oricare limbaj de programare cu care vă înțelegeți mai bine, atât timp cât va putea rula pe linux. De remarcat este faptul că pentru acest proiect timpul de execuție este critic.

Avem voie sa folosim fire de executie (thread-uri) in program?

Nu. S-a pus problema și în alți ani. Motivul este că nu toți știu să lucreze cu thread-uri, iar un astfel de avantaj ar fi incorect față de ceilalți. NU postați în legătură cu asta pe forum…it’s final and that’s that.

Avem voie să folosim baze de date pentru deschidere sau alte scopuri?

Da, atât timp cât toata arhiva este până în 5Mb.

Putem comunica cu un calculator la distanță prin TCP/IP sau alte mijloace pentru a avea acces la o bază de date suplimentară sau alte resurse?

Categoric NU. Proiectul trebuie să fie stand-alone. Nu se admit conexiuni de genul celor menționate mai sus.

Putem trimite programe executabile?

Nu. Doar cod sursă (și eventuale adiționale precum opening data bases). Codul se va compila și link-edita dupa regulile prezente în makefile-ul, ant file-ul, script-ul etc-ul vostru de build.

Unde putem cere lamuriri suplimentare in legatura cu desfasurarea proiectului?

Pe forum-ul dedicat proiectului de pe pagina web a cursului de PA.

Vreau să folosesc Xboard împreună cu WSL. Cum pot face asta?

Pentru început este nevoie de un X server care e capabil să ruleze aplicațiile grafice din Linux. O varintă ar fi să instalați Xming X server (Xming sourceforge). Aveți aici un tutorial. Pe scurt:

  1. instalați Xming
  2. porniți Xming (căutați în programele voastre XLaunch) și pentru a-l configura puteți păstra totul la valorile predefinite mai puțin la partea de parametrii adiționali. Acolo va trebui să adăugați -ac în câmpul “Additional parameters for Xming”. vezi exemplu aici
  3. mergeți într-un terminal de WSL și rulați o comandă precum
    > DISPLAY=:0 xboard

    În urma acestori pași, dacă și xboardul este instalat ar trebui să vă apară tabla din cadrul aplicației xboard. Dacă acest lucru nu merge și primiți o eroare de genul “cannot open display :0” atunci rulați următoarea comandă care ar trebui să rezolve problema:

    > export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0 ; xboard

Schelet de cod

Last update: 27/4/23 1:20 (protocol hotfix in Main.java/Main.cpp + Java Makefile)

Aveți aici schelete de cod pentru limbajele C++ și Java. Implementarea voastră se va realiza în fișierele Bot.cpp sau Bot.java, după caz. In cadrul clasei Bot, vă veți declara câmpuri private (spre exemplu tabla de șah), pe care le puteți stoca în orice structuri doriți. Inițializarea acestora o veți face în constructorul clasei. Acestea vor putea fi accesate de către voi în cele două metode ce le veți implementa:

  • recordMove(), care va fi apelată de fiecare dată când Engine-ul primește o mutare. Aceasta poate fi de la adversar (în modul normal de joc), sau de la oricare din cei doi jucători (In “Force mode”, unde xboard vă “dictează” mutări). Va trebui să memorati mutarea, actualizând câmpurile declarate de voi ce se ocupă cu stocarea stării jocului (configurația tăblii, etc.).
  • calculateNextMove(), ce va calcula și va întoarce mutarea pe care botul vostru o va efectua. Mutările se pot crea prin cele patru metode expuse în Move.h/Move.java, și anume: moveTo(), pentru o mutare obișnuită/rocadă, promote(), utilizata atunci cand mutați un pion în prima linie a adversarului pentru a obține o altă piesă în locul lui, dropIn(), pentru a plasa pe tablă o piesă capturată de către voi (mutare specifică Crazyhouse), și resign(). Pentru detalii despre apelarea/utilizarea acestora, vedeti comentariile din cod. Pozitiile sursă si destinație ce vor fi date ca parametru sunt string-uri (String sau std::string), din doua caractere, in “coordinate notation”, cum ar fi: “e4”, “d2”, “h2”, etc.
pa/regulament-proiect-2023.txt · Last modified: 2023/05/29 22:36 by stefan.ruseti
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0