Anglická verze
logolink

< Zpět na seznam lekcí

Hra pexeso II

AlgortimyObsah lekce:

  • Zobrazení kartiček
  • Inicializace hodnot kartiček
  • Řešení inicializace hodnot kartiček pomocí procedury

Výpis hodnot pexesa

V předchozí části jsme se dostali do fáze, kdy máme nadefinovány všechny potřebné proměnné pro naše pexeso. Před tím, než si tyto proměnné naplníme hodnotami, se kterými budeme dále pracovat, si zkusíme naše pole s pexesem vypsat.

Pexeso máme uložené jako dvourozměrné pole struktur (ze kterých budeme vypisovat hodnotu obrazek). Struktura je datový typ record, který může obsahovat v jedné proměnné několik dalších proměnných (v našem případě obrazek, viditelna a odebrana).

Pro vypsání našeho pole budeme potřebovat 2 vnořené cykly for, které nám budou procházet řádky a sloupce. Před vytvořením těchto cyklů si vytvoříme pomocné proměnné radek a sloupec, do kterých nám budou cykly for ukládat aktuální pozici v poli. Tyto dvě proměnné umístíme do části, kde jsme již definovali předchozí proměnné (za příkaz var), a to následovně.

Proměnné pro uložení řádku a sloupce
radek, sloupec : byte;

Když máme vytvořené proměnné, můžeme si vypsat, co naše pexeso aktuálně obsahuje. Pro vypsání obsahu dvourozměrného pole využijeme dva vnořené cykly for. První bude procházet jednotlivé řádky a druhý bude procházet hodnoty v každém řádku (tj. sloupce). Pro každou dvojici [radek, sloupec] je vypsána hodnota obrazek struktury p (doplněná o mezeru, aby byl výpis přehlednější).

Po opuštění vnitřního cyklu je ještě nutné zalomit řádek (příkaz writeln;). Výpis umístíme do bloku begin - end za definicí proměnných.

U funkce write, která nám hodnotu vypíše, přidáme ještě výpis mezery, abychom rozeznali jednotlivé vypsané hodnoty. Mezeru doplníme tak, že do funkce write doplnime za výpis obrázku čárku a mezeru, kterou ohraničíme znaky ' '.

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

Po spuštění programu v této podobě pravděpodobně zjistíme, že hodnota obrazek je u našeho pexesa nastavena na 0 u všech kartiček. To je způsobeno tím, že jsme zatím žádnou hodnotu nenastavili (pole je inicializováno na hodnotu 0).

Pexeso - výchozí hodnota pole

Inicializace pexesa

V předchozím kroku jsme si ověřili, že všechny hodnoty obrázku v pexesu máme nastaveny na hodnotu 0. My ale potřebujeme, aby zde byly dvakrát hodnoty 1-18. Máme totiž pole 6x6 kartiček pexesa, což je celkem 36 kartiček a každá kartička se má vyskytovat dvakrát.

Úkol č. 1

Naším úkolem nyní bude nalezení způsobu, jak do pole našeho pexesa naskládat hodnoty 1-18 tak, aby se vyskytovala každá dvakrát.

Naskládání hodnot do pole pexesa můžeme provést několika způsoby (zatím nebudeme řešit zamíchání pexesa). Například můžeme naplnit pexeso hodnotami 1, 1, 2, 2, 3, 3, ... nebo postupně hodnotami 1 - 18 a 1 - 18.

1. varianta řešení

První varianta nám naplní pole posloupností 1-18, za kterou bude následovat další posloupnost 1-18. Toto řešení bude vypadat následovně:

Proměnná pocet
pocet : byte;
Nastavení výchozích hodnot u kartiček pexesa - varianta 1
pocet := 0;

for radek := 1 to n do
begin
    for sloupec := 1 to n do
    begin
        p[radek, sloupec].obrazek := 1 + pocet mod 18;
        pocet := pocet + 1;
    end;
end;

V této variantě použijeme pomocnou proměnnou pocet, kterou budeme zvyšovat při každém průchodu cyklu. Tuto proměnnou si vytvoříme stejným způsobem, jako předchozí celočíselné proměnné radek a sloupec. Na počátku ji nastavíme na hodnotu 0 a v každém průchodu vnitřního cyklu ji zvýšíme o 1. Pro získání požadovaných hodnot použijeme operátor celočíselného dělení (div) a výsledek zvýšíme o 1. Když bychom použili pouze celočíselné dělení, vracela by nám naše operace výsledek od 0 do 17 (např. 0 mod 18 = 0, 5 mod 18 = 5, 17 mod 18 = 17 a 18 mod 18 = 0), proto k výsledku přičteme hodnotu 1 a získáme posloupnost čísel od 1 do 18, po kterých bude znovu následovat 1-18 (protože pocet bude růst až do hodnoty 35).

Pexeso - varianta 1

2. varianta řešení

I pro druhou variantu naplnění pole budeme potřebovat celočíselnou proměnnou pocet, která nám bude sloužit pro počítání počtu průchodů vnitřního cyklu. Naplnění hodnot pole v tomto případě může vypadat následovně:

Nastavení výchozích hodnot u kartiček pexesa - varianta 2
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;
    end;
    writeln;
end;

U tohoto způsobu naplnění pole (který je uveden výše) nejprve nastavíme proměnnou pocet na hodnotu 1 a následně ji zvýšíme při každém průchodu cyklu. Po zvýšení hodnoty této proměnné uložíme do p[radek, sloupec].obrazek výsledek celočíselného dělení proměnné pocet a hodnoty 2 (použití operátoru div). Tato operace nám bude postupně vracet hodnoty 1, 1, 2, 2, 3, 3, ..., 18, 18.

Pexeso - varianta 2

3. varianta řešení

U třetí varianty řešení opět budeme potřebovat proměnnou pocet, ale budeme ji zvyšovat pouze v každém druhém průchodu cyklu. Pro tuto variantu využijeme proměnnou sloupec a vytvoříme podmínku, kdy pokud zbytek po celočíselném dělení proměnné sloupec číslem 2 bude 1, zvýšíme proměnnou sloupec o 1. Kód programu v tomto případě bue vypadat následovně:

Nastavení výchozích hodnot u kartiček pexesa - varianta 3
pocet := 0;

for radek := 1 to n do
begin
    for sloupec := 1 to n do
    begin
        if (sloupec mod 2) = 1 then pocet := pocet + 1;
        p[radek, sloupec].obrazek := pocet;
    end;
    writeln;
end;
Pexeso - varianta 3

4. varianta řešení

Pro zajímavost si můžeme uvěst i variantu, kde se obejdeme bez pomocné proměnné pocet. V této variantě místo proměnné počet vypočítáme aktuální průchod cyklu z čísla aktuálního řádku a sloupce. Proměnná n nám udává počet sloupců.

Nastavení výchozích hodnot u kartiček pexesa - varianta 4
for radek := 1 to n do
begin
    for sloupec := 1 to n do
    begin
        p[radek, sloupec].obrazek := (((radek-1)*n + (sloupec-1)) mod 18) + 1;
    end;
    writeln;
end;
Pexeso - varianta 4

Na výše uvedených variantách jsme si ukázali, že většina úkolů v oblasti algoritmizace a programování nemá pouze jedno řešení, ale často existuje více cest, jak dojít k požadovanému cíli.

Vybranou variantu můžete doplnit před část programu pro zobrazení hodnot a program vyzkoušet v této úpravě.

V dalším kroku inicializace pexesa je třeba nastavit hodnoty i u proměnných viditelna a odebrana, které jsou součástí naší struktury. Ve výchozím stavu by neměla být viditelná žádná kartička, proto u proměnné viditelna nastavíme hodnotu false. Stejnou hodnotu (false) nastavíme i u proměnné odebrana, protože na začátku hry jsou ve hře všechny kartičky.

Tyto dvě operace přidáme do cyklu, ve kterém jsme si nastavili výchozí hodnotu u proměnné obrazek (u varianty, kterou jsme si vybrali).

Nastavení výchozích hodnot u kartiček pexesa - doplnění
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;
    writeln;
end;

Aby náš program byl přehlednější, přesuneme si naši inicializaci do samostatné procedury. Nejprve si připomeňme, jak proceduru zapsat.

Syntaxe procedury v Pascalu
procedure název (parametry procedury); //parametry jsou volitelné
var proměnné //volitelná deklarace proměnných pro proceduru
begin
  programový kód procedury
end;

Do samostatné procedury inicializacepexesa přesuneme cyklus pro inicializaci pexesa a definici proměnných radek, sloupec a pocet. Takto umístěné proměnné označujeme termínem lokální proměnné. Tyto proměnné tedy budou viditelné pouze uvnitř naší procedury. Naopak proměnné, které jsme umístili na začátek našeho programu, jsou globální. Jsou tedy viditelné ve všech procedurách, které jsou obsaženy v našem programu.

Tato procedura nebude mít žádní vstupní parametry.

Procedura pro inicializaci pexesa
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;
        writeln;
    end;
end;

Kompletní program tedy bude vypadat následovně:

Program doplněný o proceduru pro inicializaci pexesa
program pexeso3po;
{$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;

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;
        writeln;
    end;
end;


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

inicializacepexesa;

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

  end;
      writeln;
end;

readln;
end.

Po úspěšné inicializaci pole pexesa bude pexeso obsahovat hodnoty dle následujícího obrázku.

Pexeso - struktura

Výstup do prohlížeče

Pro zobrazení pexesa bude vhodnější zobrazení obrázků, než výpis čísel, který aktuálně máme. Proto v další části vytvoříme proceduru pro výpis do prohlížeče. Procedura nám vytvoří soubor ve formátu HTML, který bude zobrazovat jednotlivé kartičky pexesa, jména hráčů a počty bodů.

Pro kartičky pexesa použijeme obrázky ve formátu JPG o velikosti 100x100px. Tyto obrázky budou pojmenované 1.jpg až 18.jpg. Navíc bude potřeba jeden obrázek pro rubovou stranu kartiček. Tento obrázek bude mít stejné rozměry a bude pojmenován 0.jpg.

Domácí úkol 1

Abychom v příští části mohli pokračovat s tvorbou výstupu do prohlížeče, budeme potřebovat obrázky. Připravte proto 18 různých obrázků ve formátu JPG s rozměry 100x100 px. Tyto obrázky pojmenujte 1.jpg až 18.jpg. Dále si připravte obrázek pro rub kartiček pexesa se stejnými rozměry. Tento soubor pojmenujte 0.jpg.

Domácí úkol 2

Navrhněte algoritmus pro zamíchání kartiček pexesa a zkuste jej realizovat jako proceduru v Pascalu.

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