Czech version
logolink

< Back to the list of lessons

Memory Game IV

AlgortimyContent of the lesson:

  • Turning Cards - Part II
  • Initializing Players
  • Entering Number of Players
  • Entering Names of Players

Handling Problems When Turning Cards

We completed the easier version of our procedure to turn a card. However, we did not treat any errors like an attempt to turn the same card twice or entering a value out of bounds of array. The procedure otockarticku has this appearance:

Turning a card
procedure otockarticku(var radek,sloupec:byte);
begin
    p[radek, sloupec].viditelna := true;
end;

You have to treat these errors which can occur:

  • Turning the same card twice
  • Turning already removed card
  • An attempt to turn a card out of bounds of array pexeso

We will use a cycle to repeat the entering process to be able to treat this three problems.

Create a new variable named kartickaok for this purpose which will store the information whether the cycle should be run once again.

After launching the procedure, the variable is set to false to run the cycle once at least. A player will be asked to enter the value of row and column inside the cycle. After entering values they are checked because the same card cannot be turned twice. In case this condition is valid, the variable kartickaok is set to true and the cycle is terminated. You will treat two of three problems using this method ("Turning the same card twice" and "Turning already removed card").

Turning a card
procedure otockarticku(var radek,sloupec:byte);
var kartickaok : boolean;
begin
    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;

Then you have to treat the situation when user enters one or both values out of bounds of the array pexeso. Add two more cycles behind the entering mechanism - one to repeat entering the row in case the value is not valid and the other one to repeat entering the column in case the value is not valid. A valid number must be in interval 1 to n.

After this adjustment our procedure should look like the following one:

Turning a card
procedure otockarticku(var radek,sloupec:byte);
var kartickaok : boolean;
begin
    while kartickaok = false do
    begin
        writeln('Enter row: ');
        readln(radek);
        
        while (radek < 1) or (radek > n) do
        begin
            writeln('Enter row again: ');
            readln(radek);
        end;

        writeln('Enter column: ');
        readln(sloupec);
        
        while (sloupec < 1) or (sloupec > n) do
        begin
            writeln('Enter column again: ');
            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;

To be able to debug our program we should adjust the main part of the program which calls the procedure to turn a card. We will not load the coordinates in the main part but in the procedure otockarticku.

Delete these lines from the main part:

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);
And insert the call to procedure otockarticku:
otockarticku(radek1,sloupec1);
otockarticku(radek2,sloupec2);

Initializing Players

In previous lessons we dealt with the cards only. Now we can move to the next part - to the players. At first you have to initialize (to set default values) the array of players. We made the same operation when creating cards and filling them with default values.

Players are realized as an array of structures (of data type record) which consists of these variables:

  • Name - unique identifier of each player. Use string data type (can store up to 255 characters).
  • Score - the number of removed couples by this player. Use byte data type (values will be in interval 0-18).

We will set the name to void and the score to 0 for the whole array (using the variable maxhracu).

Initializing players
procedure inicializacehracu;
var i:byte;
begin
    for i:=1 to maxhracu do
    begin
        ph[i].jmeno:='';
        ph[i].skore:=0;
    end;
end; 

Using the for cycle to go through the array. You should use the variable i, which is increased from 1 to maxhracu and goes through the whole array ph (where we store our players).

Entering Number of Players

To be able to enter the number of players we have to define a new global variable to store the number or players. This variable has to be global to be accessible from any procedure as well as from the main part.

Name the variable as pocethracu and use the byte data type.

The following source code illustrates the basic version of our procedure:

Entering Number of Players
procedure zadejpocethracu;

begin
    writeln('Enter number of players>');
    readln(pocethracu);
end;

This procedure is quite simple; it only writes the text using the loaded variable from user.

This simple variant has one huge disadvantage - user can enter any value although we defined the upper limit of players using the maxhracu constant. You can remove this problem using the while cycle and these steps:

  • Load the value of pocethracu using the current version of procedure at first.
  • Add a while cycle behind it to be executed as long as the variable pocethracu is lower than 2 or greater than the value of maxhracu. An error message should be written inside this cycle and it should ask user to re-enter the value.
Entering Number of Players - Final Version
procedure zadejpocethracu;

begin
    writeln('Enter number of players>');
    readln(pocethracu);
    while ((pocethracu<2) or (pocethracu>maxhracu)) do
    begin
        writeln('Enter again>');
        readln(pocethracu);

    end;
end;

Entering Names of Players

The next step is entering the names of players. Create a new procedure using a simple for cycle which goes through the array of players (from 1 to pocethracu - this value was acquired using the zadejpocethracu procedure) and asks each player to enter his name.

Entering Names of Players
procedure zadejjmenahracu;

var i:byte;
begin
  writeln('Enter names of players>');
  for i:=1 to pocethracu do
  begin
     readln(ph[i].jmeno);
  end;
end;

You can edit the procedure to show information like "Enter name of Player 1:", "Enter name of Player 2:" and so on.

Entering Names of Players
procedure zadejjmenahracu;

var i:byte;
begin
  writeln('Enter names of players:');
  for i:=1 to pocethracu do
  begin
     writeln('Enter name of Player ', i, '>'); 
     readln(ph[i].jmeno);
  end;
end;

Adding Calls to Procedures to the Main Program

To be able to test everything you have to add calls to all procedures you have created of course. The entire source code using upgrades from this lesson is available below this text.

The entire source code
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
    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áš