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.