Content
of the lesson:
Before creating the algorithm for the game progress you have to create one more procedure to compare cards. After turning a couple of cards you have to find out whether they are identical or not. In case they are you have to remove these cards and increase the score of the active player.
Create a new procedure named porovnejkarticky which requires 5 input parameters:
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;
We added only one condition which compares two cards and if the value of obrazek is the same the procedure saves true inside the variable shodne; otherwise it saves false inside the variable shodne.
You should extend the procedure. In case the cards are identical, two more steps have to be done with these cards:
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;
Besides adding a few assignments of values, it was necessary to close the commands inside the IF block to the block BEGIN ... END. The reason is that more commands were used inside the IF block. In case you used one command only, you would not have to use the block BEGIN ... END as in the previous sample.
For the proper functioning of the Memory Game we need to add one more procedure. This procedure is the part of program which will control the whole game progress. Create a new procedure and name it hra.
This procedure will not have any input parameters but it will be necessary to define several local variables:
Take a look at the core of the procedure hra supplemented by these local variables. We will add more commands to the procedure in the next part.
procedure hra;
var konechry,shodnekarticky:boolean;
hrac,radek1,radek2,sloupec1,sloupec2:byte;
begin
end;
Then we can define the game progress. The base part is the while cycle which will be executed until the value of konechry is false. The game will be terminated as soon as it changes to true.
Before launching this cycle you have to set the variable konechry to false and also set default value for the variable hrac. This variable sets the active player and the default value is 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;
The while cycle which controls the game progress will gradually turn both cards (it will call the procedure otockarticku twice). This procedure turnes both cards and saves their coordinates inside the variables radek1, sloupec1 (or radek2, sloupec2). Then both cards are compared using the procedure porovnejkarticku (this procedure requires 5 input parameters - both couples of coordinates and the variable shodnekarticky to store the information if the cards are identical or not).
Then you can see a condition to check if the cards are identical. In case they are, the score of the active player is increased by 1 (ph[hrac].skore := ph[hrac].skore+1;); otherwise the variable hrac is increased by one (or set to one in case that the last player was active) to switch the active player.
It is necessary to call the procedure zobrazenipexesa after all changes (turning cards, comparing cards, ...).
This cycle is repeated until any card remains in the game.
Finally, you should handle the end of the game (if the variable konechry is changed to 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;
You should remove all attempts to write values to console and replace them with the procedure hra. This part of source code will look like the following one (after mentioned adjustments):
..
begin
{ TODO -oUser -cConsole Main : Insert code here }
inicializacepexesa;
zamichanipexesa;
inicializacehracu;
zadejpocethracu;
zadejjmenahracu;
hra;
readln;
end.
Our program is fully functional right now. We only have to improve the output to create a better visualization. We will try to output the Memory Game to browser in the next lesson.
For completeness you can see the entire source code below this text.
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
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;
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.
Adjust the procedure zobrazpexeso to be able to display names of players and their scores. Add an information about the active player inside the procedure hra.