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 4 input parameters:
The returning value will be the variable to store the information whether these cards are identical.
int porovnejkarticky(int x1, int x2, int y1, int y2) { if (p[x1][y1].obrazek==p[x2][y2].obrazek) return 1; else return 0; }
We added only one condition which compares two cards and if the value of obrazek is the same the procedure saves 1 inside the returning value; otherwise it saves 1 inside the returning value.
You should extend the procedure. In case the cards are identical, two more steps have to be done with these cards:
int porovnejkarticky(int x1, int x2, int y1, int y2) { p[x1][y1].viditelna=0; p[x2][y2].viditelna=0; if (p[x1][y1].obrazek==p[x2][y2].obrazek) { p[x1][y1].odebrana=1; p[x2][y2].odebrana=1; return 1; } else return 0; }
Besides adding a few assignments of values, it was necessary to close the commands inside the IF block to the block { ... }. 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 { ... } 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.
void hra() { int konechry, shodnekarticky; int hrac, radek1, radek2, sloupec1, sloupec2; }
Then we can define the game progress. The base part is the while cycle which will be executed until the value of konechry is 0. The game will be terminated as soon as it changes to 1.
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 0.
void hra() { int konechry, shodnekarticky; int hrac, radek1, radek2, sloupec1, sloupec2; hrac = 0; konechry = 0; while (konechry == 0) { zobrazenipexesa(); otockarticku(); zobrazenipexesa(); otockarticku(); zobrazenipexesa(); shodnekarticky = porovnejkarticky(radek1,sloupec1,radek2,sloupec2); if (shodnekarticky == 1) { ph[hrac].skore = ph[hrac].skore + 1; } else { if (hrac != pocethracu-1) { hrac = hrac + 1; } else { hrac = 0; } } fflush(stdin); getchar(); } }
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 1).
void hra() { int konechry, shodnekarticky; int hrac, radek1, radek2, sloupec1, sloupec2; int pocet; hrac = 0; konechry = 0; while (konechry == 0) { zobrazenipexesa(); otockarticku(); radek1 = rx; sloupec1 = sx; zobrazenipexesa(); otockarticku(); radek2 = rx; sloupec2 = sx; zobrazenipexesa(); shodnekarticky = porovnejkarticky(radek1,sloupec1,radek2,sloupec2); if (shodnekarticky == 1) { ph[hrac].skore = ph[hrac].skore + 1; pocet = 0; for (int i = 0; i < pocethracu; i++) { pocet = pocet + ph[i].skore; } if (pocet == (n*n / 2)) konechry = true; } else { if (hrac != pocethracu-1) { hrac = hrac + 1; } else { hrac = 0; } } fflush(stdin); getchar(); } }
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):
.. int _tmain(int argc, _TCHAR* argv[]) { int radek, sloupec, pocet; inicializacepexesa(); zamichanipexesa(); inicializacehracu(); zadejpocethracu(); zadejpocethracu(); hra(); fflush(stdin); getchar(); ...
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.
#include "stdafx.h" #include <string.h> #define n 6 #define maxhracu 4 typedef struct { int obrazek; int viditelna; int odebrana; } karticka; typedef struct { char jmeno[255]; int skore; } hrac; karticka p[n][n]; hrac ph[maxhracu]; int rx, sx; void inicializacehracu() { int i; for (i = 0; i < maxhracu; i++) { strcpy("",ph[i].jmeno); ph[i].skore=0; } } void zadejpocethracu() { printf("Zadejte pocet hracu: "); scanf("%d",&pocethracu); while ((pocethracu < 2) or (pocethracu > maxhracu)) { printf("Zadejte znovu: "); scanf("%d",&pocethracu); } } void zadejjmenahracu() { int i; printf("Zadejte jmena hracu:\n"); for (i = 0; i < pocethracu; i++) { printf("Zadejte jmeno %d. hrace: ", i+1); scanf("%s", &ph[i].jmeno); } } 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; } } } void zamichanipexesa() { int radek, sloupec; int r, s; int pom; for (radek = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { r = rand()%n; s = rand()%n; pom = p[radek][sloupec].obrazek; p[radek][sloupec].obrazek = p[r][s].obrazek; p[r][s].obrazek = pom; } } } void zobrazenipexesa() { int radek, sloupec; for (radek = 0; radek < n; radek++) { for (sloupec = 0; sloupec < n; sloupec++) { if (p[radek][sloupec].odebrana == 1) { printf("X "); } else { if (p[radek][sloupec].viditelna == 1) { printf("%d ", p[radek][sloupec].obrazek); } else { printf("0 "); } } } printf("\n"); } } void otockarticku() { int radek, sloupec; int kartickaok = 0; p[radek][sloupec].viditelna = 1; while (kartickaok == 0) { printf("Zadejte souradnice karticky (radek): "); scanf("%d", &radek); while ((radek < 0) || (radek > n-1)) { printf("Zadejte znovu souradnice karticky (radek): "); scanf("%d", &radek); } printf("Zadejte souradnice karticky (sloupec): "); scanf("%d", &sloupec); while ((sloupec < 0) || (sloupec > n-1)) { printf("Zadejte znovu souradnice karticky (sloupec): "); scanf("%d", &sloupec); } if ((p[radek][sloupec].odebrana == 0) && (p[radek][sloupec].viditelna == 0)) { kartickaok = 1; p[radek][sloupec].viditelna = 1; } } rx = radek; sx = sloupec; } void hra() { int konechry, shodnekarticky; int hrac, radek1, radek2, sloupec1, sloupec2; int pocet; hrac = 0; konechry = 0; while (konechry == 0) { zobrazenipexesa(); otockarticku(); radek1 = rx; sloupec1 = sx; zobrazenipexesa(); otockarticku(); radek2 = rx; sloupec2 = sx; zobrazenipexesa(); shodnekarticky = porovnejkarticky(radek1,sloupec1,radek2,sloupec2); if (shodnekarticky == 1) { ph[hrac].skore = ph[hrac].skore + 1; pocet = 0; for (int i = 0; i < pocethracu; i++) { pocet = pocet + ph[i].skore; } if (pocet == (n*n / 2)) konechry = true; } else { if (hrac != pocethracu-1) { hrac = hrac + 1; } else { hrac = 0; } } fflush(stdin); getchar(); } } int _tmain(int argc, _TCHAR* argv[]) { int radek, sloupec, pocet; inicializacepexesa(); zamichanipexesa(); inicializacehracu(); zadejpocethracu(); zadejjmenahracu(); hra(); zobrazenipexesa(); fflush(stdin); getchar(); return 0; }
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.