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/31 13:55] 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 ====
  
-Uz zadatak je dan i izvorni kod. \\+Uz zadatak je dan i izvorni kod.
  
-Spajanjem na zadatak otvara se izbor borca. Mogući izbor su 3 borca i 3 elementa za svakog borca. \\+Spajanjem na zadatak otvara se izbor borca, mogući izbor su 3 borca i 3 elementa za svakog borca.
  
-{{ elemental_fighters:slika1.png?nolink&500 | Slika 1 - izbor borca}}+{{ elemental_fighters:slika1.png?nolink&500 | Slika 1- izbor 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 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.
  
-Analizom kodazanimljiva je varijabla **s** (scale), koja određuje koliko će se oslabiti ili ojačati neprijatelji\\+Analizom koda zanimljiva je varijabla **s**, koja je "scale", odnosno određuje koliko će se oslabiti ili ojačati neprijatelje.
  
 {{ elemental_fighters:slika2.png?nolink&500 | Slika 2 - scale varijabla}} {{ elemental_fighters:slika2.png?nolink&500 | Slika 2 - scale varijabla}}
  
-Ova varijabla se kasnije u kodu množi s atributima neprijateljašto je manja, neprijatelji su slabijišto je veća, neprijatelji su jači.+Ova varijabla se kasnije u kodu množi s atributima neprijatelja što je manja, neprijatelji su slabiji, a što je veća, neprijatelji su jači.
  
-Takođerzanimljiv dio koda je **player default**, koji definira varijablu _player_ kao `milo("ice")ako je _player_ `None`\\+Također zanimljiv dio koda je player default, koji definira player varijablu kao **Milo("ice")**, ako je player None.
  
-{{ elemental_fighters:slika3.png?nolink&500 | Slika 3 - Player default}}+{{ elemental_fighters:slika3.png?nolink&500 | Slika 3- Player default}}
  
-Najključniji dio koda je funkcija kojom se inicijalizira varijabla _player_ iz izbora igrača. \\+Ključan dio koda je funkcija kojom se inicijalizira player varijabla iz izbora igrača.
  
-{{ elemental_fighters:slika4.png?nolink&500 | Slika 4 - inicijalizacija player varijable iz igračevog izbora}}+{{ elemental_fighters:slika4.png?nolink&500 | Slika 4- inicijalizacija player varijable iz igračevog izbora}}
  
-Ovdje se koristi funkcija **eval**, kojom se unos _fighter_ poziva kao funkcija, a _fighterType_ kao argument.+Ovdje se može vidjeti da se koristi funkcija **eval**, kojime se fighter unos poziva kao funkcija, a fighterType kao argument.
  
-Sukladno tome, fighteri su zapravo funkcije: \\+Može se vidjeti da su fighteri zapravo funkcije:
  
-{{ elemental_fighters:slika5.png?nolink&500 | Slika 5 - fighter funkcije}}+{{ elemental_fighters:slika5.png?nolink&500 | Slika 5- fighter funkcije}}
  
-Vrijednosti _fighterType_ definirane su u rječniku i parsiraju se pri pozivanju _fighter_ funkcije.+a fighterType vrijednosti su definirane u rječniku, te se parsiraju pri pozivanju fighter funkcije.
  
-To znači da unosom _fighterType_ ("Odaberite element borca") definiraš argument funkcije, a unosom _fighter_ ("Odaberite borca") definiraš funkciju kojoj će se argument proslijediti i koja će se izvršiti u `eval`.+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 **eval** funkciji.
  
-No, svaki unos prolazi kroz **validate_input**, filter koji određuje koji su unosi dozvoljeni. \\+Svaki unos prolazi kroz validate_input funkcijukoja je filter koji određuje koji su unosi dozvoljeni, a koji nisu.
  
-{{ elemental_fighters:slika6.png?nolink&500 | Slika 6 - validate funkcija}}+{{ elemental_fighters:slika6.png?nolink&500 | Slika 6- validate funkcija}}
  
-Kako bismo provjerili možemo li pozvati proizvoljnu funkciju i argument (ako validate_function ne zabrani), možemo probati:+Kako bi provjerili da možemo pozvati proizvoljnu funkciju i argumentako nemamo unos koji bi funkcija validacije zabranila, možemo probati pozvati:
  
-<code>list("aaa")</code>+<file> 
 +list("aaa") 
 +</file>
  
-Unos izgleda ovako: +Odaberite element borca (Ice, Fire, Acid): aaaa  
- +
-<code> +
-Odaberite element borca (Ice, Fire, Acid): aaaa+
 Odaberite borca (Zorn, Krev, Milo)list Odaberite borca (Zorn, Krev, Milo)list
-</code> 
  
-{{ elemental_fighters:slika7.png?nolink&500 | Slika 7 - poziv list("aaa")}}+{{ elemental_fighters:slika7.png?nolink&500 | Slika 7- poziv list("aaa")}}
  
-Program vraća listu u kojoj su svi znakovi iz stringa koji smo poslali kao prvi argument, s dodanim zagradama oko _fighterType_ varijable (vidi sliku 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čno možemo pozvati:+Slično se možpozvati len funkcija.
  
-<code>len("aaa")</code>+<file> 
 +len("aaa") 
 +</file>
  
-Unos:+Poziva se na ovakav način.
  
-<code+<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
-</code>+</file>
  
-{{ elemental_fighters:slika8.png?nolink&500 | Slika 8 - poziv len("aaa")}}+{{ elemental_fighters:slika8.png?nolink&500 | Slika 8- poziv len("aaa")}}
  
-Program vraća 5, što odgovara trima znakovima `"a"koje 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.
  
-Flag nije pohranjen u varijabli; hardkodiran je u zadnjem `print`u programa. Potrebno je osmisliti način kako pozvati odgovarajuću funkciju i argument da bi program izvršio flag.+Flag nije zapisan niti 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 je mijenjanje varijable **s** (vidi sliku 2), koja predstavlja skalu jačine protivnika. Ako je postavimo na 0, protivnici su slabiji, činjenica da se input koristi za mijenjanje varijable _s_ umjesto inicijalizacije borca nije problem jer postoji *defaultborac (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 "default" odabir borca, ako borac nije definiran, prikazan na slici 3.
  
-Cijeli unos igrača se izvršava unutar **eval**, koji evaluira *expression*. Primjeri: `"2+2"` → `4``len("(aaa)")` → `5`. Bilo koja vrijednost vraćena iz eval dodjeljuje se _player_ varijabli (vidi sliku 4).+Cijeli unos igrača se izvršava unutar funkcije **eval**, koja je namijenjena samo za evaluiranje **expression**-akoji nakon izvršavanja vraća neku vrijednost, na primjer:
  
-Potrebno je mijenjati druge varijable u globalnom kontekstu (npr. _s_) unutar eval-a.+<file> 
 +"2+2" 
 +</file>
  
-Python razlikuje *expression* i *statement*. *Statement* (npr. `a = 0`) izvršava akciju, ali ne vraćvrijednost — pa `eval("a=0")` nije validan kod. Funkcija **exec** izvršava *statement* i može mijenjati varijable u globalnom kontekstu: `exec("a=0")`. Pregledom validate_input (slika 6) vidi se da **exec** nije zabranjen.+vraćena vrijednost je 4,  
  
-Dakle, **exec** se može koristiti za mijenjanje globalne varijable **s**.+<file> 
 +len("(aaa)"
 +</file>
  
-Primjer pokušaja:+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).
  
-<code> +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**.
-exec("s=0") +
-</code>+
  
-Unos:+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.
  
-<code>+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** (a može izvršavati i **expression**), te može definirati ili mijenjati varijable u globalnom kontekstu programa, ako 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. 
 + 
 +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 potencijalni način rješavanja ovog programa bi bio izvršiti: 
 + 
 +<file> 
 +exec(s=0) 
 +</file> 
 + 
 +Čime bi unos izgledao ovako: 
 + 
 +<file>
 Odaberite element borca (Ice, Fire, Acid): s=0 Odaberite element borca (Ice, Fire, Acid): s=0
 Odaberite borca (Zorn, Krev, Milo)exec Odaberite borca (Zorn, Krev, Milo)exec
-</code>+</file>
  
-Pokretanjem pojavit će se greška `invalid syntax` (slika 9) jer parser **eval** zahtijeva validan *expression*.+Pokretanjem ovog unosa, prikazanog na slici 9, pojavljuje se greška.
  
-{{ elemental_fighters:slika9.png?nolink&500 | Slika 9 - greška pri pokušaju}}   +{{ elemental_fighters:slika9.png?nolink&500 | Slika 9- greška pri pokušaju}}
-{{ elemental_fighters:slika10.png?nolink&500 | Slika 10 - eval parser i exec funkcija}}+
  
-Rješenje: koristiti Pythonov **walrus operator** (`:=`), koji je *expression* i vraća vrijednost dok istovremeno dodjeljuje varijabli.+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.
  
-Primjer:+Opisana ponašanja su prikazana na slici 10.
  
-<code>(a := 3)</code>+{{ elemental_fighters:slika10.png?nolink&500 | Slika 10. - eval parser i exec funkcija}}
  
-U zagradama postaje validan *expression*, koji se može evaluirati unutar **eval** i izvršiti s **exec** u globalnom scopeu.+Na slici je prikazano da **eval** može izvršiti:
  
-Rješenje unosa:+<file> 
 +a==3 
 +</file>
  
-<code> +jer je to zapravo validan **expression** koji se evaluira u False.
-Odaberite element borca (Ice, Fire, Acid): s:=0 +
-Odaberite borca (Zorn, Krev, Milo)exec +
-</code>+
  
-Time se postavlja varijabla **s** na 0, a _player_ ostaje `None` — aktivira se *default`player = Milo("ice")`.+Način kako se ovo može postići je korištenjem Pythonovog "walrus" operatora, koji je zapravo **expression**, vraćrezultat evaluacije **expressiona**, ali također evaluirani **expression**, nakon evaluacije postavlja kao vrijednost dane varijable.
  
-{{ elemental_fighters:slika11.png?nolink&500 | Slika 11 - walrus operator}}   +Walrus operator se označava znakovima `:=`.
-{{ elemental_fighters:slika12.png?nolink&500 | Slika 12 - rješenje zadatka}}+
  
-Walrus operator je validan *expression*, može se izvršavati unutar **eval** i **exec**, mijenja vrijednost varijable samo ako se izvršava globalnom scopeu.+{{ elemental_fighters:slika11.png?nolink&500 | Slika 11. - walrus operator}} 
 + 
 +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**. 
 + 
 +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> 
 +(a:=3) 
 +</file> 
 + 
 +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}} 
 + 
 +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. 
 + 
 +{{ elemental_fighters:slika15.png?nolink&500 | Slika 15 - neispravna sintaksa}} 
 + 
 +To čini ovaj pristup neizvedivim: 
 + 
 +<file> 
 +Odaberite element borca (Ice, Fire, Acid): s=0 
 +Odaberite borca (Zorn, Krev, Milo)milo 
 +</file> 
 + 
 + 
 +"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 i unutar **eval** i unutar **exec** funkcijegdje u oba slučaja uspješno mijenja vrijednost varijable (ali samo ako se **exec** i **eval** pokrećunutar globalnog konteksta). 
 + 
 +{{ 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:slika16.png?nolink&500 | Slika 16 - walrus i eval / exec}}   
 {{ elemental_fighters:slika17.png?nolink&500 | Slika 17 - walrus unutar exec unutar eval}} {{ elemental_fighters:slika17.png?nolink&500 | Slika 17 - walrus unutar exec unutar eval}}
  
-Ovaj postupak reproducira originalnu logiku inicijalizacije _player_ varijable u zadatku (slika 4).+Š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 i 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}} {{ elemental_fighters:slika20.png?nolink&500 | Slika 20 - pojednostavljeno izvršavanje payloada}}
  
-Rješenje unosa:+Sada je poznato rješenje i način kako rješava zadatak.
  
-<code>+Rješenje se može unijeti ovako: 
 + 
 +<file>
 Odaberite element borca (Ice, Fire, Acid): s:=0 Odaberite element borca (Ice, Fire, Acid): s:=0
 Odaberite borca (Zorn, Krev, Milo)exec Odaberite borca (Zorn, Krev, Milo)exec
-</code>+</file> 
 + 
 +Izvršava se prethodno opisan postupak izvršavanja ovog koda, koji rezultira u postavljanju varijable **s** u 0, a varijable **player** u None, te se **player** onda inicijalizira u default, odnosno **Milo("ice")**. 
 + 
 +{{ elemental_fighters:slika21.png?nolink&500 | Slika 21. - rješenje zadatka}}
  
-Postavlja **s 0** _player None_, zatim se _player_ inicijalizira na *default* Milo("ice").+==== Eval / Exec global scope ====
  
-{{ elemental_fighters:slika21.png?nolink&500 | Slika 21 - rješenje zadatka}}+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.
  
-Pošto se izvršava u global scopeu, **exec** može mijenjati globalnu varijablu **s**Ako bi se izvršavalo unutar funkcije, lokalne varijable ne bi bile promijenjene.+{{ elemental_fighters:slika22.png?nolink&500 | Slika 22- eval unutar functiona}}
  
-{{ elemental_fighters:slika22.png?nolink&500 | Slika 22 - eval unutar functiona}}   +Dok je pri izvršavanju u global scopeu, ovo moguće.
-{{ elemental_fighters:slika23.png?nolink&500 | Slika 23 - eval unutar global scopea}}+
  
-Ovo vrijedi i za **eval** i za **exec**.+{{ 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.1761918940.txt.gz · Last modified: 2025/12/01 11:40 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki