Dungeon Crawler

The grid shows, and I have it move the first time; also sometimes when it should be invalid, it shows up as valid.
And I somehow how y being x and x being y, as in y axis is x axis and x axis is y axis.
It also sometimes skips, saying 1 time error the next time showing the grid again.
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
#include <iostream>
#include <string>

using namespace std;

int main() {
	string input;
	char cArray[7][10];
	int col, row;
	char player = 'G', trap = 'T', goal = 'X';
	int x = 0, y = 0;

	for(row = 0; row < 7; row++) {
	
		for (col = 0; col < 10; col++)
			cArray[row][col] = '.';
	}

	cArray[x][y] = player;
	cArray[5][4] = trap;
	cArray[6][9] = goal;

	cout<<"Welcome to Dungeon Crawl!"<<endl;
	
	for (row = 0; row < 7; row++){
		for(col = 0; col < 10; col++)
			cout<<cArray[row][col];
			cout<<endl;
	}

	while(cArray[6][9] != player){
		
			cout<<"Enter Up, Down, Left or Right"<<endl;
			cin>>input;
			if(input != "up" && input != "Up" && input !=  "down" && input != "Down" && input != "Right" && input != "right" && input != "Left" && input != "left"){
				cout<<"Invalid entry"<<endl;
				entry:
				cout<<"Enter Up, Down, Left or Right"<<endl;
				cin>>input;
			} else if(input == "Up" || input == "up"){
				for(col = 0; col <10; col++) {
					if(y == 0 && x > -1 && x < 10){
						cout<<"Invalid move"<<endl;
						goto entry;
						
					} else {
						cArray[x][y] = '.';
						cArray[x - 1][y] = player;
					}
				}
			} else if(input == "Down" || input == "down"){
				for(col = 0; col<10; col++) {
					if(y == 6 && x > -1 && x < 10){
						cout<<"Invalid move"<<endl;
					} else {
						cArray[x][y] = '.';
						cArray[x + 1][y] = player;
					}
				}
			} else if(input == "Right" || input == "right"){
				for(row = 0; row < 7; row++){
					if(y > -1 && y < 10 && x == 9){
						cout<<"Invalid move"<<endl;
						goto entry;
					} else {
						cArray[x][y] = '.';
						cArray[x][y + 1] = player;
					}
				}
			} else if(input == "Left" || input == "left"){
				for(row = 0; row < 7; row++){
					if(y > -1 && y < 6 && x == 0){
						cout<<"Invalid move"<<endl;
						goto entry;
					} else {
						cArray[x][y] = '.';
						cArray[x][y - 1] = player;
					}
				}
			}
	for (row = 0; row < 7; row++)  
	{
		for (col = 0; col < 10; col++)
			cout << cArray[row][col];
			cout<<endl;
	}
	}
	

	return 0;
}
Last edited on
OK - some things to fix up here.

First, I wouldn't bother with a string for user input - just use a chars ('U', 'D', 'L', 'R'). What if the user types in DOwn for example?

Make use of the toupper function so you don't test the value of variables twice.

Use a switch rather than else if conditions, have an option to quit, and use the default clause to catch bad input.

Put the switch inside a bool controlled while loop.

Have function that displays the menu - you can have code in the while loop before the switch so it only displays the first time if you want.

DON'T USE GOTO There are very rare situations where this is warranted, but this isn't one of them. The break at the end of case in the switch will achieve the same thing.

Have a function to display the grid - this will avoid repetition of code.

Don't have magic values like 7 & 10 in your code, do this instead:

1
2
3
4
const SIZEROW = 7;
const SIZECOL = 10;

char Board[SIZEROW][SIZECOL]; //better name as well 


You could have one function to decide if the move is invalid or not. It would only need one statement inside it.

If you take all this on board - it probably means starting again - hopefully your problem might go away. Don't be tempted to persevere & get this code working - IMO it is better to do it right and have good code that works, rather than have bad code than works.

Hope all goes well :)
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
#include <iostream>
#include <string>

using namespace std;

int main() {
	char input;
	const int SIZEROW = 7;
	const int SIZECOL = 10;
	char Board[SIZECOL][SIZEROW];
	int row, col;
	int x = 0, y = 0;
	char player = 'G';
	bool Gameover(true);

	for(row = 0;row < 7;row++){
		for(col = 0; col < 10; col++)
			Board[row][col] = '.';
	}

	Board[x][y] = player;

	for(row = 0;row < 7;row++){
		for(col = 0; col < 10; col++)
			cout<<Board[row][col];
		cout<<endl;
	}
	while(Gameover){
		cout<<"Enter U, D, L or R. Enter Q to quit"<<endl;
		cin>>input;
		switch(input){
		case 'U':
			Board[x][y] = '.';
			Board[x - 1][y] = player;
			break;
		case 'D':
			Board[x][y] = '.';
			Board[x + 1][y] = player;
			break;
		case 'L':
			Board[x][y] = '.';
			Board[x][y - 1] = player;
			break;
		case 'R':
			Board[x][y] = '.';
			Board[x][y + 1] = player;
			break;
		case 'Q':
			Gameover = false;
			break;
		default:
			cout<<"Invalid entry"<<endl;
		}
		
			for(row = 0;row < 7;row++){
			for(col = 0; col < 10; col++)
			cout<<Board[row][col];
			cout<<endl;
			}
	}



	return 0;
}


It appears now that R will move it, down will move it but then 3 other G's appear on the board.
Ok - that is quite a good effort - well done !

Just a couple of things:

- What happens when you try to move more than 1 spot in a direction? You can't, right? There are 2 fundamental things you need to keep track of.

- player should be a const char.

- replace all of your 7's & 10's with SIZEROW & SIZECOL respectively - that way if want to change the size of the board you can do it one place by altering the value of SIZEROW & SIZECOL, instead of having to change them everywhere.

- lines 23 -26 & 55- 58 are the same - put them in a void function with the array and SIZEROW & SIZECOL as arguments:

1
2
//put this declaration before main
void PrintBoard(char Board[][SIZECOL], int SIZEROW, int SIZECOL );


That way you can just call the function instead of repeating the code.

You should put a set of braces for line 57 - always uses braces even when there is only 1 statement - it will save you one day when you add more code. If you indent the for on line 56, it will give a visual clue to prevent errors later on.

1
2
3
4
5
6
7
8
9
10
	return 0;
} //end of main

void PrintBoard(char Board[][SIZECOL], int SIZEROW, int SIZECOL ) //definition
        for(int row = 0; row < SIZEROW; ++row) {
			for(int col = 0; col < SIZECOL; ++col) { //always use braces
			      cout<<Board[row][col];
                        }
			cout<<endl;
	}


- use the toupper function on the input variable so it gets converted to uppercase:

input = toupper(input); //input is now upper case

Alternatively, you can organise your cases like this:

1
2
3
4
5
6
7
8
9
10
11
switch(input){
		case 'U':
                case 'u':
			Board[x][y] = '.';
			Board[x - 1][y] = player;
			break;
		case 'D':
                case 'd':
			Board[x][y] = '.';
			Board[x + 1][y] = player;
			break;


- I would have the logic for the GameOver variable around the other way:

1
2
3
4
5
6
7
8
bool Gameover = false;

while(!Gameover){

// your code
case 'Q':
			Gameover = true;
			break;


- Finally, consider changing your editor so it replaces tabs with 4 spaces - so it displays better on this page.


Topic archived. No new replies allowed.