Cookie PickUp Inheritance Game

I'm writing a code for class that is an inheritance pick up game, we were tasked to limit the player to the play area, so not allowing them to move outside of the grid.
We are to be generating a random number of cookies from 1 to 10 and have the player collect them. Upon collected the all the cookies the program should be congratulating the player for the collecting of all displayed cookies as well as replying how many total cookies they have collected in the process.

I've gotten the code to limit the players movement, as well as generate random cookie images on the screen, however I can't figure out how to have the cookies actual value line up with the images, as well as register that the user is collecting them.

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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
//You can add or delete includes
#include <iostream>
#include <stdlib.h> //For system()
#include <conio.h> //For getche()
#include <time.h>
using namespace std;

//You can modify these numbers but don't delete these constants or this starting code will not work
const int MAX_HEIGHT = 20; //The height of the grid
const int MAX_WIDTH = 40; //The width of the grid

// DO NOT ALTER OR DELETE THIS CODE (START)!!!!!!!!!!!!!!!!!!!!!!!!!!!
/********************************************************************
 * Class: PickUpGame
 * Purpose: To store the grid and the current x and y position of the
 * user. Also has memeber functions to intialize the grid and print it.
 * Allows the user to move around the grid but provides no out of
 * bounds checking.
 ********************************************************************/
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;
		}
	}
};
// DO NOT ALTER OR DELETE THIS CODE (END)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

class CookieCollect : public PickUpGame
{
protected:
	int TotalCookies; // track total cookies on screen
	int CookiesLeft; //track the reamining amount of cookies on the screen
	const char CookieIcon = '$';

public:
	CookieCollect()
	{
		SetupScreen();
	}


	void SetupScreen()
	{

		int vertical;
		int horizontal;
		TotalCookies = rand() % 10 + 1; // generate a random number of cookies on screen
		CookiesLeft = TotalCookies;

		do
		{
			vertical = rand() % MAX_HEIGHT; //random generationfor cookie locations vertically
			horizontal = rand() % MAX_WIDTH; //random generation for cookie locations horizontally
			if (Screen[vertical][horizontal] != CookieIcon && Screen[vertical][horizontal] != Screen[xPos][yPos]) //check to make sure cookies do not overlap
			{
				Screen[vertical][horizontal] = CookieIcon; //generating cookies in open spaces
				CookiesLeft--;
			}
		} while (CookiesLeft != 0);
	}
	

	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
			if (xPos - 1 < 0) {//limits the arrow to the play area
			}
			else {
				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
			if (xPos + 1 >= MAX_HEIGHT) { //limits the arrow to the play area
			}
			else {
				Screen[xPos][yPos] = ' ';
				xPos++;
				Screen[xPos][yPos] = 'V';
			}
			break;
		case 75: //Left arrow
			if (yPos - 1 < 0) { //limits the arrow to the play area
			}
			else {
				Screen[xPos][yPos] = ' ';
				yPos--;
				Screen[xPos][yPos] = '<';
			}
			break;
		case 77: //Right arrow
			if (yPos + 1 >= MAX_WIDTH) { //limits the arrow to the play area
			}
			else {
				Screen[xPos][yPos] = ' ';
				yPos++;
				Screen[xPos][yPos] = '>';
			}
			break;
		}
	}


	int GetTotalCookies()
	{
		return TotalCookies; // return the value of total cookies collected
	}


	int GetCookiesLeft()
	{
		return CookiesLeft; // return the value of the cookies left in the grid
	}
};

//You can modify and change main()
int main()
{
	CookieCollect* Game = new CookieCollect; //Create a new game object and store it in a object pointer
	char UserMove = ' '; //This is used to store the users input
	Game->SetupScreen();
	do
	{
		system("cls"); //Clear the screen before printing anything
		cout << "Welcome to cookie pickup. You will move to the cookies by using the arrow keys." << endl; //Program intro
		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 (some compilers have "getche()")
		UserMove = _getche(); //Get one character from the user (Visual Studio 2010 "_getche()" is the new version of "getche()")
		Game->Move(UserMove); //Process the users input
		if (Game->GetCookiesLeft() == 0) // check if there are cookies left
		{
			cout << "Congratulations!! You found all the cookies!!" << endl; // output for winning the game
			cout << "You collected up " << Game->GetTotalCookies() << "cookies!" << endl;
		}
	}

	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;
	Game->Print(); //Print the final grid out to the user
	cout << endl;

	system("PAUSE");
	return 0;
}
You need a function to check for a cookie:
119
120
121
122
123
124
125
126
void CheckForCookie ()
    {
        if (Screen[xpos][ypos] == CookieIcon)
        {   Screen[xpos][ypos] = '.';       //  space is now empty
            cout << "Congratulations you picked up a cookie" << endl;
            CookiesLeft--;
        }
    }


Then in each of your move cases, you need to call CheckForCookie().
124
125
126
127
128
129
130
131
132
133
        case 72: //Up arrow
            if (xPos - 1 < 0) {//limits the arrow to the play area
            }
            else {
                Screen[xPos][yPos] = ' '; //Wipe out the users current cursor
                xPos--; //Move the users x position on the grid
                CheckForCookie();
                Screen[xPos][yPos] = '^'; //Move the users cursor
            }
            break;

Rinse and repeat for each of the other directions.
Last edited on
- CookieCollect::SetupScreen() should call PickupGame::SetupScreen()
- CookieCollectSetupScreen() decrements CookiesLeft to zero in the loop. I set it back
to TotalCookies. A better way is to use a local variable to represent the number left
- I changed CookieCollect::Move() to call PickupGame::Move()
- There's no need to put Game on the heap.

I had to include a definition of getche() and the values for up/down/left/right are different from yours.

Seach for "dmh" to see the changes I made.

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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
//You can add or delete includes
#include <iostream>
#include <stdlib.h>				 //For system()
// #include <conio.h> //For getche()
#include <time.h>
using namespace std;

//You can modify these numbers but don't delete these constants or this starting code will not work
const int MAX_HEIGHT = 20;	//The height of the grid
const int MAX_WIDTH = 40;	//The width of the grid

// dmh - consts for moving. Note that my keys are different from yours.
constexpr int UP = 65;
constexpr int DOWN = 66;
constexpr int LEFT = 68;
constexpr int RIGHT=67;

#include <termios.h>
#include <unistd.h>
#include <stdio.h>

/* reads from keypress, doesn't echo */
int
getch(void)
{
    struct termios oldattr, newattr;
    int ch;
    tcgetattr(STDIN_FILENO, &oldattr);
    newattr = oldattr;
    newattr.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
    return ch;
}

/* reads from keypress, echoes */
int
getche(void)
{
    struct termios oldattr, newattr;
    int ch;
    tcgetattr(STDIN_FILENO, &oldattr);
    newattr = oldattr;
    newattr.c_lflag &= ~(ICANON);
    tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
    return ch;
}

// DO NOT ALTER OR DELETE THIS CODE (START)!!!!!!!!!!!!!!!!!!!!!!!!!!!
/********************************************************************
 * Class: PickUpGame
 * Purpose: To store the grid and the current x and y position of the
 * user. Also has memeber functions to intialize the grid and print it.
 * Allows the user to move around the grid but provides no out of
 * bounds checking.
 ********************************************************************/
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 UP:				 //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 DOWN:				 //Down arrow
	    Screen[xPos][yPos] = ' ';
	    xPos++;
	    Screen[xPos][yPos] = 'V';
	    break;
	case LEFT:				 //Left arrow
	    Screen[xPos][yPos] = ' ';
	    yPos--;
	    Screen[xPos][yPos] = '<';
	    break;
	case RIGHT:				 //Right arrow
	    Screen[xPos][yPos] = ' ';
	    yPos++;
	    Screen[xPos][yPos] = '>';
	    break;
	}
    }
};

// DO NOT ALTER OR DELETE THIS CODE (END)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

class CookieCollect:public PickUpGame
{
  protected:
    int TotalCookies;		// track total cookies on screen
    int CookiesLeft;		//track the reamining amount of cookies on the screen
    const char CookieIcon = '$';

  public:
      CookieCollect()
    {
	SetupScreen();
    }

    void SetupScreen()
    {
	int vertical;
	int horizontal;
	TotalCookies = rand() % 10 + 1;		 // generate a random number of cookies on screen
	CookiesLeft = TotalCookies;
	PickUpGame::SetupScreen(); // dmh - set the base screen

	// Now place the cookies
	do {
	    vertical = rand() % MAX_HEIGHT;	 //random generationfor cookie locations vertically
	    horizontal = rand() % MAX_WIDTH;	 //random generation for cookie locations horizontally
	    if (Screen[vertical][horizontal] == '.')
	    {
		Screen[vertical][horizontal] = CookieIcon;	//generating cookies in open spaces
		CookiesLeft--;
	    }
	} while (CookiesLeft != 0);
	CookiesLeft = TotalCookies; // dmh - restore the original value
    }

    void Move(char Direction)
    {
	// dmh - no need to cast to int
	int newx{xPos}, newy{yPos};
	switch (Direction)	 //Don't know the ASCII characters for the arrow keys so use the ASCII numbers
	{
	case UP:				 //Up arrow
	    --newx;
	    break;
	case DOWN:				 //Down arrow
	    ++newx;
	    break;
	case LEFT:				 //Left arrow
	    --newy;
	    break;
	case RIGHT:				 //Right arrow
	    ++newy;
	    break;
	}
	if (newx >= 0 && newx < MAX_HEIGHT &&
	    newy >= 0 && newy < MAX_WIDTH) {
	    // The move is valid
	    if (Screen[newx][newy] == CookieIcon) {
		--CookiesLeft;
	    }
	    PickUpGame::Move(Direction);
	}
    }

    int GetTotalCookies()
    {
	return TotalCookies;			 // return the value of total cookies collected
    }

    int GetCookiesLeft()
    {
	return CookiesLeft;			 // return the value of the cookies left in the grid
    }
};

//You can modify and change main()
int
main()
{
    // dmh - no needto put this on the heap
    CookieCollect Game;	//Create a new game object and store it in a object pointer
    int UserMove = ' ';	//This is used to store the users input
    Game.SetupScreen();
    do {
	system("cls");				 //Clear the screen before printing anything
	cout << "Welcome to cookie pickup. You will move to the cookies by using the arrow keys." << endl;	//Program intro
	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 (some compilers have "getche()")
	// UserMove = _getche(); //Get one character from the user (Visual Studio 2010 "_getche()" is the new version of "getche()")
	cout << "key is " << UserMove << '\n';
	Game.Move(UserMove);			 //Process the users input
	if (Game.GetCookiesLeft() == 0)	 // check if there are cookies left
	{
	    cout << "Congratulations!! You found all the cookies!!" << endl;	// output for winning the game
	    cout << "You collected up " << Game.GetTotalCookies() << "cookies!" << endl;
	}
    }

    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;
    Game.Print();				 //Print the final grid out to the user
    cout << endl;

    system("PAUSE");
    return 0;
}

Topic archived. No new replies allowed.