Content of the lesson:
In the previous lesson we defined every important variable for our Memory Game. Before trying to fill these variables we can try to write the output of our Memory Game to console.
The Memory Game is saved into 2D array of structures (we will use the variable obrazek from these structures). A structure is a data type called record which can contain many variables inside itself (in our case it contains obrazek, viditelna and odebrana).
To write the array to console you will need 2 nested for cycles which will go through all rows and columns. You should also create two new variables (radek and sloupec) where the current position will be saved. These variables have to be defined in the var part (at the beginning of the program).
Once the variables are created, we can write the current content of our Memory Game to the console. To write the content of any 2D array you have to use two nested for cycles. The first one will go through rows and the other one will go through values in each row (that means columns). For every couple [radek, sloupec] you should write the value obrazek of structure p. An additional space was added so the result is better readable.
After the end of the inner cycle you have to break the line (command writeln;). Place the commands into the block between begin - end behind the definitions of variables.
Add a space to the function write to be able to recognize every written value. The space can be added after adding a comma and a space between ' ' characters.
for radek := 1 to n do begin for sloupec := 1 to n do begin write(p[radek, sloupec].obrazek,' '); end; writeln; end;
After launching the program you can see that the value of variable obrazek is set to 0 for all images. This is caused by our mistake - we did not initialize the variable obrazek using another value so the value 0 was initialized automatically.
In the previous step we saw that all values of the variable obrazek are set to 0. However, we need them to be set as 1-18. We have an array of 6x6 fields which gives us 36 cards (18 couples because every card is duplicated once inside the array).
Our task is to find a way to place random values inside our array (do not forget that every value has to be placed twice)
Placing values inside the fields of the Memory Game can be done using more ways (we will not shuffle the content). You can fill the array with values 1, 1, 2, 2, 3, 3, ... or gradually using values 1-18.
The first variant means that we will fill our array with the values 1-18 and 1-18 once again. The source code is available here:
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;
We use an auxiliary variable pocet which will be increased after each pass in the cycle. Create this variable using the same steps as you used for radek and column variables. Set their value to 0 at the beginning and let it be increased by one in every pass). You will use the operator of integer division and increase the result by one. If you did not increase the result by one, you would get results between 0 and 17 (0 mod 18 = 0, 5 mod 18 = 5, 17 mod 18 = 17 a 18 mod 18 = 0) so you have to increase the value by 1 to get a sequence of numbers from 1 to 18 which will be repeated forever.
You also need the integer variable pocet to compute the number of inner passes. Filling variables can look like the following one:
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;
Using this way to fill the array you have to set the variable pocet to 1 at first and then increase it in every step of the inner for cycle. After increasing the value we place the result of integer division of the variable pocet and value 2 to the field p[radek, sloupec].obrazek. This operation will return values 1, 1, 2, 2, 3, 3, ..., 18, 18.
You need the variable pocet again in this variant but you will increase the value only in every second pass of the while cycle. Use the variable sloupec and create a new condition (if the reminder from dividing variable sloupec by 2 is equal to 1, then increase the value of sloupec by one. The code should look like as this one:
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;
We can also introduce this interesting variant which does not use the variable pocet. This variant computes all needed values from the variables radek and sloupec from the cycle. The constant n means the number of columns/rows.
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;
You have seen in the previous variants that most of tasks while programming have more than one solution.
You can choose any variant and add it before the part of your program which writes the values to console. Try the program.
The next step to initialize the Memory Game is to set values for variables viditelna and odebrana which are parts of our structure. In default state no card should be visible so set viditelna to false. The same value (false) should be saved inside odebrana because the game starts with all cards.
Add these two operations inside the cycle which (for now) sets the default value for obrazek (using the variant you have chosen).
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;
To be able to orientate in the source code you should move the whole initialization to a procedure. You can remind yourself of using a procedure:
procedure name (parameters); //parameters are optional var variables //optional declaration of variables for procedure begin commands; end;
Move the definition of variables radek, sloupec and pocet to a new procedure named inicializacepexes - these variables are used as local variables (they are available only for the procedure and not outside it. The other variables which are defined at the beginning of the program are visible for the whole program (they are global). They can be used in every procedure of our program.
This procedure should have ho output parameters.
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;
The complete source code of this program is available here:
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.
After a successful initialization of the array pexeso, the items should contain values as in the following image:
To display the state of the Memory Game it would be better to use images rather than numbers. We are going to create a procedure to write the whole output inside a HTML file which can be opened in any web browser in the next lesson. This file will contain every card of the Memory Game, names of players and their points.
You should use images in format JPG of size 100x100 pixels and rename them as 1.jpg to 18.jpg. You need an additional image for the back side of each card. This image should have the same resolution and be named as 0.jpg.
To be able to continue with our program in the next lesson, we need images. Prepare 18 different images in JPG format of size 100x100 pixels. Save them as 1.jpg to 18.jpg and prepare an additional image (0.jpg) to represent the back side of each card.
Suggest an algorithm to shuffle all cards and try to realize it as a procedure in Pascal.