Need Help for a pick game

Hey, guys. I am a beginner for C++ programming. I need to program a pick up game, which I need to drop anywhere from 1 to 10 cookies. And I also need get a random number from 1 to 10 for how many cookies you will put in the grid, then loop for as many cookies you are going to put into the grid, getting a random height and random width for the location to put that cookie into the grid. Before putting the cookie in the grid, I need check to see if there is already a cookie there or if the user’s cursor is in that spot. If that spot is already a cookie or the user’s cursor then you MUST get another random height and width and try to put the cookie there.
I printed out the grid and user's cursor. But now I have a problem with putting these cookies into the grid. I have no idea how to check the spot if it is already occupied.
this is the code that I write for putting cookies into the grid:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Coins : public PickUpGame // inheritate from the the class PickUpgame
{
protected:
	int coins; // variable coins
	int point1; // variable for return coins
	int height;
	int width;
	char PutCoins[20][40];
public:
    void NumOfCoins() // function for get random number of coins
	{
		coins = rand() % 10 + 1;// get random number of coins from 1 to 10
	}
	void returncoins()// function for return value for coins
	{
		point1 = coins;// give value of variable to point1 for coins
	}
	int getcoins()// return the value for main function for the number of coins
	{
		return point1;// return the value for the coins
	}
	void Put()
	{	
		for (int i = 0; i <= coins; i++)
		{
		  height = rand() % MAX_HEIGHT; // random number for height between 0 to MAX_HEIGHT
		  width = rand() % MAX_WIDTH; // random number for with between 0 to MAX_WIDTH
		  PutCoins[height][width] = ' ';
		}
     }
	void printcoins()
	{
		for (int i = 0; i <= coins; i++)
		{
			height = rand() % MAX_HEIGHT; // random number for height between 0 to MAX_HEIGHT
			width = rand() % MAX_WIDTH; // random number for with between 0 to MAX_WIDTH
			cout << PutCoins[height][width];
		}
	}
};

I don't have a lot of knowledge about C++; so it will be really nice that someone can help me out with some basic method to complete this assignment
Last edited on
Assuming PutCoins is the grid, you need a constructor that initializes all elements of PutCoins to a known value (probably spaces).

In Put(), your for loop is going to place too many coins. The termination condition should be i<coins.

Also in Put(), why are you setting PutCoins[h][w] to a blank? Isn't that where you want to place a cookie? What's the value of a cookie?

PLEASE USE CODE TAGS (the <> formatting button) when posting code.
It makes it easier to read your code and also easier to respond to your post.
http://www.cplusplus.com/articles/jEywvCM9/
Hint: You can edit your post, highlight your code and press the <> formatting button.



Ok, it is looks better now? Sorry, this is my first time post questions. Actually the class that I inherit from (PickUpGame), is my grid. And I need to write a new class for putting the coins in there. I have no clues how to start this new class which will put coins into the grid. I am not sure that what you mean by a constructor that initializes all elements of PutCoins to a known value. Sorry that I am really not good at programming. The value of my cookie is '0'. I ran this code for once, there is nothing appear in the grid.
Last edited on
Yes, that's much better with the code tags. Thank you.

Actually the class that I inherit from (PickUpGame), is my grid.

If that statement is true, then what is PutCoins[][]?
Since you haven't shown PickUpGame, can't comment on your base class.

And I need to write a new class for putting the coins in there.

You generally don't need a new class for every function you want to add. A class can have many member functions.

You've show that Coins inherits from PickUpGame, but the relationship is not clear.
Inheritance implies a "IS A" relationship. Is Coins a PickUpGame? That may be true if PickUpGame is intended to be the base class for multiple types of games?

I am not sure that what you mean by a constructor that initializes all elements of PutCoins to a known value


A constructor is a function that is called automatically when an object is instantiated.
1
2
3
4
5
void Coins::Coins ()
{  for (int i = 0; i < MAX_HEIGHT; i ++) 
      for (int j=0; j< MAX_WIDTH; j++)
         PutCoins[height][width] = ' ';	// Initialize cell to SPACE
}







My professor provide me a class ( PickUpGame), the code is :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class PickUpGame
{
protected:
	char Screen[MAX_HEIGHT][MAX_WIDTH]; //The grid to print to the screen
	int xPos, yPos; //The current x and y position of the users cursor on the grid

public:
	//Constructor that will intialize the screen and x and y positions
	PickUpGame() : xPos(0), yPos(MAX_WIDTH - 1)
	{
		SetupScreen(); //Initalize the grid
	}

	//Initialize the screen with all '.' characters and set the intial user cursor position on the grid
	void SetupScreen()
	{
		for (int height = 0; height < MAX_HEIGHT; height++) {
			for (int width = 0; width < MAX_WIDTH; width++) {
				Screen[height][width] = '.'; //Initialize each grid position
			}
		}
		Screen[xPos][yPos] = '<'; //Set the users initial cursor position
	}

	//Print the grid to the screen
	void Print()
	{
		for (int height = 0; height < MAX_HEIGHT; height++) {
			for (int width = 0; width < MAX_WIDTH; width++) {
				cout << Screen[height][width]; //Print the character at this location in the grid
			}
			cout << endl; //After each row is printed, print a newline character
		}
	}

	//Take in user input to move around the grid
	void Move(char Direction)
	{
		switch (static_cast<int>(Direction)) //Don't know the ASCII characters for the arrow keys so use the ASCII numbers
		{
		case 72: //Up arrow
			Screen[xPos][yPos] = ' '; //Wipe out the users current cursor
			xPos--; //Move the users x position on the grid
			Screen[xPos][yPos] = '^'; //Move the users cursor
			break;
		case 80: //Down arrow
			Screen[xPos][yPos] = ' ';
			xPos++;
			Screen[xPos][yPos] = 'V';
			break;
		case 75: //Left arrow
			Screen[xPos][yPos] = ' ';
			yPos--;
			Screen[xPos][yPos] = '<';
			break;
		case 77: //Right arrow
			Screen[xPos][yPos] = ' ';
			yPos++;
			Screen[xPos][yPos] = '>';
			break;
		}
	}
};

I cannot modify anything in this class. so I need to build a new class and inherit ( PickUpGame ). In the class that I build, I need to finish all these putting coins tasks. I am sorry for poor explanation, I am not a native English speaker.
That makes sense now and changes some of my earlier comments.

Line 4: PickUpGame() declares Screen[][], as a protected member. This means you can modify Screen in your derived class. No reason for you to declare PutCoins[][]. In fact, doing so will guarantee that your program will not work correctly with your professor's framework.

Line 9: The constructor for PickUpGame calls SetupScreen() which initializes every cell of the Screen array to '.'. You should treat '.' as an empty cell.

Your printcoins() function is not required. A Print() function has already been provided in the base class.

Note that none of the functions in the base class are virtual, so you can not overload any of the provided functions.

Edit: Going back to your OP.
- You still need a constructor for your Coins class so that you can initialize your variables.
Line 5: Not clear what point1 is used for.
Line 6,7: height and width should be local variables (inside Put). No need to make them member variables. They don't represent the state of your class.
Line 8: Get rid of the PutCoins array. You need to use the Screen array in the base class.
Line 10: The purpose of NumCoins is clear. You never call it though.
Lines 14,18: Unclear what the purpose of returnscoins() and getcoins() is.
Line 24: You're going to place too many coins. The termination condition should be i<coins
Line 28: You're replacing the default contents of a cell with a space. You said earlier the value of a cookie is a '0'. Shouldn't that be what you place here? Also, if you want to make sure you don;t place a cookie where you have already placed one, you should have an if statement to see if there is already a cookie there.
Lines 31-39: As stated, your print function is unneeded.

Last edited on
Thanks. Well, I spent a lot time to figure out this program. I finally came up with something. Here is the code that I wrote:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
class Collectcoins : public PickUpGame // inherite from PickUpGame class
{
private: 
	int totalcoins;// total amount of coins
	int coinsleft;// coins left in the grid
	const char Coinsign = '$'; // the value of coins
public:
	Collectcoins() 
	{
		SetupScreen();
	}
	
/*******************************************************************************
 * Function Name: SetupScreen()
 * Parameters: 
 * Return Value: 
 * Purpose: keep printing out the grind from the class(PickUPGame), at the same time
 place coins in the grid. Take random amount of coins between 1 to 10, and place
 random place in the grid. At the same time, check if the location is free.
 *******************************************************************************/
	
	void SetupScreen() 
	{
		int vertical; // vertical value for coin
		int horizontal; // horizontal value for coin
		totalcoins = rand() % 10 + 1; // get random number between 1 to ten
		coinsleft = totalcoins; // total coins have the same value as coins left
		do { // start of the do loop
			vertical = rand() % MAX_HEIGHT; // get random number for vertical between 0 to max height
			horizontal = rand() % MAX_WIDTH; // get random number for horizontal between 0 to max width
			if (Screen[vertical][horizontal] != Coinsign && Screen[vertical][horizontal] != Screen[xPos][yPos])
			// decision statement to see if the spot is occupied
			{
				Screen[vertical][horizontal] = Coinsign; // if nothing at that spot, put coins
				coinsleft--; // coins getting one less
			}
		} 
		while (coinsleft > 0); // requirement for start the loop
		coinsleft = totalcoins; // after user pick up the coins, the left amount of coins and total amount of coins stay same
	}
	
/*******************************************************************************
 * Function Name: MoveCheck()
 * Parameters: i
 * Return Value: int
 * Purpose: check if user's move is out of boundary
 *******************************************************************************/
	
	void MoveCheck(int i)
	{
		if (xPos - 1 < 0)// check if the movement is outof boundry
		{
		    Move(i);
		}
		if (xPos + 1 >= MAX_HEIGHT)
		{
			Move(i);
		}
		if (yPos - 1 < 0)
		{
		    Move(i);
		}
		if (yPos + 1 >= MAX_WIDTH)
		{
		    Move(i);
		}
	}
   int return1() 
	{
		return totalcoins; // return the value of total coins
	}
	int return2()
	{
		return coinsleft; // return the value of the coins left in the grid
	}
};

/*******************************************************************************
 * Function Name: main()
 * Parameters: None
 * Return Value: 
 * Purpose: call out all the member functiona and classes, to run the 
 allpication. Ask user if they want to play again, after finishing the 
 game.
 *******************************************************************************/

int main()
{
	char UserMove = ' '; //This is used to store the users input
	srand(time(0)); // for random number generator
	system("cls"); // clean the screen
	cout << "Welcome to coins pickup. You will move to the basket by using the arrow keys." << endl; //Program intro
	system("pause"); // pause the screen
	do { // start the loop unitl user answer is n or N
		Collectcoins* Game = new Collectcoins; //Create a new game object and store it in a object pointer
		do {
			system("cls"); //Clear the screen before printing anything
			Game->Print(); //Print the grid out
			cout << "What direction would you like to move in? \n(Move using the arrow keys or type q to quit.) "; //Instructions to the user
			UserMove = _getche(); //Get one character from the user (Visual Studio 2010 "_getche()" is the new version of "getche()")
			Game->MoveCheck(UserMove); // checking user is out of boundary or not
			Game->Move(UserMove); //Process the users input
			if (UserMove == 'q' || UserMove == 'Q') // check if user input q 
			{
				return 0; // if user input q finish application
			}
			if (Game->return2() == 0) // check if there is coins left
			{
				cout << "Congratulations!! You found all the coins!!" << endl; // output for winning the game
				cout << "Would you like to play again? (Y/N)" << endl; // ask user if want to play again
				UserMove = _getch(); // store user's answer
			}
		}
		while (UserMove != 'Q' && UserMove != 'q'); //Keep running the program until the user types in a Q or q
		system("cls"); //Clear the screen
		cout << endl; // start a new line
		Game->Print(); //Print the final grid out to the user
		cout << endl; // start a new line
	} while (UserMove != 'n'&& UserMove != 'N'); // keep looping until the user type N or n
	system("PAUSE"); // pause the screen
	return 0; // finish applicaton
}


But, I still have two problems:
My moving check function is not working: ( Movecheck() ), I don't know why, the user still can move out of boundary.
The final output for users when they pick up all the coins is not printing out. ( A if statement in main() , and ask user if he wants to play again)
Lines 51,55,59,63: Your conditions are backwards. If the position is out of bounds, you do NOT want to call move. Only after all the checks have passed, do you want to call move().

Lines 68,72: These functions are poorly named. A function name should indicate what it does.
return1 and return2 are meaningless.

Line 95: You have a memory leak. Each time through the loop, you allocate a new instance. The instance should be deleted at the bottom of the loop.

Line 114,119: I'm confused by the difference between N and Q.
So for:
Line51,55,59,63: So I put all of them in a big if statement, but how can I make the cursor not moving when it is out of bounds.

'Q' means whenever user input q , the program return 0. And it is during the game.
"N' means when user input N means he doesn't want to play again. this will be asked (Would You like to play again) only when user complete the collection of all coins.
And what is memory leak, how can I fix it
Last edited on
how can I make the cursor not moving when it is out of bounds.

Return out of the function without doing anything.

I understand what Q and N do. I just thought it was confusing to have two different idioms for ending the game.


I tried to return out of the function, but the cursor is still moving, stead of stay there.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void MoveCheck(int i)
	{
		if (xPos - 1 < 0)// check if the movement is outof boundry
		{
			return;
		}
		if (xPos + 1 >= MAX_HEIGHT)
		{
			return;
		}
		if (yPos - 1 < 0)
		{
			return;
		}
		if (yPos + 1 >= MAX_WIDTH)
		{
			return;
		}
	}

It doesn't work. it that how to return out of a function?
Instead of 4 seperate if statements that all lead to leaving the function, why not simply have 1 if statement and 3 else if statement. That way you wouldnt need the return; because it can only enter one of them.
Line 102: You're calling Game->Move() unconditionally. So you're going to move the user's position regardless of what MoveCheck determined.
I tried to change my code like this:
1
2
3
4
5
6
7
8
9
10
11
void MoveCheck(int i)
	{
		if (xPos - 1 < 0 || xPos + 1 > MAX_HEIGHT || yPos - 1 < 0 || yPos + 1 > MAX_WIDTH)// check if the movement is outof boundry
		{
			return;
		}
		else
		{
			Move(i);
		}
	}

but it still doesn't work
Did you remove line 102?
Yes I did. Horizontally, when the cursor move out of the bound, it will switch to next line. And vertically, the cursor will still move outside of the bound, and then the system comes up a breakpoint message
Topic archived. No new replies allowed.