This shows you the differences between two versions of the page.
poo-ca-cd:laboratoare:old-exercises [2020/08/18 22:45] florin.mihalache [Visitor pattern, Overriding, Overloading] |
poo-ca-cd:laboratoare:old-exercises [2020/12/09 16:24] (current) adriana.draghici [Design Patterns] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Exerciții ===== | + | ===== Exerciții vechi ===== |
Această pagină cuprinde exerciții care au fost taskuri de laborator și acum înlocuite cu altele. | Această pagină cuprinde exerciții care au fost taskuri de laborator și acum înlocuite cu altele. | ||
Line 142: | Line 142: | ||
* În clasa **BashUtils** din pachetul **bash** vom implementa fiecare comandă ca o clasă internă. | * În clasa **BashUtils** din pachetul **bash** vom implementa fiecare comandă ca o clasă internă. | ||
* În clasa **Bash** din pachetul **bash** vom citi comenzi de la tastatură și le vom trimite spre **BashUtils** spre a fi executate. | * În clasa **Bash** din pachetul **bash** vom citi comenzi de la tastatură și le vom trimite spre **BashUtils** spre a fi executate. | ||
- | * Mecanismul de funcționare va fi de tipul [[:poo-ca-cd: https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern | Publisher-Subscriber ]]. | + | * Mecanismul de funcționare va fi de tipul [[https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern | Publisher-Subscriber ]]. |
{{ :poo-ca-cd:laboratoare:clase-interne:publish_subscribe.gif ? | Publisher-Subscriber }} | {{ :poo-ca-cd:laboratoare:clase-interne:publish_subscribe.gif ? | Publisher-Subscriber }} | ||
Line 167: | Line 167: | ||
| | ||
2. **(1p)** Un obiect de tipul **Bash** va avea: | 2. **(1p)** Un obiect de tipul **Bash** va avea: | ||
- | * un director current reținut în membrul **currentDirectory** care este de tipul [[:poo-ca-cd: https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html | Path ]] | + | * un director current reținut în membrul **currentDirectory** care este de tipul [[https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html | Path ]] |
- | * un istoric al comenzilor care este de tipul [[:poo-ca-cd: https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html | StringBuffer ]] . | + | * un istoric al comenzilor care este de tipul [[https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html | StringBuffer ]] . |
<note> De ce este mai util să folosim un StringBuffer și nu un String simplu? | <note> De ce este mai util să folosim un StringBuffer și nu un String simplu? | ||
- | [[:poo-ca-cd: http://www.javaworld.com/article/2076072/build-ci-sdlc/stringbuffer-versus-string.html | Sting vs StringBuffer ]]? | + | [[http://www.javaworld.com/article/2076072/build-ci-sdlc/stringbuffer-versus-string.html | String vs StringBuffer ]]? |
</note> | </note> | ||
- | * În constructorul clasei **Bash** vom inițializa **history** și apoi **currentDirectory** cu calea către directorul curent ".". Hint: [[:poo-ca-cd: https://docs.oracle.com/javase/tutorial/essential/io/pathOps.html | Paths.get ]] | + | * În constructorul clasei **Bash** vom inițializa **history** și apoi **currentDirectory** cu calea către directorul curent ".". Hint: [[https://docs.oracle.com/javase/tutorial/essential/io/pathOps.html | Paths.get ]] |
* Instantiati și obiectul de tip **CommandPublisher** definit la exercițiul anterior. Prin intermediul lui vom publica comenzi din **Bash** în sistem. | * Instantiati și obiectul de tip **CommandPublisher** definit la exercițiul anterior. Prin intermediul lui vom publica comenzi din **Bash** în sistem. | ||
| | ||
Line 204: | Line 204: | ||
* Metoda **executeCommand** va trebui să: | * Metoda **executeCommand** va trebui să: | ||
* verifice dacă comanda primită începe cu "cd". | * verifice dacă comanda primită începe cu "cd". | ||
- | * să schimbe variabila **currentDirectory** cu noua cale. Funcția **cd** va face **append** la calea deja existentă în **currentDirectory**. Hint: [[:poo-ca-cd: https://docs.oracle.com/javase/tutorial/essential/io/pathOps.html | Paths.get ]] | + | * să schimbe variabila **currentDirectory** cu noua cale. Funcția **cd** va face **append** la calea deja existentă în **currentDirectory**. Hint: [[https://docs.oracle.com/javase/tutorial/essential/io/pathOps.html | Paths.get ]] |
* Creați un obiect de tipul clasei **Cd** în constructorul clasei **Bash**. Înregistrați obiectul ca **subscriber** la instanța de **CommandPublisher** folosind metoda **subscribe**. | * Creați un obiect de tipul clasei **Cd** în constructorul clasei **Bash**. Înregistrați obiectul ca **subscriber** la instanța de **CommandPublisher** folosind metoda **subscribe**. | ||
* Testați rulând metoda **main** din clasa **LinuxOS**. | * Testați rulând metoda **main** din clasa **LinuxOS**. | ||
Line 212: | Line 212: | ||
* Metoda **executeCommand** va trebui să: | * Metoda **executeCommand** va trebui să: | ||
* verifice dacă comanda primită este "ls" fără parametrii. | * verifice dacă comanda primită este "ls" fără parametrii. | ||
- | * să itereze prin conținutul directorului curent și să afișeze numele fișierelor la consolă, pe câte o linie fiecare. Hint: [[:poo-ca-cd: http://stackoverflow.com/questions/1844688/read-all-files-in-a-folder | cum citim conținutul unui director în Java? ]] | + | * să itereze prin conținutul directorului curent și să afișeze numele fișierelor la consolă, pe câte o linie fiecare. Hint: [[http://stackoverflow.com/questions/1844688/read-all-files-in-a-folder | cum citim conținutul unui director în Java? ]] |
* **currentDirectory** are tipul **Path**. Putem obține un obiect de tip **File** astfel: | * **currentDirectory** are tipul **Path**. Putem obține un obiect de tip **File** astfel: | ||
<code java>File folder = currentDirectory.toFile();</code> | <code java>File folder = currentDirectory.toFile();</code> | ||
Line 294: | Line 294: | ||
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. | 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}} | + | Schelet: {{:poo-ca-cd:laboratoare:design-patterns:design-patterns1-skel.zip|Schelet}} |
+ | |||
+ | Solutie: {{:poo-ca-cd:laboratoare:old-exercises:design_patterns_2018_sol.zip|Solutie}} | ||
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 secțiunea următoare 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// |
- | * sunt reprezentați prin clase de tip ''Hero'' și sunt de trei tipuri: //Mage//, //Warrior//, //Priest//. | + | * 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 :)) | + | * 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 | + | * într-o zonă pot fi mai mulți eroi |
- | * acțiunile pe care le pot face: | + | * acțiunile pe care le pot face: |
- | * ''move'' - se mută într-o zonă învecinată | + | * ''move'' - se mută într-o zonă învecinată |
- | * ''attack'' (de implementat în laboratorul următor) | + | * ''attack'' (de implementat în laboratorul următor) |
- | * ''collect'' - eroul ia comoara găsită în zona în care se află | + | * ''collect'' - eroul ia comoara găsită în zona în care se află |
- | * Entry-point-ul în joc îl consitituie clasa ''Main''. | + | * Entry-point-ul în joc îl consitituie clasa ''Main''. |
- | * Folosiți design pattern-ul //Factory// pentru crearea obiectelor. | + | * Folosiți design pattern-ul //Factory// pentru crearea obiectelor. |
- | - Creati clase care mostenesc ''Hero'' pentru fiecare tip de erou. | + | - Creati clase care mostenesc ''Hero'' pentru fiecare tip de erou. |
* suprascrieti metoda ''toString'' din ''Object'' pentru fiecare erou | * suprascrieti metoda ''toString'' din ''Object'' pentru fiecare erou | ||
* metoda ''attack'' - deocamdată nu va omorî pe nimeni - puteți afișa ceva la consolă | * metoda ''attack'' - deocamdată nu va omorî pe nimeni - puteți afișa ceva la consolă | ||
- | - Uitați-vă la clasele ''TreasureFactory'' și ''HeroFactory''. Trebuie să implementăm două metode: ''createTreasure'' în ''TreasureFactory'' și o metodă de creare de eroi în ''HeroFactory'', fie ea ''createHero''. | + | - Uitați-vă la clasele ''TreasureFactory'' și ''HeroFactory''. Trebuie să implementăm două metode: ''createTreasure'' în ''TreasureFactory'' și o metodă de creare de eroi în ''HeroFactory'', fie ea ''createHero''. |
- | - Puteți pune orice date doriți în comori, respectiv eroi. | + | - Puteți pune orice date doriți în comori, respectiv eroi. |
- | - La ''HeroFactory.createHero'', pasați ca parametru un ''Hero.Type'' și un ''String'' cu numele eroului și întoarceți un subtip de ''Hero'' potrivit pentru tipul de erou. | + | - La ''HeroFactory.createHero'', pasați ca parametru un ''Hero.Type'' și un ''String'' cu numele eroului și întoarceți un subtip de ''Hero'' potrivit pentru tipul de erou. |
- | - După ce ați creat factory-urile, folosiți-le: | + | - După ce ați creat factory-urile, folosiți-le: |
- | - Completați metoda ''populateTreasures'' din ''World''. Folosiți-vă de membrii ''map'' și ''treasures'' din ''World''. Trebuie să marcați pe hartă că aveți o comoară și să adăugați obiectul-comoară în lista de comori. | + | - Completați metoda ''populateTreasures'' din ''World''. Folosiți-vă de membrii ''map'' și ''treasures'' din ''World''. Trebuie să marcați pe hartă că aveți o comoară și să adăugați obiectul-comoară în lista de comori. |
- | - Uitați-vă apoi la cazul ''add'' din metoda ''main''. Trebuie să adăugați eroi acolo. Folosiți ''HeroFactory.createHero''. | + | - Uitați-vă apoi la cazul ''add'' din metoda ''main''. Trebuie să adăugați eroi acolo. Folosiți ''HeroFactory.createHero''. |
- | * Folosiți design pattern-ul //Singleton// pentru elementele din joc care trebuie să aibă doar o instanță. | + | * Folosiți design pattern-ul //Singleton// pentru elementele din joc care trebuie să aibă doar o instanță. |
- | * Ce clase vor avea doar o singură instanță? | + | * Ce clase vor avea doar o singură instanță? |
- | * Folosiți design pattern-ul //Observer// pentru a monitoriza ceea ce se întâmplă în joc. Scheletul de cod vă sugerează două tipuri de observatori, pentru bonus puteți adăuga și alții. | + | * Folosiți design pattern-ul //Observer// pentru a monitoriza ceea ce se întâmplă în joc. Scheletul de cod vă sugerează două tipuri de observatori, pentru bonus puteți adăuga și alții. |
- | - veți folosi interfața [[:poo-ca-cd:https://docs.oracle.com/javase/8/docs/api/java/util/Observer.html|Observer]] și clasa [[:poo-ca-cd:https://docs.oracle.com/javase/8/docs/api/java/util/Observable.html|Observable]] din java.util. | + | - veți folosi interfața [[https://docs.oracle.com/javase/8/docs/api/java/util/Observer.html|Observer]] și clasa [[https://docs.oracle.com/javase/8/docs/api/java/util/Observable.html|Observable]] din java.util. |
- Înainte să vă apucați să scrieți, citiți comentariile din cod (e.g. TreasureDiscoverer) să vă faceți o idee despre ce vrem să facem în clasele observatoare. | - Înainte să vă apucați să scrieți, citiți comentariile din cod (e.g. TreasureDiscoverer) să vă faceți o idee despre ce vrem să facem în clasele observatoare. | ||
- Asigurati-va ca implementati corect functionalitatea din **Observable**. Mare atentie la faptul ca **metoda notifyObservers nu va face nimic daca nu este apelata mai intai metoda setChanged**. | - Asigurati-va ca implementati corect functionalitatea din **Observable**. Mare atentie la faptul ca **metoda notifyObservers nu va face nimic daca nu este apelata mai intai metoda setChanged**. | ||
- | - Care sunt elementele observatoare și care sunt observabile? Uitați-vă și în comentariile din cod. | + | - Care sunt elementele observatoare și care sunt observabile? Uitați-vă și în comentariile din cod. |
- | - Implementați interfețele ''Observer'' și ''Observable'' în clasele potrivite. | + | - Implementați interfețele ''Observer'' și ''Observable'' în clasele potrivite. |
- | - Înregistrați observatori la ''World''. Cazul ''start'' din metoda ''main''. | + | - Înregistrați observatori la ''World''. Cazul ''start'' din metoda ''main''. |
- | - 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|> | + | |
- | {{:poo-ca-cd:laboratoare:design-patterns:exercitiu.png|Componentele jocului}}</imgcaption> | + | {{ :poo-ca-cd:laboratoare:design-patterns:exercitiu.png | Componentele jocului }} |
=== Strategy, Command === | === Strategy, Command === | ||
Line 339: | Line 341: | ||
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, monștrii sau o comoară | + | * 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''. | + | * este menținută în clasa ''GameState''. |
- | * //Eroii// | + | * //Eroii// |
- | * sunt reprezentați prin clase de tip ''Hero'' și sunt de trei tipuri: //Mage//, //Warrior//, //Priest//. | + | * 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 :)) | + | * 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 | + | * într-o zonă pot fi mai mulți eroi |
- | * acțiunile pe care le pot face: | + | * acțiunile pe care le pot face: |
- | * ''move'' - se mută într-o zonă învecinată | + | * ''move'' - se mută într-o zonă învecinată |
- | * ''attack'' - ataca un monstru cand se afla pe aceeasi pozitie cu el | + | * ''attack'' - ataca un monstru cand se afla pe aceeasi pozitie cu el |
- | * ''collect'' - eroul ia comoara găsită în zona în care se află | + | * ''collect'' - eroul ia comoara găsită în zona în care se află |
- | * Entry-point-ul în joc îl consitituie clasa ''Main''. | + | * 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''. | + | * 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. | + | * 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. | + | * 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. | + | * //__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. | + | * 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. | + | * //__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. | + | * 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: | + | * 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 | + | * 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) | + | * 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. | + | * **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. | + | * **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 | + | * 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. | + | * 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ă | + | * Implementați coliziunile cu obstacolele de pe hartă |
- | * Va trebui sa creati un nou obiect ''Obstacle'' precum si un ''ObstacleObserver'' | + | * 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'' | + | * 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'' |