Hey, so im trying to make a memory game using 2d arrays.

This is my code to randomly generate the rows and columns but its not giving me pairs, could someone tell me why, i really dont know.

for (int r=0; r<4; r++)
    {
        for (int c=0; c<4; c++)
        {
            cards[r][c]=rand()%8+1;
            cout<<cards[r][c];
        }
        cout<<endl;
    }

Dani AI

Generated

Short answer: your original nested loop gives each cell an independent random value, so there’s no guarantee each value will appear exactly twice. Two reliable approaches are common: (A) build a list that contains each value twice, shuffle it, then copy into the 4×4 grid (simplest and easiest to reason about); or (B) repeatedly pick two different empty cells and place the same value into both (that’s what demonstrated). and are also right that the RNG must be seeded once at program start (don’t reseed inside a loop).

A concise, modern way (approach A) — create the deck, shuffle, then lay it out:

#include <vector>
#include <algorithm>
#include <random>

// build deck with pairs 1..8
std::vector<int> deck;
for (int v = 1; v <= 8; ++v) { deck.push_back(v); deck.push_back(v); }

// shuffle with mt19937
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(deck.begin(), deck.end(), g);

// copy to 4x4 grid
int cards[4][4];
for (int i = 0; i < 16; ++i) cards[i/4][i%4] = deck[i];

Quick debugging points for the program in Post #8 (why you saw only zeros):

  • The loop condition while (nullexists = true) is an assignment; use while (nullexists) or while (true) with a break. The current code never exits that way.
  • counter = counter++; is a no-op. Use ++counter; or counter += 1;.
  • Inside the if you wrote bool nullexists = false; which declares a new local variable and does not change the outer loop flag — remove the bool.
  • User input looks 1..4 on the UI, but arrays are 0..3. Subtract 1 from row/column after reading and validate the indices to avoid UB.
  • Add a debug print showing the two compared cards[...] values right after reading them; that will make it obvious whether the comparison ever succeeds.

Fix those and use the shuffle method for generation. It’s shorter, less error-prone, and makes the matching logic straightforward.

Recommended Answers

All 8 Replies

You forget to initialize random seed:

srand ( time(NULL) );

and this:

cards[r][c]=rand()%8+1;

gives you just one random number.

pecet is correct. Also, don't forget to #include <ctime> so that you can use the time() function.

-D

so i have

srand((unsigned)time(NULL));

already

so what would be the easiest way to generate pairs of random numbers (single digit from 1-9) then?

yep i have ctime already as well, this is just a snippit of my code for generating pairs but im really not sure why it doesnt work

OK first off I would like to say this is not that great of a way to do it but it works. This generates pairs of numbers from 1-8 at random locations in your matrix (I picked 1-8 because you have a 4x4 matrix) and thats pretty much it.

#include <iostream>
#include <time.h>

using namespace std;

int main()
{
	int cards[4][4];
	bool makeNext = false;
	memset(cards, 0, sizeof(cards));
	srand(time(NULL));
	
	for( int i = 1; i < 9; i++ )
	{
		makeNext = false;
		while(!makeNext)
		{
			int x1, y1, x2, y2;
			x1 = rand()%4;
			y1 = rand()%4;
			x2 = rand()%4;
			y2 = rand()%4;
			if( (x1 != x2 || y1 != y2) && (cards[x1][y1] == 0 && cards[x2][y2] == 0) )
			{
				cards[x1][y1] = i;
				cards[x2][y2] = i;
				makeNext = true;;
			}
		}
	}
	
	for( int i = 0; i < 4; i++ )
	{
		for( int c = 0; c < 4; c++ )
		{
			cout << cards[i][c] << " ";
		}
		cout << endl;
	}

	
	
     
	system("PAUSE");
	return 0;
}

why not do something like this:

#include<iostream>
#include<time.h>
using namespace std;
int main()
{
	int random[2];
	srand ((unsigned)time(0));
	for(int x=0;x<2;x++)
	{
		random[x] = (rand() % 8) + 1;
		cout << random[x] << " ";
	}
	cout << endl;
}

Edit: Oops, I read it to fast, you want random PAIRS, sorry. Here is the modified code that will print out pairs.

#include<iostream>
#include<time.h>
using namespace std;
int main()
{
	int random[2];
	for(int x=0;x<2;x++)
	{
		srand ((unsigned)time(0));
		random[x] = (rand() % 8) + 1;
		cout << random[x] << " ";
	}
	cout << endl;
}

In this code random[0] and random[1] are two different numbers. If you would like more pairs simply copy and past with random2[0] and random2[1].

So i have the thing almost completed but since i have been looking at it for the past 12 hours i know im missing something stupid....

Why is it that the code just outputs zeros even when you pick two matching values

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    char comma;
	int row1, column1, row2, column2, cards[4][4], cards_unflipped[4][4] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} , counter(0);

    srand((unsigned)time(NULL));
    
	//fill board with pairs
	bool makeNext = false;
	bool nullexists = true;
	memset(cards, 0, sizeof(cards));
	srand(time(NULL));

		for( int i = 1; i < 9; i++ )
			{
				makeNext = false;
				while(!makeNext)
					{
						int x1, y1, x2, y2;
						x1 = rand()%4;
						y1 = rand()%4;
						x2 = rand()%4;
						y2 = rand()%4;
						if( (x1 != x2 || y1 != y2) && (cards[x1][y1] == 0 && cards[x2][y2] == 0) )
						{
							cards[x1][y1] = i;
							cards[x2][y2] = i;
							makeNext = true;;
						}
					}
			}
					for( int i = 0; i < 4; i++ )
					{
						for( int c = 0; c < 4; c++ )
						{
							cout << cards[i][c] << " ";
						}
						cout << endl;
					}
    //display board
   while (nullexists = true)

   {
	   //selection
    cout<<"Please select the first card row and column seperated by a comma.\n";
    cin>>row1>>comma>>column1;

    cout<<"Please select the second card row and column seperated by a comma.\n";
    cin>>row2>>comma>>column2;

	  
	 
	   if (cards[row1][column1]==cards[row2][column2])

	   {
		    cards_unflipped[row1][column1] = cards[row1][column1];
			cards_unflipped[row2][column2] = cards[row2][column2];


			counter = counter++;
				if (counter == 8)
				{
					bool nullexists = false;
				}

	   }

	   //reveal the flipped cards
    cout<<"    1 2 3 4\n";
    cout<<"  ";
    for (int i=0; i<=8; i++)
    {
        cout<<"-";
    }
    cout<<endl;
    for (int r=0; r<4; r++)
    {
        cout<<r+1<<" | ";
        for (int c=0; c<4; c++)
        {
           
                cout<<cards_unflipped[r][c]<<" ";
            }
		cout<<endl;
        }
        
    }

   cout << "You Won!" << endl;
  

    return 0;
}

quoting restrictment

1.
#include<iostream>
2.
#include<time.h>
3.
using namespace std;
4.
int main()
5.
{
6.
int random[2];
7.
for(int x=0;x<2;x++)
8.
{
9.
srand ((unsigned)time(0));
10.
random[x] = (rand() % 8) + 1;
11.
cout << random[x] << " ";
12.
}
13.
cout << endl;
14.
}


thanx for that source ... it works fine in dev c++ beta 5
though for a console app ... is there any way i could know about keeping the console window open until a key is pressed to close it
and a key to toggle the random number ? thanx in advance.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.