ASCII Game using multidimensional arrays

closed account (GbX36Up4)
I am creating a game with ascii and the map shows up weird

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
#include <iostream>
#include <windows.h>

using namespace std;

main(){
int counter = 0;
int column = 0;
int row = 0;
int map1[9][15]= {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                {0,5,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};


            while(counter < 16){ // creates the map depending on what is where.
                if(map1[row][column] == 0) {cout << "#";}
                if(map1[row][column] == 5) {cout << "@";}
                if(map1[row][column] == 1) {cout << ".";}
                column++;
                counter++;
                }

            {counter = 0; // resets everything and takes us to a new row and a new line
            column = 0;
            row = 1;
            cout << endl;}

            while (counter < 16){
                if(map1[row][column] == 0) {cout << "#";}
                if(map1[row][column] == 5) {cout << "@";}
                if(map1[row][column] == 1) {cout << ".";}
            column++;
            counter++;
            }

            {counter  = 0;
            column = 0;
            row = 2;
            cout << endl;}

            while (counter < 16){
            if(map1[row][column] == 0) {cout << "#";}
            if(map1[row][column] == 5) {cout << "@";}
            if(map1[row][column] == 1) {cout << ".";}
            column++;
            counter++;
            }

            {counter = 0;
            column = 0;
            row = 3;
            cout << endl;}

            while (counter < 16){
            if(map1[row][column] == 0) {cout << "#";}
            if(map1[row][column] == 5) {cout << "@";}
            if(map1[row][column] == 1) {cout << ".";}
            column++;
            counter++;
            }

            {counter = 0;
            column = 0;
            row = 4;
            cout << endl;}

            while (counter < 16){
            if(map1[row][column] == 0) {cout << "#";}
            if(map1[row][column] == 5) {cout << "@";}
            if(map1[row][column] == 1) {cout << ".";}
            column++;
            counter++;
            }

            {counter = 0;
            column = 0;
            row = 5;
            cout << endl;}

            while (counter < 16){
            if(map1[row][column] == 0) {cout << "#";}
            if(map1[row][column] == 5) {cout << "@";}
            if(map1[row][column] == 1) {cout << ".";}
            counter++;
            column++;
            }

            {counter = 0;
            column = 0;
            row = 6;
            cout << endl;}

            while (counter < 16){
                if(map1[row][column] == 0) {cout << "#";}
                if(map1[row][column] == 5) {cout << "@";}
                if(map1[row][column] == 1) {cout << ".";}
                counter++;
                column++;
            }

            {counter = 0;
            column = 0;
            row = 7;
            cout << endl;}

            while (counter < 16){
            if(map1[row][column] == 0) {cout << "#";}
                if(map1[row][column] == 5) {cout << "@";}
                if(map1[row][column] == 1) {cout << ".";}
                counter++;
                column++;
                }

                {counter = 0;
                column = 0;
                row = 8;
                cout << endl;}

                while (counter < 16){
                if(map1[row][column] == 0) {cout << "#";}
                if(map1[row][column] == 5) {cout << "@";}
                if(map1[row][column] == 1) {cout << ".";}
                counter++;
                column++;
                }

                {counter = 0;
                column = 0;
                row = 9;
                cout << endl;}

                while (counter < 16){
                if(map1[row][column] == 0) {cout << "#";}
                if(map1[row][column] == 5) {cout << "@";}
                if(map1[row][column] == 1) {cout << ".";}
                counter++;
                column++;
                }

}

It seems like the walls on the right side and the bottom are being duplicated. Any help or a different/better way to do it?
1. Your map has 15 columns (that means indeces 0 through 14) yet you're going from columns 0 through 15
2. You declared map1 with 9 rows, yet it has 8 rows. You need to add another row after this one: {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; or leave it as is and re-declare map1 with 8 rows
3. Since map1 has 9 rows (for now) (that means indeces 0 through 8) you don't want to go to row 9 as your program is currently doing

different/better way to do it?

Whenever you copy-and-paste, that's a sign that you need to put the duplicated code in a function or loop. The following will do the same job (this code assumes 9 rows and 15 columns)

1
2
3
4
5
6
7
8
9
10
11
for(int row = 0; row < 9; row++)
{
     for(int column = 0; column < 15; column++)
     {
          if(map1[row][column] == 0) {cout << "#";}
          if(map1[row][column] == 5) {cout << "@";}
          if(map1[row][column] == 1) {cout << ".";}
     }

     cout << endl;
}


Note that counter and column do the same thing, so only one is needed.

Also, if all you're doing with the ints in the map is checking which character to output, why not put the chars directly in the map?

1
2
3
4
5
6
7
8
char map1[8][15]= {{'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'}, /*note the 8 rows*/
                   {'#','@','.','.','.','.','.','.','.','.','.','.','.','.','#'},
                   {'#','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
                   {'#','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
                   {'#','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
                   {'#','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
                   {'#','.','.','.','.','.','.','.','.','.','.','.','.','.','#'},
                   {'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#'}};


If the ints serve some other special purpose, you may consider using a std::map<int, char> which would store the relationship between the int and the character to output (so no need to do an if statement for each output).

http://www.cplusplus.com/reference/stl/map/

You may consider storing the map (that is, the map of the level, not the std::map) in a text file and reading it in (you can have each level in its own text file, for example).

Finally, you're not doing anything Windows-specific so no need to #include <windows.h> , and also main() should be int main()
Last edited on
closed account (GbX36Up4)
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
#include <iostream>
#include <windows.h>
#include <conio.h>

using namespace std;
void map1create();
void game();
void keys();
void setcharacter();
int prow = 1;
int pcolumn = 1;
int lcolumn = 1;
int lrow = 1;
int iskeypressed = 0;
string currentmsg;
int didyoumove = 0;
string pmap = "mapone";
int map1[8][15]= {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                {0,5,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
                                {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};



int main(){
game();
}

void map1create(){
int counter = 0;
int column = 0;
int row = 0;
for(int row = 0; row < 8; row++)
{
     for(int column = 0; column < 15; column++)
     {
          if(map1[row][column] == 0) {cout << "#";}
          if(map1[row][column] == 5) {cout << "@";}
          if(map1[row][column] == 1) {cout << ".";}
     }

     cout << endl;
}
}

void game(){
map1create();
keys();
setcharacter();
system("cls");
map1create();
system("pause");


}


void keys(){
#define UP_ARROW    72
#define LEFT_ARROW  75
#define DOWN_ARROW  80
#define RIGHT_ARROW 77

 char KeyStroke;
do	{		KeyStroke =	getch(); 		if (KeyStroke == -32)		{			KeyStroke = getch(); // Even though there are 2 getch() it reads one keystroke
            switch (KeyStroke)			{
                    case UP_ARROW:
                                if(map1[prow-1][pcolumn] = 0){currentmsg == "You cannot move that way"; prow++; iskeypressed = 1;}
                                if(map1[prow-1][pcolumn] = 1){prow--; iskeypressed = 1;}
                    break;
                    case DOWN_ARROW:
                                if(map1[prow+1][pcolumn] = 0){currentmsg == "You cannot move that way."; prow--; iskeypressed = 1;}
                                prow++;
                                iskeypressed = 1;
                    break;
                    case LEFT_ARROW:
                                cout << "LEFT_ARROW" << endl;
                    break;
                    case RIGHT_ARROW:
                                cout << "RIGHT_ARROW" << endl;
                    break;}		}
                    else
                    cout << KeyStroke << endl;
                    }
while (iskeypressed < 1); // 27 = Escape key

}

void setcharacter(){
    if (didyoumove = 1){
map1[lrow][lcolumn] = 1;
map1[prow][pcolumn] = 5;
    }


}



Man do I suck with numbers....
closed account (GbX36Up4)
[/code]
#include <iostream>
#include <windows.h>
#include <conio.h>

using namespace std;
void map1create();
void game();
void keys();
void setcharacter();
int prow = 1;
int pcolumn = 1;
int lcolumn = 1;
int lrow = 1;
int iskeypressed = 0;
string currentmsg;
int didyoumove = 0;
string pmap = "mapone";
char face = 1;
char npc = 2;
char openspace = '.';
void conversations();
int mapone[8][35]= {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0},
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};



int main(){
game();
}

void map1create(){
for(int row = 0; row < 8; row++)
{
for(int column = 0; column < 35; column++)
{
if(mapone[row][column] == 0) {cout << "#";}
if(mapone[row][column] == 5) {cout << face;}
if(mapone[row][column] == 1) {cout << openspace;}
if(mapone[row][column] == 2) {cout << npc;}
}

cout << endl;
}
cout << currentmsg << endl;
}

void game(){
int gameactive = 0;
while(gameactive == 0){
map1create();
keys();
setcharacter();
system("cls");
map1create();
keys();
setcharacter();
system("cls");

}

}


void keys(){
#define UP_ARROW 72
#define LEFT_ARROW 75
#define DOWN_ARROW 80
#define RIGHT_ARROW 77
#define SPACE 32

char KeyStroke;
currentmsg = "";
do { KeyStroke = getch(); if (KeyStroke == -32) { KeyStroke = getch(); // Even though there are 2 getch() it reads one keystroke
switch (KeyStroke) {
case UP_ARROW:
if(mapone[prow-1][pcolumn] == 0){currentmsg = "You cannot move that way."; iskeypressed = 1;}
if(mapone[prow-1][pcolumn] == 1){lcolumn = pcolumn; lrow = prow; prow--; iskeypressed = 1; didyoumove = 1;}
break;
case DOWN_ARROW:
if(mapone[prow+1][pcolumn] == 0){currentmsg = "You cannot move that way."; iskeypressed = 1;}
if(mapone[prow+1][pcolumn] == 1){lcolumn = pcolumn; lrow = prow; prow++; iskeypressed = 1; didyoumove = 1;}
break;
case LEFT_ARROW:
if(mapone[prow][pcolumn-1] == 0){currentmsg = "You cannot move that way."; iskeypressed = 1;}
if(mapone[prow][pcolumn-1] == 1){lcolumn = pcolumn; lrow = prow; pcolumn--; iskeypressed = 1; didyoumove = 1;}
break;
case RIGHT_ARROW:
if(mapone[prow][pcolumn+1] == 0){currentmsg = "You cannot move that way."; iskeypressed = 1;}
if(mapone[prow][pcolumn+1] == 1){ lcolumn = pcolumn; lrow = prow; pcolumn++; iskeypressed = 1; didyoumove = 1;}
break;
case SPACE:
if(mapone[prow][pcolumn+1] == 2){conversations(); iskeypressed = 1;}
if(mapone[prow][pcolumn-1] == 2){conversations(); iskeypressed = 1;}
if(mapone[prow+1][pcolumn] == 2){conversations(); iskeypressed = 1;}
if(mapone[prow-1][pcolumn] == 2){conversations(); iskeypressed = 1;}
break; } }
}
while (iskeypressed < 1); // 27 = Escape key

}

void setcharacter(){
if (didyoumove = 1){
mapone[lrow][lcolumn] = 1;
mapone[prow][pcolumn] = 5;
}

cout << currentmsg << endl;
}


void conversations(){

cout << "rgargsaeth";
system("pause");

}
[/code]

Pressing enter does nothing. I think it may be because of the order in game() where the screen is cleared, but the systen("pause") should fix it, right?
What do you expect hitting enter to do? You're not listening for it. Clearing the screen won't do anything to keyboard input.

gameactive is always zero so game() is an infinite loop.

iskeypressed is never reset to zero, so after it's set to 1, keys() is guaranteed to only check one key.

systen("pause") should fix it, right?

No, and why are you calling it? You should find an alternative for it anyway.
http://www.cplusplus.com/forum/beginner/1988/
Man I am making a game just like what you are doing at the moment, but you are doing it all wrong.
1.Store the map in a 2D char array.
2.Make the infrastructure to the game e.g.

void gamerutine();//all the different functions
void refresh();
void printer();
void keyinput();
void refreshoutput();

ect...

So your method of printing should be...

for (int a=0;a<maxmaphight;a++)
{
for (int b=0;b<maxmapwidth;b++)
{
cout << map[a][b];//map is where you have sored all your chars
}
cout<<endl;
}


It would be a good idea to create two of the same arrays one called output and one called map, map is a const and output isnt, each cycle output is renewed by the maaps chars and then you add on other things to the map like monsters, and your char.

your colision detection should be something like (presudo code)...

int myx;
int myy;
int adderx=0;//to reset
int addery=0;


inputdown(because the y axis is inverted)
addery++;

inputup
addery--;

inputright
adderx++;

inputleft
adderx--;


if(map[myy+addery][myx+adderx])!='#';//this is a resistant char
{
mapx+=adderx;
mapy+=addery;
}

ALSO...

dont forget to clear the screen like this(because it has no flicker):
COORD newpos = {0,0};
SetConsoleCursorPosition( GetStdHandle(STD_OUTPUT_HANDLE), newpos );

AND..

you can colour the screen like this

HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, 67); //this int defines colour
cout << "#";
SetConsoleTextAttribute(hConsole, 99); //this int defines colour
cout << "#";
Last edited on
closed account (GbX36Up4)
Thanks, I'm really tired and lazy to do it right now, but I will make sure to try it out tommorow and show you guys the results :P
Topic archived. No new replies allowed.