Obsah lekce:
Před vytvoření popisu algoritmu pro průběh hry je třeba vytvořit ještě jednu proceduru a touto procedurou bude porovnání kartiček. Po otočení dvojice kartiček je třeba zjistit, zda jsou kartičky shodné a v případě, že shodné jsou, tyto kartičky odebrat a upravit skóre daného hráče.
Potřebnou proceduru pojmenujeme porovnejkarticky a na vstupu bude celkem 5 vstupních hodnot:
procedure porovnejkarticky(var x1,y1,x2,y2:byte; var shodne:boolean); begin if p[x1,y1].obrazek=p[x2,y2].obrazek then shodne:=true else shodne:=false; end;
Do této procedury zatím pouze doplníme podmínku, která porovná dvě kartičky pexesa a pokud je hodnota obrazek shodná, procedura uloží do proměnné shodne hodnotu true (pravda), v opačném případě doplní do této proměnné hodnotu false (nepravda).
Následně proceduru ještě rozšíříme. V případě, že jsou kartičky shodné, tak se provedou dvě úpravy hodnot u těchto kartiček:
procedure porovnejkarticky(var x1,y1,x2,y2:byte; var shodne:boolean); begin p[x1,y1].viditelna:=false; p[x2,y2].viditelna:=false; if p[x1,y1].obrazek=p[x2,y2].obrazek then begin p[x1,y1].odebrana:=true; p[x2,y2].odebrana:=true; shodne:=true; end else shodne:=false; end;
Kromě přidání několika piřazení hodnot bylo nutné příkazy v bloku IF umístit do bloku BEGIN ... END. Důvodem je použití více příkazů u větve IF. V případě jednoho příkazu je možné používat bez BEGIN ... END tak, jako v předchozím příkladu.
Pro správnou funkci programu Pexeso chybí již jen jedna procedura. Touto procedurou je část programu, která bude řídit průběh hry. Proceduru si pojmenujeme hra.
Procedura hra nebude mít žádné vstupní parametry, ale bude nutné si definovat několik lokálních proměnných:
Uveďme si tedy nejprve základní kostru procedury hra doplněnou o tyto lokální proměnné. Následně si doplníme i další příkazy a funkce této procedury.
procedure hra; var konechry,shodnekarticky:boolean; hrac,radek1,radek2,sloupec1,sloupec2:byte; begin end;
Následně již můžeme definovat průběh hry. Základem bude cyklus while, který bude prováděn, pokud proměnná konechry bude mít hudnotu false. Jakmile se změní na true, hra bude ukončena.
Před spuštěním tohoto cyklu je třeba nastavit proměnnou konechry na hodnotu false a také je tžeba nastavit výchozí hodnotu pro proměnnou hrac. Tato proměnná bude určovat, který hráč je na řadě a na počátku bude mít hodnotu 1.
procedure hra; var konechry,shodnekarticky:boolean; hrac,radek1,radek2,sloupec1,sloupec2:byte; begin hrac:=1; konechry := false; while konechry = false do begin zobrazenipexesa; otockarticku(radek1,sloupec1); zobrazenipexesa; otockarticku(radek2,sloupec2); zobrazenipexesa; porovnejkarticky(radek1,sloupec1,radek2,sloupec2,shodnekarticky); if shodnekarticky then begin ph[hrac].skore := ph[hrac].skore+1; end else begin if hrac<>pocethracu then hrac := hrac + 1 else hrac := 1; end; readln; end; end;
Uvnitř cyklu, který bude řídit průběh hry dojde postupně k otočení dvou kartiček (dvě volání procedury otockarticku). Tato procedura zajistí otočení kartičky a uložení jejich souřadnic do proměnných radek1, sloupec1 (případně radek2, sloupec2). Následně jsou kartičky porovnány prostřednictvím procedury porovnejkarticku (do ní vstupují dvě dvojice souřadnic kartičky a proměnná shodnekarticky, do které bude uložena informace, zda jsou kartičky shodné, či nikoliv).
Následně je spuštěna podmínka, která ověří, zda jsou kartičky shodné. Pokud jsou shodné, zvýší skóre aktuálního hráče o 1 (ph[hrac].skore := ph[hrac].skore+1;), v opačném případě se zvýší číslo hráče o 1 (nebo se změní na 1, pokud byl na řadě poslední hráč v pořadí).
Důležité je ještě volání procedury zobrazenipexesa po každé změně (otočení kartičky, vyhodnocení stejných kartiček, ...).
Tento cyklus se opakuje, pokud ve hře zůstávají nějaké kartičky.
Pro správnou funkci programu doplníme ještě ošetření konce hry (změna proměnné konechry na hodnotu true).
procedure hra; var konechry,shodnekarticky:boolean; hrac,radek1,radek2,sloupec1,sloupec2:byte; pocet, i : byte; begin hrac:=1; konechry := false; while konechry = false do begin zobrazenipexesa; otockarticku(radek1,sloupec1); zobrazenipexesa; otockarticku(radek2,sloupec2); zobrazenipexesa; porovnejkarticky(radek1,sloupec1,radek2,sloupec2,shodnekarticky); if shodnekarticky then begin ph[hrac].skore := ph[hrac].skore+1; pocet := 0 for i := 1 to pocethracu do begin pocet := pocet + ph[i].skore; end; if pocet = (n*n div 2) then konechry = true; end else begin if hrac<>pocethracu then hrac := hrac + 1 else hrac := 1; end; readln; end; end;
Následně v hlavní části programu odstraníme všechny pokusné výpisy a nahradíme je voláním procedury hra. Po této úpravě bude tato část kódu vypadat následovně:
.. begin { TODO -oUser -cConsole Main : Insert code here } inicializacepexesa; zamichanipexesa; inicializacehracu; zadejpocethracu; zadejjmenahracu; hra; readln; end.
Aktuálně je již program plně funkční. Pro kompletaci programu chybí již jen výstup do prohlížeče, aby bylo pexeso lépe vzualizováno. Tomuto úkolu bude věnována příští lekce.
Pro úplnost je opět vhodné uvěst kompletní kód našeho programu.
program pexeso1; {$APPTYPE CONSOLE} uses SysUtils; const n=6; maxhracu=4; type karticka = record obrazek:byte; viditelna:boolean; odebrana:boolean; end; hrac = record jmeno:string; skore:byte; end; hraci=array[1..maxhracu]of hrac; pexeso=array[1..n,1..n]of karticka; var p:pexeso; ph:hraci; radek, sloupec : byte; radek1, sloupec1, radek2, sloupec2 : byte; pocethracu : byte; procedure inicializacepexesa; var radek, sloupec : byte; pocet : byte; begin pocet := 1; for radek := 1 to n do begin for sloupec := 1 to n do begin pocet := pocet + 1; p[radek, sloupec].obrazek := pocet div 2; p[radek, sloupec].viditelna := false; p[radek, sloupec].odebrana := false; end; end; end; procedure zamichanipexesa; var radek, sloupec : byte; r, s : byte; pom : byte; begin for radek := 1 to n do begin for sloupec := 1 to n do begin r := random(n) + 1; s := random(n) + 1; pom := p[radek, sloupec].obrazek; p[radek, sloupec].obrazek := p[r, s].obrazek; p[r, s].obrazek := pom; end; end; end; procedure zobrazenipexesa; var radek, sloupec : byte; begin for radek := 1 to n do begin for sloupec := 1 to n do begin IF p[radek, sloupec].odebrana THEN write('X ') ELSE IF p[radek, sloupec].viditelna THEN write(p[radek, sloupec].obrazek,' ') ELSE write('0 '); end; writeln; end; writeln; end; procedure otockarticku(var radek,sloupec:byte); var kartickaok : boolean; begin while kartickaok = false do begin writeln('Zadejte souradnice karticky (radek): '); readln(radek); while (radek < 1) or (radek > n) do begin writeln('Zadejte znovu souradnice karticky (radek): '); readln(radek); end; writeln('Zadejte souradnice karticky (sloupec): '); readln(sloupec); while (sloupec < 1) or (sloupec > n) do begin writeln('Zadejte znovu souradnice karticky (sloupec): '); readln(sloupec); end; if (p[radek,sloupec].odebrana = false) and (p[radek,sloupec].viditelna = false) then begin kartickaok :=true; p[radek,sloupec].viditelna:=true; end; end; end; procedure inicializacehracu; var i:byte; begin for i:=1 to maxhracu do begin ph[i].jmeno:=''; ph[i].skore:=0; end; end; procedure zadejpocethracu; begin writeln('Zadejte pocet hracu>'); readln(pocethracu); while ((pocethracu<2) or (pocethracu>maxhracu)) do begin writeln('Zdejte znovu>'); readln(pocethracu); end; end; procedure zadejjmenahracu; var i:byte; begin writeln('Zadejte jmena hracu:'); for i:=1 to pocethracu do begin writeln('Zadejte jmeno ', i, '. hrace>'); readln(ph[i].jmeno); end; end; procedure porovnejkarticky(var x1,y1,x2,y2:byte; var shodne:boolean); begin p[x1,y1].viditelna:=false; p[x2,y2].viditelna:=false; if p[x1,y1].obrazek=p[x2,y2].obrazek then begin p[x1,y1].odebrana:=true; p[x2,y2].odebrana:=true; shodne:=true; end else shodne:=false; end; procedure hra; var konechry,shodnekarticky:boolean; hrac,radek1,radek2,sloupec1,sloupec2:byte; pocet, i : byte; begin hrac:=1; konechry := false; while konechry = false do begin zobrazenipexesa; otockarticku(radek1,sloupec1); zobrazenipexesa; otockarticku(radek2,sloupec2); zobrazenipexesa; porovnejkarticky(radek1,sloupec1,radek2,sloupec2,shodnekarticky); if shodnekarticky then begin ph[hrac].skore := ph[hrac].skore+1; pocet := 0 for i := 1 to pocethracu do begin pocet := pocet + ph[i].skore; end; if pocet = (n*n div 2) then konechry = true; end else begin if hrac<>pocethracu then hrac := hrac + 1 else hrac := 1; end; readln; end; end; begin { TODO -oUser -cConsole Main : Insert code here } inicializacepexesa; zamichanipexesa; inicializacehracu; zadejpocethracu; zadejjmenahracu; hra; readln; end.
Upravte proceduru zobrazpexeso tak, aby zobrazovala i jména hráčů a počty jejich bodů. Do procedury hra přidejte informaci, který hráč je na řadě.