A common memory matching game played by young children is to start with a deck of cards that contain identical pairs. For example, given six cards in the deck, two might be labeled “1,” two might be labeled “2,” and two might be labeled “3.” The cards are shuffled and placed face down on the table. The player then selects two cards that are face down, turns them face up, and if they match they are left face up. If the two cards do not match, they are returned to their original position face down. The game continues in this fashion until all cards are face up.
Write a program that plays the memory matching game. Use 16 cards that are laid out in a 44 square and are labeled with pairs of numbers from 1 to 8. Your program should allow the player to specify the cards that she would like to select through a coordinate system.
For example, suppose the cards are in the following layout:
1 2 3 4
-------------------------
1| 8 * * *
2| * * * *
3| * 8 * *
4| * * * *
All of the cards are face down except for the pair 8, which has been located at coordinates (1, 1) and (2, 3). To hide the cards that have been temporarily placed face up, output a large number of newlines to force the old board off the screen.
Hint: Use a two-dimensional array for the arrangement of cards and another two-dimensional array that indicates if a card is face up or face
down. Write a function that “shuffles” the cards in the array by repeatedly selecting two cards at random and swapping them. Random number generation is described in Appendix 4.
PROGRAM CODE:
//Header file section
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
const int ROWS = 4;
const int COLS = 4;
const int TOTAL_CARDS = ROWS * COLS;
const int MAX_PAIRS = TOTAL_CARDS / 2;
const int MAX_CARD_VALUE = 8;
// Function to shuffle the cards in the array
void shuffleCards(int cards[][COLS], bool faceUp[][COLS]) {
srand(static_cast<unsigned int>(time(0)));
for (int i = 0; i < MAX_PAIRS; i++) {
int card1Row, card1Col, card2Row, card2Col;
// Find two random cards that are face down
do {
card1Row = rand() % ROWS;
card1Col = rand() % COLS;
} while (faceUp[card1Row][card1Col]);
do {
card2Row = rand() % ROWS;
card2Col = rand() % COLS;
} while (faceUp[card2Row][card2Col] || (card1Row == card2Row && card1Col == card2Col));
// Swap the values of the two cards
int temp = cards[card1Row][card1Col];
cards[card1Row][card1Col] = cards[card2Row][card2Col];
cards[card2Row][card2Col] = temp;
}
}
// Function to display the current state of the board
void displayBoard(int cards[][COLS], bool faceUp[][COLS]) {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (faceUp[i][j]) {
cout << cards[i][j] << " ";
} else {
cout << "* ";
}
}
cout << endl;
}
}
int main() {
int cards[ROWS][COLS];
bool faceUp[ROWS][COLS] = {false}; // Initialize all cards to face down
// Assign pairs of numbers to the cards
for (int i = 1; i <= MAX_CARD_VALUE; i++) {
for (int j = 0; j < 2; j++) {
int row, col;
do {
row = rand() % ROWS;
col = rand() % COLS;
} while (cards[row][col] != 0);
cards[row][col] = i;
}
}
shuffleCards(cards, faceUp); // Shuffle the cards
// Game loop
while (true) {
displayBoard(cards, faceUp);
// Ask the user for two coordinates
int row1, col1, row2, col2;
cout << "Enter the coordinates of two cards (row1 col1 row2 col2): ";
cin >> row1 >> col1 >> row2 >> col2;
// Ensure the coordinates are valid
if (row1 >= 1 && row1 <= ROWS && col1 >= 1 && col1 <= COLS &&
row2 >= 1 && row2 <= ROWS && col2 >= 1 && col2 <= COLS) {
// Convert to zero-based indexing
row1--; col1--; row2--; col2--;
// Check if the cards are face down and not the same position
if (!faceUp[row1][col1] && !faceUp[row2][col2] && (row1 != row2 || col1 != col2)) {
// Reveal the selected cards
faceUp[row1][col1] = true;
faceUp[row2][col2] = true;
// Check if the cards match
if (cards[row1][col1] == cards[row2][col2]) {
cout << "Match! You found a pair." << endl;
} else {
cout << "No match. Try again." << endl;
// Wait for a moment to display the selected cards
for (int i = 0; i < 100000000; i++) {}
// Hide the selected cards again
faceUp[row1][col1] = false;
faceUp[row2][col2] = false;
}
// Check if all cards are face up (game is over)
bool allFaceUp = true;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (!faceUp[i][j]) {
allFaceUp = false;
break;
}
}
if (!allFaceUp) {
break;
}
}
if (allFaceUp) {
cout << "Congratulations! You have matched all the pairs." << endl;
break;
}
} else {
cout << "Invalid selection. Try again." << endl;
}
} else {
cout << "Invalid coordinates. Try again." << endl;
}
// Clear the screen to hide the temporarily revealed cards
for (int i = 0; i < 100; i++) {
cout << endl;
}
}
return 0;
}
OUTPUT:
* * * *
* * * *
* * * *
* * * *
Enter the coordinates of two cards (row1 col1 row2 col2): 1
2
3
4
No match. Try again.
* * * *
* * * *
* * * *
* * * *
Enter the coordinates of two cards (row1 col1 row2 col2): 2
3
4
3
No match. Try again.
* * * *
* * * *
* * * *
* * * *