User Tools

Site Tools


elemental_fighters

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
elemental_fighters [2025/10/30 13:52] mbunicelemental_fighters [2025/12/01 11:40] (current) – external edit 127.0.0.1
Line 1: Line 1:
-==== Elemental Fighters ====+==== Zadatak s Hacknite platforme - Elemental Fighters ====
  
-<file>  +Uz zadatak je dan izvorni kod.
-Možete li odabrati pravog borca pobijediti sve neprijatelje? +
- Spoji se Linux naredbom nc chal.hacknite.hr 12037 ili Windows naredbom telnet chal.hacknite.hr 12037  +
-</file>+
  
-Uz zadatak je dan izvorni kod\\+Spajanjem na zadatak otvara se izbor borca, mogućizbor su 3 borca i 3 elementa za svakog borca.
  
-Spajanjem na zadatak otvara se izbor borcaMogući izbor su tri borca i tri elementa za svakog borca. \\+{{ elemental_fighters:slika1.png?nolink&500 | Slika 1. - izbor borca}}
  
-{{ :slika1.png?nolink&500 | Slika 1 - izbor borca}}+Analizom koda u zadatku može se zaključiti da zapravo ne postoji kombinacija borca koja bi ni u najsretnijem slučaju uspjela pobijediti sve neprijatelje i doći do flaga, to znači da je potrebno nešto drugo učiniti jer ne postoji izbor pravog borca.
  
-No analizom koda u zadatku može se zaključiti da zapravo ne postoji kombinacija borca koja bi, ni u najsretnijem slučaju, uspjela pobijediti sve neprijatelje i doći do flaga. Znači da je potrebno nešto drugo napraviti, jer izbor pravog borca ne postoji.+Analizom koda zanimljiva je varijabla **s**, koja je "scale", odnosno određuje koliko će se oslabiti ili ojačati neprijatelje.
  
-Analizom koda zanimljiva je varijabla **s**, koja je “scale”, odnosno određuje koliko će se oslabiti ili ojačati neprijatelji\\+{{ elemental_fighters:slika2.png?nolink&500 | Slika 2 - scale varijabla}}
  
-{{ :slika2.png?nolink&500 | Slika 2 - scale varijabla}}+Ova varijabla se kasnije u kodu množi s atributima neprijatelja i što je manja, neprijatelji su slabiji, a što je veća, neprijatelji su jači.
  
-Ova varijabla se kasnije u kodu množi s atributima neprijatelja: što je manjaneprijatelji su slabiji; što je većaneprijatelji su jači.+Također zanimljiv dio koda je player defaultkoji definira player varijablu kao **Milo("ice")**ako je player None.
  
-Također, zanimljiv dio koda je **player default**, koji definira varijablu *player* kao *milo("ice")*, ako je *player* None\\+{{ elemental_fighters:slika3.png?nolink&500 | Slika 3. - Player default}}
  
-{{ :slika3.png?nolink&500 | Slika 3 - Player default}}+Ključan dio koda je funkcija kojom se inicijalizira player varijabla iz izbora igrača.
  
-Najključniji dio koda je funkcija kojom se inicijalizira varijabla *playeriz izbora igrača. \\+{{ elemental_fighters:slika4.png?nolink&500 | Slika 4. - inicijalizacija player varijable iz igračevog izbora}}
  
-{{ :slika4.png?nolink&500 | Slika 4 - inicijalizacija player varijable iz igračevog izbora}}+Ovdje se može vidjeti da se koristi funkcija **eval**, kojime se fighter unos poziva kao funkcija, a fighterType kao argument.
  
-Ovdje se može vidjeti da se koristi **eval** funkcija, kojom se *fighter* unos poziva kao funkcija, a *fighterType* kao argument.+Može se vidjeti da su fighteri zapravo funkcije:
  
-Sukladno tome, može se vidjeti da su *fighteri* zapravo funkcije\\+{{ elemental_fighters:slika5.png?nolink&500 | Slika 5. - fighter funkcije}}
  
-{{ :slika5.png?nolink&500 | Slika 5 - fighter funkcije}}+a fighterType vrijednosti su definirane u rječniku, te se parsiraju pri pozivanju fighter funkcije.
  
-Vrijednosti *fighterType* definirane su u rječniku te se parsiraju pri pozivanju *fighter* funkcije.+To znači da je unosom fighterType ("Odaberite element borca") zapravo se definira argument funkcije, a unosom fighter ("Odaberite borca") se definira funkcija kojoj će se argument proslijediti i koja će se izvršiti s proslijeđenim argumentom u **eval** funkciji.
  
-To znači da se unosom *fighterType* (“Odaberite element borca”) zapravo definira argument funkcijea unosom *fighter* (“Odaberite borca”) definira funkcija koja će se izvršiti s proslijeđenim argumentom u eval funkciji.+Svaki unos prolazi kroz validate_input funkciju, koja je filter koji određuje koji su unosi dozvoljeni, a koji nisu.
  
-No svaki unos prolazi kroz **validate_input**, koji je filter koji određuje koji su unosi dozvoljeni, a koji nisu\\+{{ elemental_fighters:slika6.png?nolink&500 | Slika 6. - validate funkcija}}
  
-{{ :slika6.png?nolink&500 | Slika 6 - validate funkcija}} +Kako bi provjerili da možemo pozvati proizvoljnu funkciju i argument, ako nemamo unos koji bi funkcija validacije zabranila, možemo probati pozvati:
- +
-Kako bismo provjerili možemo li pozvati proizvoljnu funkciju i argument, ako nemamo unos koji bi *validate_function* zabranio, možemo probati pozvati:+
  
 <file> <file>
Line 48: Line 43:
 </file> </file>
  
-<file> +Odaberite element borca (Ice, Fire, Acid): aaaa  
-Odaberite element borca (Ice, Fire, Acid): aaaa+
 Odaberite borca (Zorn, Krev, Milo)list Odaberite borca (Zorn, Krev, Milo)list
-</file> 
  
-{{ :slika7.png?nolink&500 | Slika 7 - poziv list("aaa")}}+{{ elemental_fighters:slika7.png?nolink&500 | Slika 7- poziv list("aaa")}}
  
-Vidimo da je program vratio listu u kojoj se nalaze svi znakovi iz stringa koji smo poslali kao prvi argument, te oko njih znakovi zagrada koje se dodaju oko *fighterTypevarijable (vidljivo na slici 4).+Vidimo da je program vratio listu u kojoj se nalaze svi znakovi iz stringa koji smo poslali kao prvi argument, te oko njih znakovi za zagrade, koji su znakovi zagrada oko fighterType varijable (vidi sliku 4).
  
-Sličnomožemo pozvati:+Slično se možpozvati len funkcija.
  
 <file> <file>
 len("aaa") len("aaa")
 </file> </file>
 +
 +Poziva se na ovakav način.
  
 <file> <file>
-Odaberite element borca (Ice, Fire, Acid): aaa+Odaberite element borca (Ice, Fire, Acid): aaa  
 Odaberite borca (Zorn, Krev, Milo)len Odaberite borca (Zorn, Krev, Milo)len
 </file> </file>
  
-{{ :slika8.png?nolink&500 | Slika 8 - poziv len("aaa")}}+{{ elemental_fighters:slika8.png?nolink&500 | Slika 8- poziv len("aaa")}}
  
-Vidimo da program vraća 5, što odgovara trima znakovima "akoje smo poslali i dvama znakovima zagrada.+Vidimo da program vraća 5, što je točno 3 znakova a koje smo poslali plus dva znaka zagrada.
  
-No flag nije zapisan ni u jednoj varijabli, nego je hardkodiran u zadnjem printu programa. Zato je potrebno osmisliti način kako pozvati odgovarajuću funkciju i argument da bi se program uspješno izvršio do kraja i ispisao flag.+Flag nije zapisan niti u jednoj varijabli, nego je samo hardkodiran u zadnjem printu programa, pa je potrebno osmisliti način kako pozvati odgovarajuću funkciju i argumentda bi se program uspješno izvršio do kraja i ispisao flag.
  
-Dobar pristup bio bi mijenjanje varijable **s** (vidi sliku 2), koja predstavlja skalu jačine protivnika. Ako bismo tu varijablu mogli smanjiti ili postaviti na 0, protivnici bi bili znatno slabiji. Činjenica da je input potrošen na mijenjanje varijable s” umjesto na inicijalizaciju borca ne bi bila problem jer postoji *defaultodabir borca (vidi sliku 3).+Dobar pristup bi bio mijenjanje varijable **s** na slici 2, koja je skala jačine protivnika. Ako bi tu varijablu mogli smanjiti ili pretvoriti u 0, protivnici bi bili puno slabiji, dok činjenica da je unos potrošen na mijenjanje varijable **s** umjesto na inicijalizaciju našeg borca ne bi bio problemjer postoji "defaultodabir borca, ako borac nije definiran, prikazan na slici 3.
  
-No cijeli unos igrača izvršava se unutar **eval** funkcije, koja je namijenjena za evaluiranje *expressiona**Expressionje izraz koji nakon izvršavanja vraća neku vrijednost — primjericeizraz je `"2+2"`, a vraćena vrijednost je 4; izraz je `len("(aaa)")` (kao na slici 8), a vraćena vrijednost 5. Svaka vrijednost vraćena nakon izvršavanja izraza u **eval** funkciji bit će pridružena varijabli *player* (vidi sliku 4).+Cijeli unos igrača se izvršava unutar funkcije **eval**, koja je namijenjena samo za evaluiranje **expression**-a, koji nakon izvršavanja vraća neku vrijednost, na primjer:
  
-Potrebno je pronaći način kako mijenjati druge varijable u globalnom kontekstu programa (poput varijable *s*) unutar **eval** funkcije, čiji se rezultat pridružuje varijabli *player*.+<file> 
 +"2+2" 
 +</file>
  
-Osim **expressiona** koje izvršava *eval*, u Pythonu postoji i **statement**, koji izvršava akciju, ali ne vraćvrijednost. *Statement* je, primjerice, `a=0`. No budući da *statement* ne vraća vrijednost, `b = (a = 0)` nije validan Python kod; također, ni `eval("a = 0")` nije validan Python kod.+vraćena vrijednost je 4 
  
-Slično **eval**, postoji funkcija **exec**, koja je namijenjena za izvršavanje *statementa* (ali može izvršavati i *expressione*). Ona može definirati ili mijenjati varijable u globalnom kontekstu programa ako se pokreće u globalnom kontekstu.   +<file> 
-Primjer: `exec("a=0")` je validan kod i postavit će (ili promijeniti) vrijednost varijable *a* na 0.   +len("(aaa)"
-Pregledom funkcije za validaciju unosa (slika 6.) vidi se da funkcija **exec** nije zabranjena.+</file> 
 + 
 +vraćena vrijednost je 5, i bilo koja vrijednost koja će biti vraćena nakon izvršavanja ekspresije u **eval** funkciji će biti pridružena varijabli **player** (vidi sliku 4). 
 + 
 +Potrebno je pronaći način kako mijenjati druge varijable u globalnom kontekstu programa, kao varijablu **s**, unutar **eval** funkcije, čiji se rezultat izvršavanja pridružuje varijabli **player**. 
 + 
 +Osim **expression** u Pythonu, koji izvršava izraz i vraća izračunatu vrijednost izraza, postoji i **statement**, koji izvršava definiranu akciju, no ne vraća ništa. 
 + 
 +Primjer **statement-a** 
 + 
 +<file> 
 +a = 0 
 +</file> 
 + 
 +, no pošto **statement** ne vraća ništa 
 + 
 +<file> 
 +b = (a = 0) 
 +</file> 
 + 
 +je neispravan Python kod, kao što bi bilo i da se eval koristio. 
 + 
 +<file> 
 +eval("a = 0") 
 +</file> 
 + 
 +(probajte u Python interpreteru). 
 + 
 +Slično funkciji **eval**, postoji funkcija **exec**, koja je upravo namijenjena za izvršavanje **statement** (može izvršavati i **expression**), te može definirati ili mijenjati varijable u globalnom kontekstu programaako se također pokreće u globalnom kontekstu programa
 + 
 +<file> 
 +exec("a=0") 
 +</file> 
 + 
 +Pregledom funkcije za validaciju unosa na slici 6 vidi se da funkcija **exec** nije zabranjena.
  
-Dakle, **exec** se može koristiti za mijenjanje vrijednosti varijable *s*, koja je globalna.+Znači da se funkcija **exec** može koristiti za mijenjanje vrijednosti scale varijable **s**, koja je globalna varijabla.
  
-Iz ovoga se može zaključiti da bi potencijalno rješenje bilo izvršiti:+Iz ovoga se može zaključiti da potencijalni način rješavanja ovog programa bi bio izvršiti:
  
 <file> <file>
Line 94: Line 125:
 </file> </file>
  
-Unos bi izgledao ovako:+Čime bi unos izgledao ovako:
  
 <file> <file>
Line 101: Line 132:
 </file> </file>
  
-Pokretanjem ovog unosa (slika 9.) pojavljuje se greška. \\+Pokretanjem ovog unosa, prikazanog na slici 9pojavljuje se greška.
  
-{{ :slika9.png?nolink&500 | Slika 9 - greška pri pokušaju}}+{{ elemental_fighters:slika9.png?nolink&500 | Slika 9- greška pri pokušaju}}
  
-Greška je *invalid syntax*, koju zapravo baca parser **eval** funkcije. On pregledava kod prije izvršavanja da bi odredio je li kod validan *expression*. Iako je kod namijenjen da bude proslijeđen **exec** funkciji, **eval** parser ga ne prihvaća.+Greška je invalid syntax, koju zapravo baca parser **eval** funkcije, koji pregledava kod prije nego će se izvršiti da odredi je li kod zapravo validan **expression**, iako je kod namijenjen da bude proslijeđen **exec** funkciji koja bi ovaj kod mogla normalno izvršiti.
  
-Opisana ponašanja prikazana su na slici 10. \\+Opisana ponašanja su prikazana na slici 10.
  
-{{ :slika10.png?nolink&500 | Slika 10 - eval parser i exec funkcija}}+{{ elemental_fighters:slika10.png?nolink&500 | Slika 10- eval parser i exec funkcija}}
  
-Na slici je prikazano da **eval** može izvršiti `a==3`, jer je to validan *expression* koji se evaluira u *False*.+Na slici je prikazano da **eval** može izvršiti:
  
-Može se zaključiti da je cilj napisati takav kod koji će **eval** parser odobriti, koji će imati logiku jednaku *statementu* `s=0`.   +<file> 
-Ovdje pomaže činjenica da **exec** može izvršavati i *expression*, pa treba napisati *expression* koji će **eval** parser odobriti, a **exec** će ga izvršiti i promijeniti globalnu varijablu *s*.+a==3 
 +</file>
  
-Način da se to postigne je korištenjem Pythonovog **walrus operatora** (`:=`), koji je zapravo *expression*. On vraća rezultat evaluacije izraza, ali također postavlja evaluiranu vrijednost varijablu.+jer je to zapravo validan **expression** koji se evaluira False.
  
-{{ :slika11.png?nolink&500 | Slika 11 - walrus operator}}+Način kako se ovo može postići je korištenjem Pythonovog "walrus" operatora, koji je zapravo **expression**, vraća rezultat evaluacije **expressiona**, ali također evaluirani **expression**, nakon evaluacije postavlja kao vrijednost dane varijable.
  
-Na slici 11. može se vidjeti kako funkcionira *walrus* operator. On evaluira izraz `== 1`, što je `True`, tu vrijednost vraća kao rezultat *if* statementu, ali istovremeno postavlja tu vrijednost varijabli *a*.+Walrus operator se označava znakovima `:=`.
  
-*Walrus* operatorom se može napisati validan *expression* koji nakon evaluacije mijenja vrijednost odabrane varijable (nprvarijable *s*).+{{ elemental_fighters:slika11.png?nolink&500 | Slika 11- walrus operator}}
  
-No *walrus* operator se ne može sam izvršavati unutar **eval** ni **exec** funkcije, jer mora biti dio *expressiona*.   +Na slici 11 može se vidjeti kako funkcionira walrus operator: evaluira **expression** "1 == 1", što je `True`, i to prosljeđuje kao rezultat **if izrazu**, ali također tu istu vrijednost postavlja kao vrijednost varijable **a**. 
-Ako se stave zagrade oko njega, izraz+ 
 +Walrus operatorom se može napisati validan **expression**, koji nakon evaluacije također mijenja vrijednost odabrane varijable, ciljano varijable **s**. 
 + 
 +Walrus operator se ne može sam izvršavati niti unutar **eval** niti unutar **exec** funkcije, zato što je namijenjen da bude izvršen unutar **expressiona**. 
 + 
 +{{ elemental_fighters:slika12.png?nolink&500 | Slika 12 - walrus operator}} 
 + 
 +No ako se stave zagrade oko njega, izraz:
  
 <file> <file>
Line 131: Line 170:
 </file> </file>
  
-postaje validan *expression*, što je prikazano na slici ispod. \\+postaje validan **expression**, što je prikazano na slici ispod. 
 + 
 +{{ elemental_fighters:slika13.png?nolink&500 | Slika 13 - walrus operator unutar zagrada}} 
 + 
 +Ovo je slučaj i u kodu zadatka, zato što se oko unosa dodaju zagrade, što je prikazano na slici ispod. 
 + 
 +{{ elemental_fighters:slika14.png?nolink&500 | Slika 14 - zagrade oko korisničkog unosa}}
  
-{{ :slika12.png?nolink&500 | Slika 12 - rješenje zadatka}}+Kada su zagrade oko unosa, unutar zagrada mora biti validan **expression**, što `s=0` nije nego je **statement**, kao što se vidi na slici ispod.
  
-Ovo je zapravo slučaj u kodu zadatka, jer se oko unosa dodaju zagrade (vidi sliku ispod).+{{ elemental_fighters:slika15.png?nolink&500 | Slika 15 - neispravna sintaksa}}
  
-Kada su zagrade oko unosa, unutar njih mora biti validan *expression*.   +To čini ovaj pristup neizvedivim:
-`s=0` to nije jer je *statement*, zato rješenje+
  
 <file> <file>
Line 145: Line 189:
 </file> </file>
  
-nije moguće. 
  
-Ali *walrus* operator je validan *expression* i može se izvršiti unutar **eval** i **exec** funkcije, gdje u oba slučaja uspješno mijenja vrijednost varijable (ako se izvršava globalnom kontekstu).+"alrus operator je validan **expression** i namijenjen je za izvršavanje unutar **expressiona**, što se može napraviti stavljanjem dodatnih zagrada. Ovako se walrus operator može izvršiti unutar **eval** i unutar **exec** funkcije, gdje u oba slučaja uspješno mijenja vrijednost varijable (ali samo ako se **exec** i **eval** pokrećunutar globalnog konteksta).
  
-Zato se može izvršiti i ovako:+{{ elemental_fighters:slika16.png?nolink&500 | Slika 16 - walrus i eval / exec}} 
 + 
 +I zato se također može izvršavati na ovaj način: 
 + 
 +{{ elemental_fighters:slika17.png?nolink&500 | Slika 17 - walrus unutar exec unutar eval}} 
 + 
 +Što je, uz dodavanje zagrada, zapravo ekvivalentno ovom kodu: 
 + 
 +{{ elemental_fighters:slika18.png?nolink&500 | Slika 18 - kod ekvivalentan kodu zadatka}} 
 + 
 +Odnosno ovome, nakon zamjene stringova da se sve vidi u jednoj liniji: 
 + 
 +{{ elemental_fighters:slika19.png?nolink&500 | Slika 19 - pojednostavljeni ekvivalentan kod}} 
 + 
 +I ovo je format inicijalizacije **player** varijable u zadatku, pa time rješenja ovog zadatka; ove zagrade su iste kao i u liniji koda inicijalizacije **player** varijable **eval** funkcijom na slici 4. 
 + 
 +Nakon toga se mogu raditi daljnje redukcije, zamjenom **eval** funkcije i njenih argumenata s ekvivalentnim kodom, pa primjenom istog postupka za **exec** funkciju s proslijeđenim argumentima. Nakon redukcija ta linija koda postaje ekvivalentna samo walrus operatoru unutar zagrada. 
 + 
 +{{ elemental_fighters:slika20.png?nolink&500 | Slika 20 - pojednostavljeno izvršavanje payloada}} 
 + 
 +Sada je poznato rješenje i način kako rješava zadatak. 
 + 
 +Rješenje se može unijeti ovako:
  
 <file> <file>
Line 156: Line 221:
 </file> </file>
  
-Time se izvršava postupak koji postavlja varijablu *s* na 0, a *player* na *None*što zatim aktivira *default* vrijednost *player = Milo("ice")*.+Izvršava se prethodno opisan postupak izvršavanja ovog koda, koji rezultira u postavljanju varijable **s** u 0, a varijable **player** None, te se **player** onda inicijalizira u default, odnosno **Milo("ice")**. 
 + 
 +{{ elemental_fighters:slika21.png?nolink&500 | Slika 21. - rješenje zadatka}} 
 + 
 +==== Eval / Exec i global scope ==== 
 + 
 +Budući da je ovo izvršeno u global scopeu, **exec** može promijeniti vrijednost scale varijable **s**, dok, da se izvršavao unutar funkcije, ne bi mogao promijeniti niti lokalnu varijablu unutar istog scopea kao funkcija.
  
-Ovo ne bi bilo moguće bez *walrus* operatora jer **eval** parser vidi samo *statement*, dok je *walrus* operator unutar zagrada validan *expression* koji mijenja vrijednost varijable.+{{ elemental_fighters:slika22.png?nolink&500 | Slika 22. - eval unutar functiona}}
  
-Pošto se ovo izvršava **global scopeu****exec** možpromijeniti vrijednost globalne varijable *s*.   +Dok je pri izvršavanju u global scopeu, ovo moguće.
-Da se izvršavalo unutar funkcije, ne bi moglo promijeniti ni lokalne varijable u istom *scopeu*.+
  
-Pri izvršavanju u globalnom *scopeu* ovo postaje moguće i daje konačno rješenje zadatka.+{{ elemental_fighters:slika23.png?nolink&500 | Slika 23. - eval unutar global scopea}}
  
 +Ovo pravilo vrijedi i za **eval** i za **exec**, obje funkcije mogu mijenjati globalne varijable samo kada se izvršavaju u globalnom scopeu.
elemental_fighters.1761832325.txt.gz · Last modified: 2025/12/01 11:40 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki