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ě.