out of bounds in game

Hi guys I made a game in which you can move up down,left and right in a console the X is the current position you are at and I will implement a random position which will basically hold tressure and when the user lands on that spot they win the game kind of like a hunting for gold game(don't know what to call it)

anyway my problem is how can I test to see if the user goes out of bounds of the map I tried implementing this but no luck I even got a bool value start and set it to true but this made the code complicated and couldn't come up with the solution

the functionality works except for when I go out of bounds I'm having a hard time implementing this in my if and switch block of code

I will post the full code here as reference


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
  #include <iostream>
using namespace std;

char map[5][10]; // GLOBAL

void options() {

	cout << "press one to move right" << "press two to go right"
			<< "press three to go down" << "press four to go up" << endl;
}

void initMap() {

	for (int i = 0; i < 5; i++) {

		for (int j = 0; j < 10; j++) {

			map[i][j] = '0';
		}
	}
}

void showMap() {

	for (int i = 0; i < 5; i++) {

		cout << endl;
		for (int j = 0; j < 10; j++) {

			cout << map[i][j];
		}
	}
}

int main() {

	initMap();
	map[0][0] = 'X';
	int currentCol = 0;
	int currentRow = 0;
	int start = true;

	bool quit = false;

	while (!quit) {

		options();
		int choice;
		cin >> choice;

		switch (choice) {

		case 1:
			if (((currentCol >= 0 && currentCol <= 4)
					&& (currentRow >= 0 && currentRow <= 9))) {

				map[currentCol][currentRow] = '0';
				currentRow++;
				map[currentCol][currentRow] = 'X';

			}
			else{
				cout << "out of bounds" << endl;
			}
			break;
		case 2:
			if ((currentCol >= 0 && currentCol <= 4)
					&& (currentRow >= 0 && currentRow <= 9)) {

				map[currentCol][currentRow] = '0';
				currentRow--;
				map[currentCol][currentRow] = 'X';
			}
			else {
				cout << "out of bounds" << endl;
			}
			break;
		case 3:
			if ((currentCol >= 0 && currentCol <= 4)
					&& (currentRow >= 0 && currentRow <= 9)) {

				map[currentCol][currentRow] = '0';
				currentCol++;
				map[currentCol][currentRow] = 'X';
			}
			else {
				cout << "out of bounds" << endl;
			}
			break;
		case 4:
			break;
			if ((currentCol >= 0 && currentCol <= 4)
					&& (currentRow >= 0 && currentRow <= 9)) {

				map[currentCol][currentRow] = '0';
				currentRow--;
				map[currentCol][currentRow] = 'X';
			}
			else {
				cout << "out of bounds" << endl;
			}
			break;
		case 5:
			quit = true;
			break;
		default:
			cout << "out of bounds" << endl;
		}
		showMap();
		cout << endl;
	}
}



but this is the code that I need to implement

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




map[0][0] = 'X';
	int currentCol = 0;
	int currentRow = 0;
	int start = true;

	bool quit = false;

	while (!quit) {

		options();
		int choice;
		cin >> choice;

		switch (choice) {

		case 1:
			if (((currentCol >= 0 && currentCol <= 4)
					&& (currentRow >= 0 && currentRow <= 9))) {

				map[currentCol][currentRow] = '0';
				currentRow++;
				map[currentCol][currentRow] = 'X';

			}
			else{
				cout << "out of bounds" << endl;
			}
			break;
		case 2:
			if ((currentCol >= 0 && currentCol <= 4)
					&& (currentRow >= 0 && currentRow <= 9)) {

				map[currentCol][currentRow] = '0';
				currentRow--;
				map[currentCol][currentRow] = 'X';
			}
			else {
				cout << "out of bounds" << endl;
			}
			break;
		case 3:
			if ((currentCol >= 0 && currentCol <= 4)
					&& (currentRow >= 0 && currentRow <= 9)) {

				map[currentCol][currentRow] = '0';
				currentCol++;
				map[currentCol][currentRow] = 'X';
			}
			else {
				cout << "out of bounds" << endl;
			}
			break;
		case 4:
			break;
			if ((currentCol >= 0 && currentCol <= 4)
					&& (currentRow >= 0 && currentRow <= 9)) {

				map[currentCol][currentRow] = '0';
				currentRow--;
				map[currentCol][currentRow] = 'X';
			}
			else {
				cout << "out of bounds" << endl;
			}
			break;
		case 5:
			quit = true;
			break;
		default:
			cout << "out of bounds" << endl;
		}
		showMap();
		cout << endl;
	}





Thanks
I think you will find it easier to implement a bounds checking function:
1
2
3
4
5
6
7
bool inbounds (int row, int col)
{  if (row < 0 || row >= 5) 
     return false;
   if (col < 0 || col >= 10)
     return false;
   return true;
}


Lines 21-22,34-35,46-47,59-60: You're checking the current position. The current position should always be inbounds. You want to check the proposed position is inbounds before adjusting the position.
20
21
22
23
24
25
26
27
28
29
30
31
	case 1:
			if (inbounds(currentCol, currentRow+1)) 
			{  // okay to move to next row 
				map[currentCol][currentRow] = '0';
				currentRow++;
				map[currentCol][currentRow] = 'X';
			}
			else{
				cout << "out of bounds" << endl;
			}
			break;
//  cases 2-4 are similar 


A note on style: You will find it a good idea to use named consts for the dimensions of your grid rather than embedding 5 and 10 in many places in the code.
1
2
3
4
  const int ROWS = 5;
  const int COLS = 10;
...
  char map[ROWS][COLS];

That way if you ever want to change the dimensions of your map, you have only one place to change the dimensions.
Last edited on
great idea Anon =)

thanks
Your problem is two fold.

First, you're using >= and <= instead of > and <. Why is this a problem? Just think.
If a user is at (0, 0) and wanted to go left, your code would have allowed him to do so!

Second, in all 4 cases you're checking if the current position out of bounds which should never happen. What you should be checking is if the potential (i.e. new) position is out of bounds and not move if it is!

In a nutshell, your code doesn't prevent the user to go out of bounds; it just alerts him that he has done so!
If you fixed the above two then your code would work. But of course (as you noticed) it's really repetitive.
A much more elegant way to write it is like this:
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
int main() 
{
    initMap();
    map[0][0] = 'X';
    int currentCol = 0;
    int currentRow = 0;
    int start = true;
    bool quit = false;
    while (! quit) {
        options();
        int choice;
        cin >> choice;
        int changeRow = 0;
        int changeCol = 0;
        switch (choice) {
            case 1: changeRow =  1; break;
            case 2: changeRow = -1; break;
            case 3: changeCol =  1; break;
            case 4: changeCol = -1; break;
            case 5: quit = true; break;
            default: cout << "Bad input" << endl; break;
        }
        if (quit)
            break;
        if (! OutOfBounds(currentRow + changeRow, currentCol + changeCol)) {
            map[currentCol][currentRow] = '0';
            currentRow += changeRow;
            currentCol += changeCol;
            map[currentCol][currentRow] = 'X';
        } else {
            cout << "Out of bounds" << endl;
        }
        showMap();
        cout << endl;
    }
}

The out of bounds function could look like this:
1
2
3
4
5
6
7
#define MAP_WIDTH 5
#define MAP_HEIGHT 10
char map[MAP_WIDTH][MAP_HEIGHT];
bool OutOfBounds(int x, int y) 
{
    return (x < 0 || x >= MAP_WIDTH) || (y < 0 || y >= MAP_HEIGHT);
}

Note that you should always tend to use named constants instead of putting magic numbers like 5 or 10 directly into code. This way, you could easily change dimensions of the map just by changing two numbers! In your code, if you wanted to change dimensions of the map you would need to change numbers all over the place.
Last edited on
Ihatov thank you very much =)

that is a much cleaner and nicer way to write it,

I will try implement this right away
Last edited on
hi guys I have stumbled upon another bug in my program

I added another if block of code and once these if blocks were added

1
2
3
4
5
6
7
8
9
10

if (((currentCol == trapCol1) && (currentRow == trapRow1))
						|| ((currentCol = trapCol2) && (currentRow == trapRow2))) {

					map[currentCol][currentRow] = 'T';
					cout << "GAME OVER" << endl;
					return 0;
				}



my program operates in strange ways,for example two X's will appear sometimes

instead of one

0X00000000
X000000000
0000000000
0000000000
0000000000
press one to move right press two to go right press three to go down press four to go up

but when I remove those if statements checking to see if the current position is a trap it works fine no bugs at all

I wonder what's wrong something is clearly wrong with that block of code above but I fail to see the logic error in it,

here is the full code for reference

thanks

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
#include <iostream>
#include <limits>
#include <ctime>
#include <random>
using namespace std;

char map[5][10]; // GLOBAL

void options() {

	cout << "press one to move right " << " press two to go right "
			<< " press three to go down " << " press four to go up" << endl;
}

void initMap() {

	for (int i = 0; i < 5; i++) {

		for (int j = 0; j < 10; j++) {

			map[i][j] = '0';
		}
	}
}

void showMap() {

	for (int i = 0; i < 5; i++) {

		cout << endl;
		for (int j = 0; j < 10; j++) {

			cout << map[i][j];
		}
	}
}

bool inbounds(int row, int col) {
	if (row < 0 || row >= 5)
		return false;
	if (col < 0 || col >= 10)
		return false;
	return true;
}

int validInput() {
	int x;
	cin >> x;
	while (cin.fail()) {
		cin.clear();
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		cout << "Bad entry.  Enter a NUMBER: " << endl;
		;
		cin >> x;
	}
	return x;
}

int main() {

	initMap();
	map[0][0] = 'X';
	int currentCol = 0;
	int currentRow = 0;

	bool quit = false;
	srand(time(NULL));

	int randomCol = rand() % 4;
	int randomRow = rand() % 9;

	int trapCol1 = rand() % 4;
	int trapRow1 = rand() % 9;

	int trapCol2 = rand() % 4;
	int trapRow2 = rand() % 9;

	while (!quit) {

		options();
		int choice;
		choice = validInput();

		switch (choice) {

		case 1:
			if (inbounds(currentCol, currentRow + 1)) {

				map[currentCol][currentRow] = '0';
				currentRow++;
				map[currentCol][currentRow] = 'X';
				if (((currentCol == trapCol1) && (currentRow == trapRow1))
						|| ((currentCol = trapCol2) && (currentRow == trapRow2))) {

					map[currentCol][currentRow] = 'T';
					cout << "GAME OVER" << endl;
					return 0;
				}

				if ((currentCol == randomCol) && (currentRow == randomRow)) {

					map[currentCol][currentRow] = '$';
					showMap();
					cout << endl;
					cout << "YOU WIN!!" << endl;
					return 0;
				}
			} else {
				cout << "out of bounds" << endl;
			}
			break;
		case 2:
			if (inbounds(currentCol, currentRow - 1)) {

				map[currentCol][currentRow] = '0';
				currentRow--;
				map[currentCol][currentRow] = 'X';

				if (((currentCol == trapCol1) && (currentRow == trapRow1))
						|| ((currentCol = trapCol2) && (currentRow == trapRow2))) {

					map[currentCol][currentRow] = 'T';
					cout << "GAME OVER" << endl;
					return 0;
				}

				if ((currentCol == randomCol) && (currentRow == randomRow)) {

					map[currentCol][currentRow] = '$';
					showMap();
					cout << endl;
					cout << "YOU WIN!!" << endl;
					return 0;
				}
			} else {
				cout << "out of bounds" << endl;
			}
			break;
		case 3:
			if (inbounds(currentCol + 1, currentRow)) {

				map[currentCol][currentRow] = '0';
				currentCol++;
				map[currentCol][currentRow] = 'X';

				if (((currentCol == trapCol1) && (currentRow == trapRow1))
						|| ((currentCol = trapCol2) && (currentRow == trapRow2))) {

					map[currentCol][currentRow] = 'T';
					cout << "GAME OVER" << endl;
					return 0;
				}

				if ((currentCol == randomCol) && (currentRow == randomRow)) {

					map[currentCol][currentRow] = '$';
					showMap();
					cout << endl;
					cout << "YOU WIN!!" << endl;
					return 0;
				}
			} else {
				cout << "out of bounds" << endl;
			}
			break;
		case 4:
			if (inbounds(currentCol-1, currentRow)) {

				map[currentCol][currentRow] = '0';
				currentCol--;
				map[currentCol][currentRow] = 'X';

				if (((currentCol == trapCol1) && (currentRow == trapRow1))
						|| ((currentCol = trapCol2) && (currentRow == trapRow2))) {

					map[currentCol][currentRow] = 'T';
					cout << "GAME OVER" << endl;
					return 0;
				}

				if ((currentCol == randomCol) && (currentRow == randomRow)) {

					map[currentCol][currentRow] = '$';
					showMap();
					cout << endl;
					cout << "YOU WIN!!" << endl;
					return 0;
				}
			} else {
				cout << "out of bounds" << endl;
			}
			break;
		case 5:
			quit = true;
			break;
		default:
			cout << "out of bounds" << endl;
		}
		showMap();
		cout << endl;
	}
}
**edit silly me I forgot to add an extra =,so it was = when it should have been ==

it's crazy how just one character can wreck havoc on a program

anyway if anyone stumbles upon this problem solved but if anyone wants to give me some input or if they can spot any other bugs,they would be more than welcome,every bit of feedback is appreciated =)
I haven't been into it in depth, but three things stand out immediately:

- look VERY closely at lines 93, 120, 147, 174: = is NOT the same as ==

- rand() % 4 produces numbers 0,1,2,3 NOT 0,1,2,3,4, which I suspect was your intention; also, why is this being used for COLUMNS (which I thought went from 0 to 9)? Actually, I've just noticed that you are completely inconsistent over which index is rows and which is columns - it seems to change from routine to routine.

- you are using magic numbers (5 and 10) - more flexible and helps identify errors if they are named variables; (sorry, just noticed that @AbstractionAnon and @Ihatov had already pointed that out - so: three of us are leaning on you!)
Last edited on
@lastchance nice spot =)

changed the random numbers,

thanks
Topic archived. No new replies allowed.