3. lecke Számkitalálós játék

Online Android szakkör (DKRMG)


Az első két lecke elvégzése után (telepítés és Hello World) végre belevághatunk az Android programozásba! A Hello World alkalmazásunk az előző alkalommal ugyan fontos lépésnek számít, komoly applikációnak mégis csak jóindulattal lehet nevezni.

Ma ehhez képest megírjuk az első androidos játékunkat!

Nem, repkedő mérges madarakat ma még nem fogtok látni a képernyőn. Ehhez képest kihívhatjuk a telefonunkat egy olyan küzdelemre, ami próbára teszi az agyunkat és a kitartásunkat: következzen a számkitalálós játék.

A játék menete

A számítógép/telefon gondol egy számra 1 és 100 között. A mi feladatunk kitalálni, hogy a gép melyik számra gondolhatott! Ehhez:

Hogyan néz ez ki a telefonunkon?

A programozás szépsége, hogy ezt az egyszerű játékot is rengeteg különböző módon lehetne elkészíteni. Mivel ez az első komolyabb programunk, mi most maradjunk a felhasználói felület legegyszerűbb elemeinél:

A kész alkalmazás képe már látható is a szöveg mellett.

A lecke folyamán…

A projekt importálása

Az egyszerűség kedvéért előkészítettünk nektek egy projektet (GuessGame), ami nagyon hasonló a 2. leckében létrehozott Hello World projekthez, csak pár szükségtelen dolgot kiszedtünk belőle, illetve a Java kódba segítségként némi útmutatást helyeztünk el.

Ahhoz, hogy a projektet használni tudjuk, importálni kell az Android Studio-ba:

  1. Töltsük le a L03-GuessGame.zip fájlt, és csomagoljuk ki a Hello World projekt mappája mellé. (Tehát a Hello World mappa mellett legyen egy L03-GuessGame mappa, amely tartalmazza az app, gradle mappákat)
  2. Nyissuk meg az Android Studio-t.
  3. Egy idő után valószínűleg ugyanaz az ablak fogad minket, mint amivel bezártuk az előző lecke végén, azaz újra megnyitotta a Hello World! projektet.
  4. Nekünk másik projektre lesz szükségünk, ezért zárjuk be a projektet a File -> Close project menüponttal.
  5. Az így megjelenő kis ablakban nyomjuk meg az Import project sort.
  6. A megjelenő dialógusablakban keressük meg, és válasszuk ki az 1. lépésben kicsomagolt L03-GuessGame mappát, majd kattintsunk az OK gombra.
  7. Ha minden jól megy, rövid gondolkodás után megnyílik egy újabb Android Studio ablak, benne az új projekttel. Az ablak megnyitása után az Android Studio még feldolgozza a projekt fájljait, ez eltarthat akár pár percig is (Indexing...)
  8. Mivel a projektünk nem feltétlenül az általad letöltött (legújabb) Android Studio verzióval készült, az első megnyitáskor találkozhatunk néhány furcsa hibaüzenettel. Szerencsére az Android Studio elég okos ahhoz, hogy elvégezze helyettünk a projekten az apróbb (szükséges) átalakításokat. Fogadjuk el a javaslatait.

Beállítások

Mielőtt belekezdünk a fejlesztésbe, érdemes a File -> Settings menüben beállítani pár dolgot, ami megkönnyíti majd a munkát.

A végén a beállításokat az OK gomb megnyomásával mentsd el!

Layout – felhasználói felület

Első lépésként most megtanuljuk, hogy miként lehet könnyedén és gyorsan felhasználói felületet építeni. Ha programozás szakkörön találkoztál már a Lazarus-szal, némi előnnyel indulhatsz neki ennek a fejezetnek. Ha nem, akkor se csüggedj, ez az applikáció készítés egyik legegyszerűbb része!

  1. Nézd meg, hogy az ablak bal oldalán megjelenik-e a projekted tartalma az alábbi módon:

    Ha nem, akkor:

    • Győződjünk meg arról, hogy a "Tool Buttons" látszik (View -> Tool Buttons legyen pipálva)
    • Nézzük meg, hogy mi is van egész pontosan a projektünkben. Ehhez kattintsunk a Project gombra a bal szélen megjelent sávon.
  2. Most, hogy látjuk a projekt tartalmát, nyissuk meg az app -> res -> layout -> activity_main.xml fájlt.
  3. Győződjünk meg arról, hogy a Design fül van az ablak alján kiválasztva. Ilyekor mefjelenik a layout szerkesztő összetett, ám igen hasznos ablaka.
  4. Kezdő fejlesztőként érdemes egy keveset legalább könnyíteni a dolgunkon. Tüntessük el az egyelőre kevéssé hasznos jobb oldali (kék) ábrát a bal felső sarokban található Show design gombocska kiválasztásával.

Miért van egy szinte üres projektben ennyi mappa és fájl? Ezt a kérdést most nem is fogjuk megválaszolni, nem akarunk senkit oldalakon keresztül az Android azon részével untatni, amit „mezei” programozóknak ismernie sem kell. A hasznos dolgokkal a szakkör folyamán meg fogunk ismerkedni, egyelőre el kell fogadni, hogy ez így van!

Egy fontos dolgot azonban még most tisztáznunk kell. Amikor az alkalmazásunkat készítjük, két különböző ablakban, két különböző felülettel fogunk találkozni:

Komponensek, tulajdonságok

Ha eddig pontosan követtük az utasításokat, akkor megjelent a Design ablak egy okostelefon képével, ami megmutatja nekünk: mi is fogadna bennünket, ha az alkalmazásunkat most egy igazi készüléken/emulátorban elindítanánk.

Amikor a layout üres, a telefon képernyője is üres marad. Ebből bizonyára rájöttél, hogy máris van egy komponensünk, egy úgynevezett TextView, amelyen az általunk begépelt szellemes szöveg látható.

A komponenseinknek vannak tulajdonságai is, mivel mégsem nézhet ki minden felirat ugyanúgy! Jobb oldalt a Properties részen találjátok az épp kijelölt komponens összes tulajdonságát.

Próbaként kattints rá egyszer a TextView komponensünkre (Ez itt egy szöveg!), és nézd meg a tulajdonságait.

Ezen kívül kipróbálhatod még óvatosan a textStyle tulajdonságot is.

A bátrabbak megnézhetik a View all properties nyilak lenyomása után a Background tulajdonságot is

Új komponens hozzáadása

Ha minden igaz, akkor jelenleg van egy tetszőlegesen átszínezhető és méretezhető feliratunk. A feliratok nagyon hasznosak, de térjünk át egy kicsit izgalmasabb komponensre: a gombokra (Button).

Helyezzünk el egy gombot a felirat alá!

  1. Baloldalt a Widget kategóriában megtaláljuk a Button komponenst.

  2. Kattintsunk rá, majd az egérgombot lenyomva tartva húzzuk át a telefon kijelzőjére. Ahogy a kijelző különböző pontjaira mozgatjuk a gombot, láthatjuk, hogy a tervező megpróbálja a gombot a létező komponensekhez illetve a képernyő széleihez igazítani.

  3. Tegyük le a gombot pontosan középre, valahol a képernyő alsó felén. Ekkor felengedhetjük az egér bal gombját.

    Az új komponensünk hasonló tulajdonságokkal rendelkezik, mint a felirat.

  4. Írjuk át a megjelenő szöveget (text) erre: "kattints rám!"

  5. nézzük meg a gomb id tulajdonságát, mert később szükségünk lesz még rá! Ez nem más, mint button.

  6. Próbáljuk ki, hogy amit eddig csináltunk, hogy néz ki igazi telefonon/emulátoron! Futtassuk a projektet!

Interaktivtás

Van egy csinosan kinéző alkalmazásunk, csak sajnos még nem használható semmire. Nem reagál a gombnyomásra, nem gondol semmilyen számra. Leheljünk életet bele!

Eddig az activity_main.xml fájlban dolgoztunk, ami azt tartalmazta, hogy hogy nézzen ki az alkalmazásunk. Azt, hogy mit csináljon, Java nyelven kell megírnunk, az app -> java -> hu.dkrmg.android.guessgame -> MainActivity fájlban. Nyissuk is meg és próbáljunk meg egy pillanatig megbarátkozni a kóddal.

Ha eddig nem találkoztál még a Java nyelvvel, elsőre talán kissé sokkoló lehet a látvány. Ne félj, a többnyire angol szavakból, rövidítésekből és szimbólumokból álló kavalkád szépen lassan értelmet nyer! Mielőtt elkezdenéd az első feladatot, szeretnénk csak egy-két dolgot elmagyarázni.

1. feladat

Írjunk meg egy új függvényt, és állítsuk be a gombunk onClick tulajdonságával, hogy ez a függvény fusson le amikor megnyomjuk a gombot.

Először keressük meg az első feladatot [TODO 1] (44.sor), és hozzunk létre ezen a helyen egy új függvényt! Ehhez másoljuk be a TODO sor helyére az alábbi sorokat:

public void buttonClicked(View v) {
    Toast.makeText(this, "Megnyomtad a gombot!", Toast.LENGTH_SHORT).show();
}
		

Fontos, hogy mindent pontosan írj be! A kis-/nagybetűk, vesszők, zárójelek, idézőjelek és a sorvégi pontosvessző – mind számít!

Tehát például ez is egy helyes függvény lenne:

public void enEgyFuggvenyVagyok(View v) {
	// bla-bla
	// bla-bla
	// és most jöjjön egy Toast
	Toast.makeText(this, "Szia!", Toast.LENGTH_SHORT).show();
}

Próbáljuk is ki ()! Mi történik, ha megnyomjuk a telefonon a gombot? Ha pontosan követted a leírást, akkor az a működés, hogy nem történik semmi :-) ! Ugyanis mi csak megírtuk a függvényünket, de nem kötöttük össze a gombot a kóddal.

A gomb onClick tulajdonságban megadhatjuk, hogy a gomb megnyomásakor melyik függvény fusson le.

  1. Nyissuk meg újra az activity_main.xml fájlt. (layout)
  2. Kattintsunk egyszer a gombunkra, és jobboldalt a Properties ablakban keressük meg az onClick sort.
  3. Ha a mellette lévő üres mezőre kattintunk, megjelenik egy legördülő lista, amit ha lenyitunk, megtaláljuk annak az eljárásnak a nevét (buttonClicked), ahova kódot írtuk. Válasszuk ki!
  4. Próbáljuk meg újra futtatni az alkalmazást!

Kitérő: változók

A layout nézetben egyszerűen ki tudunk választani egy gombot, csak rá kell kattintanunk! Mi a helyzet, ha a Java programunkból szeretnénk hivatkozni egy komponensre? Nincs más dolgunk mint létrehozni egy változót, elnevezni mondjuk gomb1-nek és közölni a számítógéppel, hogy mostantól a "gomb1" változó nem más, mint az általunk meghatározott gomb a layout szerkesztőben. De mi is az a változó?

A változó a programozásban egy tároló, aminek van:

  • típusa
  • neve

Például létrehozhatunk egy-egy változót (a és b), amiben egy téglalap oldalainak hosszát tároljuk

int a; // az a oldal. int: egész szám pl. 0,1,2,3
int b; // a b oldal. int
a = 10; // az a oldal hossza legyen 10 (pl. cm)
b = 15; // a b oldal hossza legyen 15 (pl. cm)

Az első két sor a változók deklarációja (létrehozása, bemutatása), az alsó két sor pedig bemutatja, hogy miként tárolhatunk el új értéket a változóinkban.

int x;
x = 5; // x értéke legyen 5

Az értékadás (=) után a régi érték elveszik.

x = 6;			// x értéke mostantól 6!

Miért is jó, hogy vannak változóink? Például most könnyedén kiszámíthatjuk a téglalapunk területét

int terulet;
terulet = a * b; 	// téglalap területe: T=a*b

Más típusú változó kell, ha egy számot szeretnénk eltárolni benne, megint más, ha szöveget, vagy ha mondjuk egy gombot.

  • egy szam nevű, egész számot tároló változót így deklarálhatunk: int szam;
  • egy szoveg nevű, szöveget tárolót így: String szoveg;
  • egy leiras nevű, TextView-ra hivatkozó változót pedig így: TextView leiras;

Figyelni kell, hogy az, amit bele szeretnénk rakni a változóba, belepasszoljon, azaz ugyan olyan típusú legyen, mint a változó.

  • A szam változóba rakjuk bele a 42 értéket: szam = 42;
  • A szoveg változóba rakjuk bele a "Halihó!" értéket: szoveg = "Halihó!"
  • A leiras rakjuk bele a leírást megjelenítő komponenst: leiras = (TextView) findViewById(R.id.leiras);

Hohó! Ez az utolsó kicsit más, mint az előzőek! Nézzük meg közelebbről. Nagyjából stimmel, van baloldalt egy változó (leiras), utána az =. De ami utána következik, az egy kicsit más.

A findViewById egy beépített függvény, ami meg tudja keresni a kért komponenst, és a fenti módszerrel el tudjuk azt menteni egy változóba. Azt, hogy melyik komponenst kérjük, a második pár zárójel között kell megadni. Emlékeztek? Az Új komponens hozzáadása rész előtt közvetlenül megnéztük, hogy a leírást tartalmazó szöveg- komponensnek mi az azonosítója. Ugyan az, mint ami itt az R.id. után szerepel. Ezt majd később megnézzük, hogy miért van így, most fogadjuk el, hogy komponenst megkeresni így lehet: findViewById(R.id.≤komponens azonosítója>); Már csak egy dologról nem tudjuk, hogy micsoda: a "(TextView)” rész. Mivel komponensből nagyon sok féle lehet, meg kell mondanunk, hogy a változóba milyen típus passzol. Mivel a változónk típusa TextView, így ilyen típusú komponenst kérünk.

Pascalban / Lazarusban a változók nagyon hasonlóak.

var
  a : integer; // int a; Pascalban "név : típus", nem "típus név"
  ...
  a := 10; // a = 10; Pascalban ":=", nem "=".

2. feladat

A következő feladat legyen az, hogy gombnyomásra változzon meg a gomb feliratának színe!

2.1. feladat

Készíts egy új változót a gombodnak [TODO 2.1 helyére, 2x szerepel!] (Segítség: a gomb változójának típusa Button legyen!)!

Keresd meg a gomb komponensedet, és tárold el az új változódban!

Segítségként nézd meg, hogy mi hogyan csináltuk ugyanezt a "leiras" nevű TextView típusú változóval.

A layout komponenst az azonosítója alapján (id) a (<típus>) findViewById(R.id.); függvény segítségével találjuk meg!

2.2. feladat

Most egészítsük ki a gombunk buttonCliked függvényét azzal a paranccsal, ami átállítja a gombunk színét!

A gomb változónk rengeteg hasznos belső függvénnyel rendelkezik, amihez a következőképp férünk hozzá:

változóNeve.függvényNeve(...);

Amikor leütjük a pontot, az Android Studio elkezd javaslatokat tenni, hogy melyik függvényt használjuk. Írjuk be a következőt, és figyeljük, hogy a számítógép hogyan próbál nekünk segíteni!

gomb1.setTextColor(Color.GREEN);

A fenti sor azt mondja a gombnak, hogy állítsa át a szöveg színét zöld színűre. A kód talán kissé kaotikusan fest, de ez alapján remélhetőleg nem nagy feladat, ha mondjuk pirosra kéne állítani a szöveg színét!

Ellenőrizzük le, hogy tényleg az történik-e, mint amit szeretnénk, futtassunk egyet!

  • A MainActivity.java fájl 21. sora környékén található „TextView leiras;” sor alá írd be ezt: Button gomb1;. Ezzel készítettünk egy új változót.
  • A 34.sor környékén található leiras = (TextView) findViewById(R.id.leiras); sor alá írd be ezt: gomb1 = (Button) findViewById(R.id.button);. Most értéket adtunk a változónak.
  • A gombnyomást kezelő kódba pedig: gomb1.setTextColor(color.GREEN);. Ezzel pedig a gomb szövegének színét állítottuk be.

Szuper, már nagyon szép színes szövegeket és gombokat tudunk csinálni, de elég unalmasak, mert a szövegük nem változik. Ha figyelmesen dolgoztál, akkor láthattad, hogy amikor a fenti gomb1.setTextColor(Color.GREEN); sort írtad, a pont leütése után megjelent egy kis ablak hol mindenféle függvénynevek vannak felsorolva. A gomb1.setTextColor(Color.GREEN); sor alá kezd el újra beírni, hogy gomb1.set, és a felbukkanó függvények közül próbáld meg kitalálni, hogy melyik lehet az, amelyik a gomb szövegét módosítja!

Csak a függvény nevét figyeld egyelőre! A zárójelben lévő dolgokkal még ne foglalkozz!

Reméljük, te is a „setText” nevű függvényre gondoltál. Ezzel a függvénnyel lehet módosítani minden olyan komponens feliratát/szövegét, amin van valami szöveg. A gombnak például így módosíthatjuk a feliratát: „gomb1.setText("Új felirat");”. Fontos, hogy a szövegeket " " (kettős idézőjelek, Shift+2) közé kell tenni, és a sorvégi pontosvessző se maradjon le!

Ezt az új működést is ellenőrizzük egy futtatással!

Most jön az igazi felhasználói felület

Az előzőekben mindent megtanultunk, ami ahhoz kell, hogy eltudjuk készíteni az alkalmazást! Lássunk hozzá!

3. feladat

Először készítsük el a terven szereplő layout-ot: Nyissuk meg újra az activity_main.xml fájlt, figyeljünk rá, hogy alul a Design fül legyen aktív, és a fent megtanult módszerrel töltsük fel a képernyőt a szükséges komponensekkel.

  1. A képernyő tetején legyen a már korábban létrehozott leírás. Módosítjuk a szövegét, hogy röviden tájékoztassa a felhasználót, mit is várunk tőle. Pl. „Írd be a tippedet!”.
  2. Alatta, középen legyen egy szövegdoboz. A szövegdobozokat a Text Fields kategóriában találjuk, innen a Number komponenst válasszuk ki, amelyik csak számokat enged beírni.
    1. Amikor lerakod a szövegdobozt, észre fogod venni, hogy igen keskeny lett és nem engedi a szélességét átméretezni. Ezen segíthetsz, ha a layout:width tulajdonságát átállítod match_parent-re. Ez meghatározza, hogy a komponens ne a beírt szöveghez méretezze magát, hanem töltse ki a rendelkezésére álló helyet
    2. A hint tulajdonságba megadhatjuk, hogy milyen szöveg jelenjen meg mielőtt a felhasználó elkezd gépelni. pl. "ide írd a számot!", vagy "(szám 1 és 100 között)"
  3. Közvetlen ez alá, középre, helyezzünk el egy újabb gombot, ami segítségével tippelni tudunk majd! Ne felejtsük el átírni a text tulajdonságát!
  4. Az alsó gombunk lesz az újrakezdés gombja, írjuk is át a feliratát ennek megfelelően!
  5. A két gomb közé rakjunk le egy nagy szöveget (TextView, a Widget kategóriában találod). Itt fog megjelenni a tipp eredménye.

A komponensek egyéb tulajdonságait (szöveg mérete, színe stb.) ezek után formázd kedved és ízlésed szerint :-)

4. feladat

Ha sikerült a layout szerkesztőben létrehozni a kívánt felületet, akkor eljött az ideje a Java kód befejezésének (bal oldalt app -> java -> hu.dkrmg.android.guessgame -> MainActivity fájlban).

Először is gondoljuk végig, hogy milyen eseményekre kell reagálnia a telefonnak:

4.1. feladat

Az újrakezdés gombhoz elvileg még megvan az eseménykezelőnk (2. feladatból a buttonClicked függvény, ami a Toast üzenetet dobta). Ezt alakítsuk át, hogy a függvény belsejében csak az alábbi sor legyen:

gondoltSzam = randomGenerator.nextInt(100) + 1;

Ez garantálja, hogy a gondoltSzam változóban egy véletlen szám legyen. A randomGenerator nextInt(100) függvénye egy véletlen számot ad vissza a (0, 1, 2, 3, ..., 99) számok közül. Figyelj, 100 nem lehet, 0 viszont igen! Ezért kell a végén egy +1, hogy mindenképpen az 1, 2, 3, …, 99, 100 számok valamelyikére gondoljon a telefon.

4.2. feladat

A felhasználó visszajelzése egy picit hosszabb lesz ennél!

Ahhoz, hogy megtudjuk, hogy mit tippelt a játékos, először szükségünk lesz két változóra.

(Segítség: a szövegdobozt tartalmazó változó típusa EditText, az eredményjelzőé pedig TextView).

Ha megvannak a változóink, adjunk nekik értéket is. Ehhez meg kell keresni a belevaló komponenst. Ilyet is csináltunk már, szintén a 2.1. feladatban. (nézd meg a komponenseid azonosítóját – id – azután használd a findViewById függvényt) [TODO 4.2 helyére. 4x!]

4.3. feladat

Most, hogy megfelelően elő vannak készítve a komponenseink, már ki tudjuk olvasni a felhasználó által beírt számot. Ez egy kicsit bonyolultabb (hiszen az EdtiText szöveget tartalmaz, nekünk pedig int típusú változóra van szükségünk), ezért megadjuk a kódot, csak be kell másolni a megfelelő helyre [TODO 4.3]:

// A szövegdoboz nem tudja, hogy a felhasználó számot írt be,
// mindenképp szövegként adja vissza a tartalmát.
String szovegesTipp = VÁLTOZÓ_NEVE.getText().toString();

// Ahhoz, hogy a gondolt számot össze tudjuk hasonlítani a tippel,
// a tippet előbb számmá kell konvertálni.
int tipp = Integer.parseInt(szovegesTipp);

Ha bemásoltad, láthatod, hogy a „VÁLTOZÓ_NEVE” részt az Android Studio csúnya pirossal írja. Ez azért van, mert nem ismeri ezt a változót, mivel az nincs deklarálva. Annak a helyére kell nektek beírnotok a ti változótok nevét, amiben a szövegdobozt tároljátok (kicsit feljebb csináltuk meg).

Ezek után a felhasználó tippje a tipp nevű, egész szám (int) típusú változóban lesz benne, készen a további felhasználásra.

Kitérő: elágazások

A programunk sokszor egy feltételtől függően több féleképpen is viselkedhet. Esetünkben például: HA a gondoltSzam változó értéke egyenlő a tipp változó értékével, AKKOR írd át a megfelelő TextView szövegét! Pascal-ban találkozhattál esetleg a következővel:

if (gondoltSzam=tipp) then
begin
  // valami kód
end;

A Java nyelvben is hasonlóan módunkban áll feltételeket szabni a programban.

if (feltétel)
{
    // valami kód
}

Ha a zárójelben lévő feltétel igaz, akkor a kapcsos zárójelek közötti rész futtatásra kerül. Utána a program fut tovább.

Tehát pl.

// a feltétel előtti kód mindig lefut

if (gondoltSzam == tipp)
{
    // ez a sor beljebb kezdődik
    // Ami itt van, az csak akkor fut le, ha a gondoltSzam változó értéke egyenlő a tipp értékével
}

// vége a feltételnek. Ami itt van, az mindig le fog futni

4.4. feladat

Vizsgáljuk meg, hogy a gondoltSzam változó (gép által gondolt szám) és a tipp változó értéke hogyan viszonyul egymáshoz!

Írj három if-elágazást [TODO 4.4 helyére], ami megvizsgálja

Ha nagyon elakadtál, akkor .

A feltételeknél a következő legyen a kód. A feltételeket te írd meg!

if (...egyenlő…)
{
// valami.setText("dsaad");
}
if (...tipp kevesebb mint gondoltSzam...)
{
// valami.setText("dsaad");
}
if (... tipp nagyobb mint gondoltSzam...)
{
// valami.setText("dsaad");
}

Ha nem tudod hogyan hasonlíthatod össze a változóidat, akkor kattints

Az összehasonlításnál használd:

a == b egyenlőek?

a < b a kisebb, mint b?

a > b a nagyobb, mint b?

A feltételek belsejében pedig írd át a felirat (eredményjelző) szövegét, illetve állítsd át a színét (pl. pirossal: „kisebbet”, zölddel: „nyertél!”)! Hasonló feladatok már előfordultak korábban :-)

Ha ezt sikerült megírni, próbáljuk ki újra a programot. Immár lényegében kész van, egy dologra kell odafigyelni: Mielőtt elkezdhetnénk az első játékot, meg kell nyomni az Újrakezdés gombot. A későbbiekben megnézzük majd, hogy hogy lehetne ezt megkerülni, de egyelőre nézzük el ezt a kis kellemetlenséget.

Előfordulhat, hogy amikor elindítod a programot, és megnyomod a „Tippelek” gombot, nem történik semmi. Gondolkodj el azon, hogy melyik lépés maradhatott ki! Nézd vissza, hogy az első gombnál miket kellett megcsinálni!

Az elkészült programokat küldjétek el nekünk tömörítve a szakkör feltöltő lapján keresztül!

Szorgalmi feladatok

A következő feladatokat is érdemes megnézni! Ne felejtsétek, programozni gyakorlással lehet megtanulni!

A leckéhez tartozó szorgalmi feladatok ezen a lapon érthetőek el.