Izdelava Igre 15

Izdelava Igre 15

Avtor: Andrej Koželj

Povzetek

V tem gradivu bom poskusil čimbolje predstaviti približno idejo, potek izdelave in pravila igre 15, preproste igrice, pri kateri moramo 15 premešanih kvadratkov urediti po vrsti.

Izdelava je potekala v jeziku C#, pri samem pisanju kode pa nisem uporabil nobenega posebno zanimivega algoritma ali programerskega prijema, zato se bom vključevanju dejanske kode izognil.

(primer.PNG)
Prikaz končnega programa

Igra 15

Igra 15 je ena enostavnejših igric, pri katerih sestavljamo določene komponente po določenih pravilih. V tem primeru urejamo 15 kvadratkov od najmanjšega do največjega.

Kvadratki so razporejeni na površini 4x4, kar pomeni, da je eno mesto prazno. Tako lahko vedno vsaj dva izmed kvadratkov premaknemo na sosednje mesto, kar nam omogoča urejanje.

Igra se konča, ko so kvadratki urejeni od najmanjšega do največjega. Seveda pa ni nujno vsaka postavitev kvadratkov rešljiva. Pri table sode dimenzije velja: če je prazen kvadratek v sodi vrstici od spodaj navzgor (se pravi predzadnji, 4. od spodaj, itd.), potem je število inverzij za rešljivo postavitev liho. Če pa je prazen kvadratek v lihi vrstici od spodaj navzgor, je število inverzij za rešljivo situacijo sodo.

Sama inverzija pomeni zamenjavo dveh elementov v seznamu. Če imamo naprimer seznam [1,2,3], nato pa zamenjamo drugi in tretji element, smo s tem naredili inverzijo. Nov seznam je sedaj [1,3,2].

Kaj dejansko pomeni število inverzij? Za število inverzij moramo najprej vse kvadratke postaviti v vrsto od prvega do zadnjega, nato pa izračunati vsoto števila manjših kvadratkov desno od vsakega kvadratka (praznega ne upoštevamo). Se pravi, če imamo na prvem mestu kvadratek 14, imamo desno od njega samo en večji kvadratek, in sicer 15.

Ko vemo teh nekaj stvari, se lahko že kar lotimo izdelave te igrice.

Kaj vključiti v igro

Ko se lotimo programiranja katerekoli stvari, si moramo najprej zamisliti, česa bo pravzaprav nastali program zmožen. Lahko vključimo samo osnovne stvari, ki so nujne za delovanje, lahko pa dodamo tudi kaj drugega, kar lahko polepša izgled programa ali pa olajša njegovo uporabo.

Ker je Igra 15 že sama po sebi precej enostavna, ni potrebno, da iz izdelave naredimo celo znanost. Dovolj je, da najprej dodamo nujne funkcionalnosti, nato pa vključujemo dodatke, dokler se nam ne zazdi, da jih je za enostavno uporabo dovolj.

Sedaj se moramo odločiti, katere stvari pravzaprav vključiti. Za začetek vemo, da bomo potrebovalipovrpino s kvadratki in način, s katerim jih lahko premikamo. Za to bo za začetek dovolj miška.

Na tem nato gradimo naprej. Vključimo naprimer še možnost igranja s smernimi tipkami. Za večjo preglednost vstavimo meni, s pomočjo katerega bomo nato uporabljali nadaljnje dodatke. Lahko naprimer vključimo števec premikov, da uporabnik ve, koliko potez potrebuje za zaključek igre. Mogoče ga zanima tudi, koliko časa porabi za reševanje, zato lahko vključimo tudi štoparico. Ker števec in štoprica nista preverč uporabna, če rezultatov ni s čemer primerjati, lahko dodamo še lestvico najboljših igralcev. Te se da urediti po števil potez ali pa po porabljenem času za zmago. Ker potrebujemo seveda tudi imena igralcev, pomeni, da moramo ob zmagi tudi ponuditi možnost vpisa imena.

Mogoče se bo igralcu igra zdela težka, in bo potreboval več časa za reševanje. V tem primeru bi bilo mogoče dobro, da mu ponudimo možnost shranjevanja igre in kasnejšega odpiranja.

Zakaj bi ostali samo pri urejanju števil? Kaj pa, če bi uporabnik sestavljal poljubno sliko? Lahko vključimo še to, kar igro pravzaprav precej oteži.

Ko si postavimo te naloge, je čas, da se lotimo samega programiranja.

Načrt vmesnika

Še preden začnemo besno pisati naš program, bi si mogoče morali vsaj približno zamisliti, kako bo izgledal naš vmesnik. Za začetek bo dovolj, da si naredimo načrt glavnega okna igrice. Ker sem program že napisal, je tukaj slika že izdelanega vmesnika, ki sem si ga zamislil sam, seveda pa bi se dalo kakšno zadevo narediti tudi drugače.

(vmesnikGlavno.PNG)
glavno okno

Načrt vmesnika

Kot vidimo, je meni seveda zgoraj, kot smo ga navajeni. Ko poženemo naš program, se najprej pojavi napis z imenom programa. Pod igralno površino imamo na levi števec premikov, na desni pa merilec časa igranja. Ko z menijem izberemo novo igro, zadeva izgleda tako:

(vmesnikGlavnoNova.PNG)
Nova igra

Načrt vmesnika - lestvica

Že kar takoj si lahko izdelamo tudi približne načrte za dodatna okna, ki jih bomo odpirali s pomočjo ukazov v meniju ali pa se bodo odprla sama ob zmagi. Takole sem si zamislil lestvico najboljših igralcev:

(vmesnikLestvica.PNG)
Lestvica najboljših igralcev

Kot vidimo, so na tem oknu trije stolpci, igralci, časi in števila potez. Naenkrat je lahko prikazano največ 7 igralcev. Poleg tega imamo gumb Zapri, ki nam zapre lestvico, in pa gumba Po času in Po potezah, ki nam igralce uredita naraščajoče glede na čas ali poteze. Vredno je omeniti, da je na lestvici več igralcev, le prikazanih je samo prvih 7. Ko pritisnemo na enega od gumbov za razvrščanje, se lahko na lestvici pojavijo drugi igralci kot prej.

Načrt vmesnika - shranjevanje igre

Vmesnik za shranjevanje je precej enostaven, vključuje samo nekaj teksta, vnosno vrstico in pa gumb Shrani. Kaj več se mi ni zdelo potrebno, saj shranjenih iger ponavadi ne hranimo v poljubnih mapah, pač pa jih imamo kar tam, kamor jih spravi program sam, kar je ponavadi nekje na mestu samega programa ali pa v podmapi. Za shranjevanje zato vpišemo samo ime datoteke, brez končnice. Če hočemo igro shraniti kam drugam, še vedno lahko vpišemo polno ime (brez končnice), vendar v tem ne vidim nekega smisla.

(vmesnikShrani.PNG)
Shranjevanje igre

Načrt vmesnika - odpiranje igre

Za odpiranje si naredimo malce obsežnejši vmesnik. Dodamo še prostor, kjer se nam prikažejo datoteke, ki so mogoče primerne za odpiranje. Že na tem mestu velja omeniti, da se da s takšnim načinom programiranja vsako računalniško generirano datoteko kaneje ročno spremeniti in tako prirediti podatke. S tem seveda lahko pokvarimo format in tako onemogočimo odpiranje takšne datoteke. To bi lahko onemogočili s šifriranjem datoteke ali pa samo preverimo veljavnost igre pri odpiranju. Sam sem poskrbel za to, da so datoteke, preden jih poskušamo uporabiti, vsaj približno smiselne, sicer jih program zavrne in izpiše opozorilo.

(vmesnikOdpri.PNG)
Odpiranje igre

To okno vsebuje prav tako vnosno vrstico, s katero spet lahko vpišemo tudi polno ime, gumb za odpiranje in pa površino za izpisovanje. Če z miško označimo neko datoteko, ki je izpisana, se nam njeno ime izpiše v vnosni vrstici, in lahko jo odpremo z gumbom Odpri.

Načrt vmesnika - odpiranje slike

Za odpiranje slike lahko naredimo podoben vmesnik kot pri shranjevanju. Ker pa sem igro delal v okolju Visual Studio, sem uporabil kar gradnik openFileDialog, ki nam omogoča izbiro datoteke z uporabnikom sistema Windows znanim oknom za izbiro datoteke.

(odpriSliko.PNG)
Odpiranje slike

Poleg teh oken imamo še manjše okence, ki nam služi kot čestitka ali opozorilo, vendar ni nič posebnega, zato ga tukaj ne bom prikazal.

Izdelava programa - glavno okno

Za glavno okno si najprej ustvarimo osnovni gradnik (TableLayoutPanel). Na tega nato dodajamo nadaljnje elemente. Najprej lahko omogočimo meni, ki mu nato dodajamo potrebne ukaze. Za realizacijo igrice sem definiral 16 dodatnih gradnikov panel in 16 oznak na teh gradnikih. na začetku ti izgledajo kot na prvi sliki načrta vmesnika, z napisom Igra 15. Nato v meni dodamo ukaz Nova igra, na katerega vežemo funkcijo, ki nam določi nekaj spremenljivk in kliče naslednjo funkcijo, ki nam premeša kvadratke in primerno spremeni parametre panel in tekst na oznakah.

Za tak način sem se odločil zato, ker se mi poljubna dimenzija igre zdi pretiravanje. Pri manjši dimenziji igra postane prelahka, pri večjih pa prezamudna. Če imamo namesto številk razrezano sliko, bi pri večjih dimenzijah reševanje postalo praktično nemogoče, saj med majhnimi delci slike težje opazimo razlike.

Na ukaz Nova igra tudi vežemo funkcijo, ki nam požene Timer, kar nam omogoča osveževanje prikaza časa igranja.

Pri izdelavi glavnega okna moramo predvsem paziti, da se vse metode kličejo v pravilnem vrstnem redu, sicer lahko pride do napak in posledično sesutja programa. Poleg tega je lepo, če tudi preprečimo uporabniku, da bi naenkrat odprl več dodatnih oken, naprimer okno za odpiranje igre, okno za shranjevanje, itd.

Ko imamo okno v osnovi ustvarjeno, moramo tudi vezati ustrezne metode, ki nam omogočajo igranje. Za vezavo klika z miško moramo posebej nastaviti vsak gradnik na površini, za vezavo smernih tipk pa je dovolj, da nastavimo glavno okno. Sedaj, če smo napisali pravilne metode in jih pravilno vezali, lahko že premikamo kvadratke.

Posebej bi mogoče omenil še funkcijo, ki nam premeša kvadratke. To sem dosegel tako, da sem ustvaril poseben seznam števil, nato pa premešam samo tega, kvadratke na platnu nato samo nastavim glede na števila v tem seznamu. Da so števila dovolj premešana, sem poskrbel z naključno menjavo praznega kvadratka (0 v tabeli števil) in enega od sosednjih. To se izvede tisočkrat, kar nam tabelo dodobra premeša. Nato se osveži prikaz kvadratkov.

Izdelava programa - okno za shranjevanje

Okno za shranjevanje je precej preprosto in tudi večinoma samostojno, povezano z glavnim mora biti samo toliko, da vemo, kakšni so podatki igre (tabela števil, število potez in čas) in pa, da vemo, kdaj je bilo okno uničeno, ko lahko spet uporabljamo ostale ukaze na glavnem oknu.

Vse metode, ki nam podatke zapišejo na datoteko, pa lahko definiramo v kodi tega okna. Pri shranjevanju nam tudi ni treba posebej paziti, samo preberemo ime shranjene igre iz vnosne vrstice in na novonastalo datoteko shranimo teh nekaj potrebnih podatkov v pravem formatu. Na tem mestu ne more priti do napak (skoraj), do teh lahko pride šele pri odpiranju.

Izdelava programa - okno za odpiranje

Okno za odpiranje spet najprej zgradimo iz nekaj osnovnih gradnikov, kar je v Visual Studiu precej enostavno. Ko pišemo metode, pa stvar postane malo težja. Sedaj bi radi, da se potencialne shranjene igre, ki bi jih lahko odprli, prikažejo na zaslonu. To dosežemo z gradnikom Listbox, ki nam omogoča dodajanje nizev, ki se nato izpišejo. Že na tem mestu sem dodal manjši filter, ki izpiše samo datoteke s končnico .shr, ki sem jo nastavil shranjenim igram. Še vedno pa takšna končnica ne pomeni, da je igra res veljavna. Uporabnik lahko namreč ponesreči ali namenoma spremeni vsebino takšne tekstovne datoteke. Zato potem, ko uporabnik datoteko že izbere, preverim še vso vsebino datoteke, in to vsebino šele, če je res vsaj približno smiselna, podam glavnemu oknu. K tem omejitvam najprej spada že format zapisa na datoteki. Samo kakšen presledek več in stvar že ni uporabna.

Poleg tega pa uporabnik lahko med seboj zamenja tudi dve števili tabele, ki se nahaja v prvi vrstici. Kot sem že omenil, ni rešljiva vsaka kombinacija števil, zato bi s tem lahko igro naredili nemogočo. Zaradi tega sem dodal še metodo, ki preveri rešljivost tabele. Če datoteka ustreza vsem tem zahtevam, se podatki prenesejo na glavno okno, in lahko nadaljujemo to shranjeno igro.

Izdelava programa - lestvica

Pri lestvici je spet nujno, da imamo podatke shranjene nekje zunaj programa. Sam sem za to uporabil datoteko lestvica.lt, kjer imamo v vsaki vrstici s tekstom najprej ime igralca, nato presledek, čas igranja, presledek in nazadnje še število potez. Ko kličemo lestvico, se ti podatki najprej porazdelijo v tri sezname. To nam nato omogoča urejanje vseh seznamov glede na enega. Ko imamo te sezname, samo še izpišemo prvih sedem elementov vsakega seznama. Ostali se izpišejo samo, če se spremeni ureditev seznamov, in ti pridejo med prvih sedem elementov. Če je dolžina seznamov krajša od sedem, izpišemo namesto igralcev še nekaj črtic in presledkov.

Izdelava programa - okno za izbiro slike

Sama izdelava okna je spet čisto osnovna. zateve se rahlo zapletejo pri pisanju metod, ki nam bodo res pripravile slike in jih poslale glavnemu oknu.

Samo sliko, ko jo izberemo, odpremo podobno kot shranjeno igro. Ker mora biti to slika, odpiranje postavimo v try/catch blok, kar nam prepreči sesutje programa ob neveljavni datoteki. Nato moramo še poskrbeti, da je slika prave velikosti. Naša površina je velikosti 400x400, zato mora biti enakih dimenzij tudi slika. To dosežemo tako, da ustvarimo novo prazno sliko velikosti 400x400, nato pa uporabimo interpolacijo, ki nam na to prazno sliko nariše nekoliko raztegnjeno ali skrčeno podano sliko, ki je sedaj pravih dimenzij.

Ko imamo sliko pravilne velikosti, jo moramo še razrezati. Za to naredimo tabelo, v kateri bodo ti kosi slike, nato pa v to tabelo dodajamo kopije rezov. Na koncu to tabelo slikic podamo nazaj glavnemu oknu, ki te slike nastavi kot ozadje posameznemu kvadratku. Še poskrbimo, da so napisi in barve teh kvadratkov sedaj nevidne, in že lahko začnemo sestavljati našo sliko.

Program - dodatne možnosti

Naš program sedaj dela ind ela v bistvu kar zadovoljivo, še vedno pa obstajajo ideje za izboljšave (ali vsaj dodatke, če že niso dejanske izboljšave). Lahko bi seveda vseeno vključili možnost izbire dimenzij tabele, ki pa bi igro s številkami naredila precej dolgočasno, igro s slikicami pa praktično nemogočo. V tem primeru bi se tudi morali lotiti izdelave igralne površine na malo drugačen način, z zanko, s pomočjo katere bi ustvarjali dodatne ploščice, ali pa kar risali kvadratke na platno.

Poleg izbire dimenzij bi lahko dodali še olepšavo premikanja. KOt imamo napisano sedaj, se kvadratki premaknejo v trenutku, ko jih kliknemo, ali premaknemo s smernimi tipkami. To je mogoče preveč mehanično za bolj zahtevne, ki si želijo mehkega premikanja kvadratkov, kot pri pravi, otipljivi igrici 15. To bi lahko dosegli s postopnim spreminjanjem koordinat kvadratka s pomočjo timerja, na vsak določen interval bi se kvadratek premaknil za določeno število pikslov.

Poleg tega bi lahko tudi vključili kakšno metodo za preverjanje ustreznosti slike. Trenutno moramo sami vedeti, ali bo slika dovolj raznolika, da bomo igro lahko končali, če pa bo preveč enobarvna ali vzorčasta, ne bomo vedeli, na katerem mestu je kakšen kvadratek.

vse to so nekateri moji predlogi, ki jih nisem uspel vključiti,ali pa so se mi zdeli nepotrebni, bralec pa jih lahko poskusi napisati sam.

Filmčka

Za konec sta tu še dva filmčka s prikazom igre s števili in sliko.

Filmčka

Filmček s sliko:

Kviz

0%
0%