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 exiting the inner cycle you have to break the line (command printf("\n");).
Add a space to the function printf to be able to recognize every written value. The space can be added after adding a comma and a space between ' ' characters.
for (radek = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { printf("%d ", p[radek][sloupec].obrazek); } printf("\n"); }
After launching the program you can see that the variable obrazek is not initialized - the program will report an error when trying to output its value. We should correct it and set the default value to 0.
for (radek = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { p[radek][sloupec].obrazek = 0; } }
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 = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { p[radek][sloupec].obrazek = 1 + pocet % 18; pocet = pocet + 1; } }
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 (div) 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 = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { pocet = pocet + 1; p[radek][sloupec].obrazek = pocet / 2; } }
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 = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { if ((sloupec % 2) == 1) pocet = pocet + 1; p[radek][sloupec].obrazek = pocet; } }
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.
for (radek = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { p[radek][sloupec].obrazek := ((radek*n + sloupec) mod 18) + 1; } }
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 0. The same value (0) 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 = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { pocet = pocet + 1; p[radek][sloupec].obrazek = pocet % 2; p[radek][sloupec].viditelna = 0; p[radek][sloupec].odebrana = 0; } }
To be able to orientate in the source code you should move the whole initialization to a function. You can remind yourself of using a function:
datovytyp název (parametry funkce); //parametry jsou volitelné { programový kód funkce; return návratováhodnota; }
Move the definition of variables radek, sloupec and pocet to a new function named inicializacepexes - these variables are used as local variables (they are available only for the function 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 function of our program.
This function should have ho output parameters.
void inicializacepexesa() { int radek, sloupec, pocet; pocet = 1; for (radek = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { pocet = pocet + 1; p[radek][sloupec].obrazek = pocet % 2; p[radek][sloupec].viditelna = 0; p[radek][sloupec].odebrana = 0; } } }
The complete source code of this program is available here:
#include "stdafx.h" #define n 6 #define maxhracu 4 typedef struct { int obrazek; int viditelna; int odebrana; } karticka; typedef struct { char jmeno[255]; int skore; } hrac; void inicializacepexesa() { int radek, sloupec, pocet; pocet = 1; for (radek = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { pocet = pocet + 1; p[radek][sloupec].obrazek = pocet % 2; p[radek][sloupec].viditelna = 0; p[radek][sloupec].odebrana = 0; } } } int _tmain(int argc, _TCHAR* argv[]) { karticka p[n][n]; hrac ph[maxhracu]; int radek, sloupec, pocet; inicializacepexesa(); for (radek = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { printf("%d ", p[radek][sloupec].obrazek); } printf("\n"); } fflush(stdin); getchar(); return 0; }
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 function in C.