This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
laboratoare:old-exercises [2019/12/02 16:04] Adriana Draghici |
laboratoare:old-exercises [2020/01/04 12:19] (current) Adriana Draghici [Singleton, Observer, Factory] |
||
---|---|---|---|
Line 291: | Line 291: | ||
== Design Patterns == | == Design Patterns == | ||
- | === Singleton, Observer, Strategy === | + | === Singleton, Observer, Factory === |
- | Acest laborator și [[laboratoare:design-patterns2|următorul]] au ca temă comună a exercițiilor realizarea unui joc controlat din consolă. Jocul constă dintr-o lume (aka hartă) în care se plimbă eroi de trei tipuri, colectează comori și se bat cu monștri. În acestă săptămână trebuie să implementați o parte din funcționalitățile jocului folosind patternurile //Singleton//, //Factory// și //Observer//, urmând ca la laboratorul următor să terminați implementarea folosind pattern-urile studiate atunci. | + | Exercițiile din această secțiune și din urmatoarea au ca temă comună realizarea unui joc controlat din consolă. Jocul constă dintr-o lume (aka hartă) în care se plimbă eroi de trei tipuri, colectează comori și se bat cu monștri. În acestă secțiune trebuie să implementați o parte din funcționalitățile jocului folosind patternurile //Singleton//, //Factory// și //Observer//, urmând ca în secțiunea următoare să terminați implementarea. |
+ | |||
+ | Schelet: {{.:design-patterns:design-patterns1-skel.zip|Schelet}} | ||
Detalii joc: | Detalii joc: | ||
* //Harta// | * //Harta// | ||
- | * reprezentată printr-o matrice. Fiecare element din matrice reprezintă o zonă care poate fi liberă, poate conține obstacole sau poate conține o comoară (în laboratorul următor poate conține și monștrii). | + | * reprezentată printr-o matrice. Fiecare element din matrice reprezintă o zonă care poate fi liberă, poate conține obstacole sau poate conține o comoară (în secțiunea următoare poate conține și monștrii). |
* este menținută în clasa ''World''. | * este menținută în clasa ''World''. | ||
* //Eroii// | * //Eroii// | ||
Line 328: | Line 330: | ||
- Notificați observatorii lui ''World'' când eroii execută o acțiune. Aveți două ''TODO''-uri în clasa ''Hero''. | - Notificați observatorii lui ''World'' când eroii execută o acțiune. Aveți două ''TODO''-uri în clasa ''Hero''. | ||
* Începeți rezolvarea prin implementarea claselor pentru eroi și implementarea design pattern-ului factory pentru crearea lor. Pentru a putea vizualiza harta trebuie să implementați partea de observare a stării jocului. ''World'' trebuie să fie observabilă și să notifice pe observatorii săi atunci când a început jocul și când se schimbă ceva (e.g. s-a mutat un erou). | * Începeți rezolvarea prin implementarea claselor pentru eroi și implementarea design pattern-ului factory pentru crearea lor. Pentru a putea vizualiza harta trebuie să implementați partea de observare a stării jocului. ''World'' trebuie să fie observabilă și să notifice pe observatorii săi atunci când a început jocul și când se schimbă ceva (e.g. s-a mutat un erou). | ||
- | * Urmăriți todo-urile din scheletul de cod (pentru a le vizualiza mai ușor pe toate puteți să folosiți view-ul pt ele din IDE, de exemplu în eclipse aveți //Window -> Show View -> Tasks//) | + | * Urmăriți **todo**-urile din scheletul de cod (pentru a le vizualiza mai ușor pe toate puteți să folosiți view-ul pt ele din IDE, de exemplu în eclipse aveți //Window -> Show View -> Tasks//) |
<imgcaption exercitii|> | <imgcaption exercitii|> | ||
{{:laboratoare:design-patterns:exercitiu.png|Componentele jocului}}</imgcaption> | {{:laboratoare:design-patterns:exercitiu.png|Componentele jocului}}</imgcaption> | ||
+ | === Strategy, Command === | ||
+ | Această secțiune și cea precedentă au ca temă comună a exercițiilor realizarea unui joc controlat din consolă. Jocul constă dintr-o lume (aka hartă) în care se plimbă eroi de trei tipuri, colectează comori și se bat cu monștrii. În acestă secțiune terminam jocul inceput in cea precedenă folosind pattern-urile //Strategy// și //Command//. | ||
+ | Detalii joc: | ||
+ | * //Harta// | ||
+ | * reprezentată printr-o matrice. Fiecare element din matrice reprezintă o zonă care poate fi liberă, poate conține obstacole, monștrii sau o comoară | ||
+ | * este menținută în clasa ''GameState''. | ||
+ | * //Eroii// | ||
+ | * sunt reprezentați prin clase de tip ''Hero'' și sunt de trei tipuri: //Mage//, //Warrior//, //Priest//. | ||
+ | * puteți adăuga oricâți eroi doriți pe hartă (cât vă permite memoria :)) | ||
+ | * într-o zonă pot fi mai mulți eroi | ||
+ | * acțiunile pe care le pot face: | ||
+ | * ''move'' - se mută într-o zonă învecinată | ||
+ | * ''attack'' - ataca un monstru cand se afla pe aceeasi pozitie cu el | ||
+ | * ''collect'' - eroul ia comoara găsită în zona în care se află | ||
+ | * Entry-point-ul în joc îl consitituie clasa ''Main''. | ||
+ | * Folosiți design pattern-ul //Command// pentru a implementa functionalitatea de undo si redo la comanda ''move''. | ||
+ | * Momentan, aveti erori de compilare in clasele Main si GameState. Dupa ce veti implementa acest exercitiu, se vor rezolva, nu modificati in mod direct acolo. | ||
+ | * Va trebui sa completati clasa ''MoveCommand'' care implementeaza interfata ''Command''. Urmariti //TODO-urile// din aceasta clasa. | ||
+ | * //__Hint__//: Pentru Undo, de exemplu, daca v-ati deplasat la dreapta, ar trebui sa va deplasati la stanga. Creati-va o metoda ajutatoare care trateaza astfel de cazuri. | ||
+ | * Precum si clasa ''CommandManager'' care va tine evidenta comenzilor si ordinea lor. | ||
+ | * //__Hint__//: Amintiti-va de la cursul de Structuri de Date cum se implementează operatiile Redo si Undo. Folositi doua stive. | ||
+ | * Folosiți design pattern-ul //Strategy// pentru a implementa logica de atac a unui monstru. | ||
+ | * Pentru acest exercitiu va trebui sa implementati 2 strategii: **AttackStrategy** si **DefenseStrategy**. Ambele vor implementa Strategy si metodele aferente. Fiecare din aceste Strategy, va retine o referinta interna la un Hero. Abordarea este urmatoarea: | ||
+ | * Exista 3 clase Hero, fiecare cu cate un DamageType aferent: Warrior - Blunt, Mage - Magic, Priest - Poison | ||
+ | * Fiecare monstru are un weakness (slabiciune la atacurile de tip Blunt, Magic sau Poison) | ||
+ | * **AttackStrategy**: In metoda attack(), veti itera prin inventory-ul eroului si veti verifica daca exista un obiect Treasure care are DamageType-ul identic cu cel al eroului. Daca da, atunci damage-ul pe care il veti da unui obiect Monster este **3 x damage-ul treasure-ului**. Daca nu aveti un astfel de Treasure, atunci cautati un Treasure cu un DamageType identic cu cel al mob-ului (mobul poate fi vulnerabil la Magic, de ex.). Daca gasiti un astfel de Treasure, damage-ul pe care il veti imprima mob-ului este **2 x damage-ul treasure-ului**. Daca nu, veti scade din HP-ul mob-ului rezultatul apelului metodei getBaseDamage() asupra Hero-ului. | ||
+ | * **DefenseStrategy**: In metoda attack(), veti itera prin inventory-ul eroului si veti verifica, la fel, daca exista un obiect Treasure care are DamageType-ul identic cu cel al eroului. Daca da, atunci veti da un boost de HP egal cu treasure.getBoostHp() + getBaseHpBoost() eroului (getBaseHpBoost este implementata in clasa Hero). Daca nu, veti da doar un boost egal cu ce va intoarce getBaseHpBoost(). Damage-ul imprimat mobului va fi, de asemenea, egal cu ce va intoarce getBaseDamage(). Adaugati log-uri in clasa DefenseStrategy, pentru a va asigura ca i se mareste viata eroului. | ||
+ | * Urmariti si TODO-urile din cele doua clase | ||
+ | * Implementati metoda //attack// din clasa **Hero** astfel incat, daca eroul are mai mult de **50HP**, folositi strategia **AttackStrategy**. Altfel, folositi **DefenseStrategy**. Urmariti TODO-urile din cod. | ||
+ | * Implementați coliziunile cu obstacolele de pe hartă | ||
+ | * Va trebui sa creati un nou obiect ''Obstacle'' precum si un ''ObstacleObserver'' | ||
+ | * Cand eroul ajunge pe un obstacol se va printa un mesaj ''Can't move there !'' si se va apela automat undo pe ultima comanda de move pentru a reveni in pozitia anterioara coliziunii. Acest feature de wall collision va fi implementat in ''ObstacleObserver'' |