Anglická verze
logolink

< Zpět na seznam lekcí

Hra pexeso IV

AlgortimyObsah lekce:

  • Otočení kartičky - dokončení
  • Inicializace hráčů
  • Zadání počtu hráčů
  • Zadání jmen hráčů

Ošetření problémů u otočení kartičky

Zatím máme dokončenu jednodušší verzi procedury pro otočení kartičky. Neošetřujeme však možné chyby, jako například pokus o znovu otočení stejné kartičky nebo zadání souřadnic mimo rozsah pole našeho pexesa. Proceduru otockarticku máme zatím v následující podobě:

Otočení kartičky
procedure otockarticku(var radek,sloupec:byte);
begin
    p[radek, sloupec].viditelna := true;
end;

V této proceduře je dále nutné ošetřit některé chyby, ke kterým mohlo dojít. Jedná se zejména o následující:

  • Otočení již otočené kartičky
  • Otočení odebrané kartičky
  • Pokus o otočení kartičky mimo rozsah pole pexesa

Tyto tři problematické jevy ušetříme pomocí cyklu, který nám zopakuje zadání hodnot, pokud dojde k nějaké chybě.

Pro tento účel si vytvoříme pomocnou proměnnou kartickaok, která bude uchovávat informaci, zda má být cyklus spuštěn ještě jednou.

Po spuštění procedury se do této proměnné uloží hodnota false, aby byl cyklus spuštěn alespoň jednou. Uvnitř tohoto cyklu následně bude uživatel vyzván k zadání hodnoty řádku a sloupce. Po zadání řádku a sloupce se ověří, zda kartička již nebyla otočena nebo odebrána. Pokud je tato podmínka splněna, uloží se do proměnné kartickaok hodnota true a cyklus je ukončen. Touto úpravou ošetříme dva body ze tří, které jsme stanovili v předchozím textu (konkrétně "Otočení odebrané kartičky" a "Pokus o otočení kartičky mimo rozsah pole pexesa").

Otočení kartičky
procedure otockarticku(var radek,sloupec:byte);
var kartickaok : boolean;
begin
    kartickaok := false;
    while kartickaok = false do
    begin
        writeln('Zadejte souradnice karticky (radek): ');
        readln(radek);

        writeln('Zadejte souradnice karticky (sloupec): ');
        readln(sloupec);
 
        if (p[radek,sloupec].odebrana = false) and (p[radek,sloupec].viditelna = false) then
        begin
            kartickaok :=true;
            p[radek,sloupec].viditelna:=true;
        end;
    end;
end;

Následně je nutné ještě ošetřit situaci, kdy uživatel zadá adresu kartičky mimo rozsah pole pexesa. Do našeho cyklu přidáme na místo po zadání hodnot řádku a sloupce postupně dva cykly: jeden, který zopakuje zadání čísla řádku v případě, že číslo řádku bude mimo povolený rozsah od 1 do n, a druhý, který zopakuje zadání čísla sloupce v případě, že číslo sloupce bude mimo povolený rozsah od 1 do n.

Po této úpravě bude kód procedury pro otočení kartičky vypadat následovně:

Otočení kartičky
procedure otockarticku(var radek,sloupec:byte);
var kartickaok : boolean;
begin
    kartickaok := false;
    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;

Pro potřeby testování programu nyní ještě upravíme hlavní část programu, odkud voláme proceduru pro otočení kartičky pexesa. Nyní již totiž nebudeme načítat souřadnice kartičky v hlavní části programu, ale až v proceduře pro otočení kartičky.

Z hlavní části programu odstraníme následující řádky:

Odstraníme

writeln('Zadejte souradnice 1. karticky (radek): ');
readln(radek1);
writeln('Zadejte souradnice 1. karticky (sloupec): ');
readln(sloupec1);

writeln('Zadejte souradnice 2. karticky (radek): ');
readln(radek2);
writeln('Zadejte souradnice 2. karticky (sloupec): ');
readln(sloupec2);

A ponecháme pouze volání procedury otockarticku:

Ponecháme
otockarticku(radek1,sloupec1);
otockarticku(radek2,sloupec2);

Inicializace hráčů

V předchozích lekcích jsme zatím řešili pouze práci s kartičkami pexesa. Nyní se přesuneme k další části a tou jsou hráči. Nejprve je nutné pole hráčů inicializovat, tj. nastavit jeho výchozí hodnoty. Stejnou operaci jsme již dělali u kartiček pexesa, kde jsme je naplnili výchozími hodnotami obrázku a natavili vlastnosti stavu viditelnosti a odebrání kartičky.

Hráči jsou realizováni opět jako pole struktur, tj. pole datového typu rekord, které se skládá s následujících proměnných:

  • Jméno - jednoznačný identifikátor hráče. Bude datového typu string (umožní tedy uložit až 255 znaků).
  • Skóre - počet uhodnutých dvojic kartiček. Bude datového typu byte (skóre bude nabývat hodnot z intervalu 0-18).

U hráčů budeme postupovat tak, že pro celé pole hráčů nastavíme pro jméno hráče prázdnou hodnotu a pro skóre hodnotu 0. To vše v celém rozsahu pole (ten je dán proměnnou maxhracu).

Inicializace hráčů
procedure inicializacehracu;
var i:byte;
begin
    for i:=1 to maxhracu do
    begin
        ph[i].jmeno:='';
        ph[i].skore:=0;
    end;
end; 

Pomocí cyklu for postupně projdeme pole. Pro tento účel nám poslouží proměnná i, kterou postupně zvyšujeme od 1 do maxhracu a tím postupně procházíme pole ph (pole, ve kterém máme uložené hráče). U každého hráče takto nastavíme jméno na prázdný řetězec a skóre na 0.

Zadání počtu hráčů

Pro zadání počtu hráčů si nejprve vytvoříme globální proměnnou, do které následně uložíme počet hráčů. Proměnná můséí být globální, abychom k ní mohli přistupovat i z procedur, které budou řídit průběh hry.

Proměnnou pro počet hráčů pojmenujeme pocethracu. Bude se jednat o celočíselnou proměnnou typu byte.

Nyní již k samotní proceduře. Její základní verzi zobrazuje níže uvedený kód.

Zadání počtu hráčů
procedure zadejpocethracu;

begin
    writeln('Zadejte pocet hracu>');
    readln(pocethracu);
end;

Výše uvedená procedura vypadá velmi jednoduše. Pouze se vypíše text s požadavkem a načte se hodnota od uživatele.

Tato jednoduchá varianta má však i jeden nedostatek - uživateli je dovoleno zadat libovolnou hodnotu (i když máme definovanou horní hranici počtu hráčů - v proměnné maxhracu). Tento nedostatek lze odstranit pomocí cyklu while. Postup bude následující:

  • Nejprve načteme pomocí stávajícího řešení hodnotu pocethracu.
  • Následovat bude cyklus while, který bude prováděn tak dlouho, dokud proměnná pocethracu bude menší než 2 nebo větší než maxhracu. V tomto cyklu se vypíše informace o chybě a uživatel je vyzván pro zadání nového počtu hráčů.
Zadání počtu hráčů - finální verze
procedure zadejpocethracu;

begin
    writeln('Zadejte pocet hracu>');
    readln(pocethracu);
    while ((pocethracu<2) or (pocethracu>maxhracu)) do
    begin
        writeln('Zdejte znovu>');
        readln(pocethracu);

    end;
end;

Zadání jmen hráčů

Další procedurou, která se týká hráčů je zadání jmen hráčů. Jedná se o proceduru s jednoduchým cyklem for, který postupně projde pole hráčů od 1 do pocethracu (hodnota, kterou jsme získali v proceduře zadejpocethracu) a u každého hráče uživatele vyzve pro zadání jména hráče.

Zadání jmen hráčů
procedure zadejjmenahracu;

var i:byte;
begin
  writeln('Zadejte jmena hracu>');
  for i:=1 to pocethracu do
  begin
     readln(ph[i].jmeno);
  end;
end;

Proceduru si můžeme ještě upravit, aby se u každého hráče zobrazila postupně informace "Zadejte jméno 1. hráče", "Zadejte jméno 2. hráče" apod.

Zadání jmen hráčů
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;

Doplnění volání procedur do hlavní části programu

Abychom mohli testovat chod programu je samozřejmě nutné doplnit volání jednotlivých procedur, které jsme vytvořili, do hlavní části programu. Pro úplnost proto uveďme kompletní program po doplnění úprav z této lekce.

Program po doplnění úprav
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;

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
    kartickaok := false;
    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;

begin
{ TODO -oUser -cConsole Main : Insert code here }

inicializacepexesa;
zamichanipexesa;
inicializacehracu;
zadejpocethracu;
zadejjmenahracu;

for radek := 1 to n do
begin
  for sloupec := 1 to n do
  begin
      write(p[radek, sloupec].obrazek,' ');
  end;
      writeln;
end;
writeln;
zobrazenipexesa;



otockarticku(radek1,sloupec1);
otockarticku(radek2,sloupec2);

zobrazenipexesa;

readln;
end.

webdesign, xhtml, css, php - Mgr. Michal Mikláš