2d grid using array c++

Pages: 12
I have to create a grid that start out in the position left top corner (0,0). Then the program would go randomly up down right or left until it gets stuck or reaches letter Z.
I have to use the functions
bool can_go_left(int i, int j);
bool can_go_right(int i, int j);
bool can_go_up(int i, int j);
bool can_go_down(int i, int j);
&&
void initialize_grid(char grid[M][N]);
void print_grid(char grid[M][N]);

Here's what I have so far. When I try to run it, it gives gibberish symbols instead of letters A to Z.
If you can let me know what I did wrong and How to fix it it would be so helpful


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
#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;
const int M = 10;
const int N = 6;

void initialize_grid(char grid[M][N]);
void print_grid(char grid[M][N]);
bool can_go_left(int i, int j);
bool can_go_right(int i, int j);
bool can_go_up(int i, int j);
bool can_go_down(int i, int j);


int main()
{
    srand(time(NULL));
    char grid[M][N];
    // Start out with '.' (DOT) in each space


   bool can_go_left();
   bool can_go_right();
  bool can_go_down();
   bool can_go_up();
    print_grid(grid);

}
bool can_go_left(int i, int j)
{

   int CurrentI = 0;
    int CurrentJ = 0;
    char CurrentChar = 'A';
    while(CurrentChar <= 'Z' && CurrentI < M
          && CurrentJ < N)
    {
   switch(rand() % 2)
   {
       case 0: CurrentJ--;
       return true;
   }
    }
}

bool can_go_right(int i, int j)
{
    int CurrentI = 0;
    int CurrentJ = 0;
    char CurrentChar = 'A';
    while(CurrentChar <= 'Z' && CurrentI < M
          && CurrentJ < N)
          {


    switch(rand() % 2)
    {
        case 0: CurrentJ++;
    }
          }
}
bool can_go_down(int i, int j)
{
     int CurrentI = 0;
   int CurrentJ = 0;
char CurrentChar = 'A';
    while(CurrentChar <= 'Z' && CurrentI < M
        && CurrentJ < N)
          {


   switch(rand() % 2)
    {
        case 0: CurrentI++;
    }
}
}
bool can_go_up(int i, int j)
{
    int CurrentI = 0;
    int CurrentJ = 0;
    char CurrentChar = 'A';
    while(CurrentChar <= 'Z' && CurrentI < M
        && CurrentJ < N)
    {


    switch(rand() % 2)
    {
      case 0: CurrentI--;
    }
          }
}

void initialize_grid(char grid[M][N])
{
    int CurrentI = 0;
    int CurrentJ = 0;
    char CurrentChar = 'A';
    while(CurrentChar <= 'Z' && CurrentI < M
          && CurrentJ < N)
    {
        // Mark our position
        grid[CurrentI][CurrentJ] = CurrentChar;
        CurrentChar++;
    }
}

void print_grid(char grid[M][N])
{
      for(int i = 0; i < M; i++) {
        for(int j = 0; j < N; j++) {
            cout << grid[i][j];
        }
        cout << endl;
}
}
Last edited on
It gives gibberish symbols because you haven't initialised grid before you try to print it.

How to fix it?
- Remove all your functions can_go_left() etc. YES, REALLY, REMOVE THEM. Start from a short code and develop it SLOWLY.

- Have int main() call just two functions - initialize_grid and print_grid. UNTIL THESE ARE WORKING YOU SHOULD NOT WRITE ANY NEW FUNCTIONS. print_grid will work; initialise_grid won't (it never changes the i or j indices; you are simply changing grid[0][0] repeatedly until it gets to 'Z'). It is not actually clear what you want to do, because your comment line 21 is inconsistent with what you appear to be trying to do in line 106.

It would help with debugging if you made your code indentation consistent.

Please state your problem more clearly.
Last edited on
closed account (48T7M4Gy)
lastchance is quite right in his advice. To write 119 lines of code a not test it is just a waste of time.

However, a couple of the non-void (bool) functions don't return anything.

But on balance, I think you should take the lastchance advice and do unit testing and show us the problems etc with each in turn to avoid being here for hours. :)
Last edited on
xx123

Provided main only calls initialize_grid and print_grid, then your output should look like this (not very exciting) array after initialisation:
......
......
......
......
......
......
......
......
......
......

PROCEED ONLY WHEN YOU HAVE SUCCESSFULLY GOT THIS.



Ultimately, you are after one of two possibilities.
The grid proceeds to completion, for example:
ABC...
..D...
.FE...
.GJK..
.HIL..
..NMZY
..O..X
..PQVW
...RU.
...ST.

or it gets stuck, for example:
A.....
BCFG..
.DEH..
...IJ.
....K.
....LM
....ON
....PU
....QT
....RS


From the name of the functions concerned, I would guess that your bool functions are simply telling you whether a move is POSSIBLE from the current position i, j, and not actually making that move (i.e. changing the current character). Consider, for example,
bool can_go_left( i, j )
You can only "go left" if i > 0 (because otherwise you would cross the left boundary) and that position is not already occupied (i.e. it is still '.'). Just as an example, you might use
1
2
3
4
bool can_go_left ( int i, int j )
{
   return ( i > 0  && grid[i-1][j] == '.' );
}

This presupposes that grid[M][N] is being treated as a global variable like M and N; if not, you will need to include it in the function definition; thus:
bool can_go_left ( int i, int j, grid[M][N] )

You should be able to create the other functions similarly. Your sequential population of the grid could be done from int main() itself if you wish.
Last edited on
Okay so I did what you said, but however I don't know how to recall the boolean statements as true and update the character.

here is the updated code:

#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;
const int M = 10;
const int N = 6;

void initialize_grid(char grid[M][N]);
void print_grid(char grid[M][N]);
bool can_go_left(int i, int j);
bool can_go_right(int i, int j);
bool can_go_up(int i, int j);
bool can_go_down(int i, int j);


int main()
{
srand(time(NULL));
char grid[M][N];
int i = 0;
int j = 0;
char currentChar = 'A';
while(currentChar <= 'Z' && i < M && j < N)
{ bool can_go_left();
bool can_go_right();
bool can_go_up();
bool can_go_down();
currentChar++;
}

initialize_grid(grid);
print_grid(grid);

}
bool can_go_left(int i, int j, char grid[M][N])
{
return ( j > 0 && grid[j-1][i] == '.');
}

bool can_go_right(int i, int j, char grid[M][N])
{
return ( j < 0 && grid[j+1][i] == '.');
}
bool can_go_down(int i, int j, char grid[M][N])
{
return ( i < 0 && grid[j][i+1] == '.');
}
bool can_go_up(int i, int j, char grid[M][N])
{
return ( i > 0 && grid[j][i-1] == '.');
}
void initialize_grid(int i, int j, char grid[M][N])
{
for(int i = 0; i < M; i++)
{
for(int j = 0; j < N; j++)
{
grid[i][j] = '.';
}
}
}
void print_grid(char grid[M][N])
{
for(int i = 0; i < M; i++) {
for(int j = 0; j < N; j++) {
cout << grid[i][j];
}
cout << endl;
}
}
closed account (48T7M4Gy)
I don't know how to recall the boolean statements as true and update the character


This is where you need to step back from the coding and analyse what you are supposed to do. A good way to do this is with pseudocode.

It would go something like this:
My current position is i,j
Can I go left? true or false*
If the answer is true then move left and update current position
If the answer is false then stay put and try another direction

Now you need to write pseudocode which answers the first part of your question, to give the true false answer above*:
...

xx123

Before you do anything else, please REMOVE from int main() your block of code
1
2
3
4
5
6
7
while(currentChar <= 'Z' && i < M && j < N)
{ bool can_go_left();
bool can_go_right();
bool can_go_up();
bool can_go_down();
currentChar++;
}

It makes no sense and it's in the wrong place (before you have even initialised the grid).

Next, have a look at your functions can_go_left() etc.
- these return either 'true' or 'false': remember this;
- you will get everyone confused if the i and j indices in these functions are in order grid[j][i], whereas in print_grid and initialize_grid they are in the opposite order, grid[i][j]: I strongly recommend changing this. Also, check these functions carefully: they will be crucial later on. Note also that 'left' and 'right' will be OK, but 'up' and 'down' could refer to the actual index increasing and decreasing, which (given the perfectly reasonable order in which the grid is printed) will not be the same as the direction on the printed page: be aware of this, at least.

In int main() You have variables i and j to store current position and currentChar to store the character. These are correctly initialised, so all good here. Why don't you, at this stage, assign this starting point on the grid and print the grid; with your new values M=10 and N=6 this should look like the following:
A.....
......
......
......
......
......
......
......
......
......

If this is OK, then move on.


Try just ONE move first. You need to generate a random number - either amongst the values 0,1,2,3 say, or 1,2,3,4 say - entirely your choice. You must decide for yourself which of those numbers correspond to left, which to right, which to up, which to down. (Entirely free choice - but you must stick to it thereafter.) While testing, output this number to check that it is OK.

Now you can use either a switch or an 'if' block to respond to the particular number and its corresponding direction. Suppose it corresponded to moving left - you would then check the can_move_left(..) function. If it returns false then you do nothing; if it returns true then you can: increment i and j, update the grid, update currentChar.

After the first move the top left corner of your grid can only look like one of the following (the first corresponds to an impossible move which would have gone through left or top boundaries).
A.
..
AB
..
A.
B.


Once this is done, you can then try a SMALL, FIXED number of moves. While testing, print out any variables you need and the grid at the end of each step. Note that your results will be different with each run if you are using random numbers. (While developing, you could ask the user to put in prescribed numbers instead, so as to test and debug.)

Here is an example after a few moves (some of the projected moves not being possible).
ABC...
..DE..
...F..
......
......
......
......
......
......
......



Finally, you can write a loop that runs to completion. Your condition for stopping will be
currentChar has reached (or gone beyond) 'Z'
OR
you are stuck (i.e. can_go_left AND can_go_right AND can_go_down AND can_go_up all return false)

Think about the logic statement that encompasses this.


Some suggestions for code development:
- don't add too much code at once; compile regularly and don't move on if not compiling;
- print out the values of any variables to see what is going on; you can remove this in the final version;
- track the calculations and output with pen and paper.


Good luck!




Last edited on
So would you suggest the switch statement to be in the print grid instead of int main?
closed account (48T7M4Gy)
A couple of code snippets:

1
2
3
4
5
6
7
 switch (direction)
        {
            case 0:
                if(can_go_up(grid, current_row, current_col))
                    set_current_position(grid, --current_row, current_col, ++current_character);
                break;
            case 1: etc etc


1
2
3
4
5
6
7
8
// UP
bool can_go_up(char g[][COLS], int i, int j)
{
    if ( i > 0 and g[i - 1][j] == '*')// * means cell unoccupied
        return true;
    else
        return false;
}


1
2
3
4
5
6
void set_current_position(char g[][COLS], int i, int j, char ch)
{
    g[i][j] = ch;
    display_grid(g);
    return;
}
Where would you suggest the switch statement to go? Is it okay in int main or do I have to move it into a separate function?
closed account (48T7M4Gy)
main() is an ideal place for it.

Since there are numerous moves involved the process needs to be in some form of loop:

1
2
3
4
while there are still characters available (ie < 'Z')
   generate a random move
   switch on direction
loop


BTW you need to look carefully at how the moves occur because in the 0,0 starting position there are only 2 directions available. (down and go_right)
Last edited on
Hello xx123

The switch statement can go in whichever loop you progress around for each "move". This can be inside main if you like, or a separate function. However, I can't see any way it would be inside print_grid().
is char g[][COLS] the same as grid[M][N]?
I am having trouble understanding the calling to the bool function

while(currentChar <= 'Z' && CurrentI < M
&& CurrentJ < N)
{ rand() % 4;
switch(direction)
{ case 0:
if(can_go_left(grid, i , j))
{CurrentJ++;
grid[CurrentI][CurrentJ] = currentChar;
currentChar++;}
}
}

does that work?
When I try to call the Boolean function it says too many arguments
Hello xx123,

is char g[][COLS] the same as grid[M][N]

I'm not sure of the context here. You can call your array whatever you like - g or grid - as long as you are consistent throughout your program. I thought from your original posting that you were using grid. Similarly, only you know what you are calling the size of the second index, but in your original posting you were calling it N, not COLS.

while(currentChar <= 'Z' && CurrentI < M
&& CurrentJ < N)
{ rand() % 4;
switch(direction)
{ case 0:
if(can_go_left(grid, i , j))
{CurrentJ++;
grid[CurrentI][CurrentJ] = currentChar;
currentChar++;}
}
}


The currentChar bit in the while condition is OK, but CurrentI is only being checked against one side of the array, not both. Similarly CurrentJ. Why don't you use your boolean routines can_go_left, can_go_right, can_go_down, can_go_up here - that's what they are there for.

You need to assign a variable to your random number. It looks like you meant to use
direction = rand() % 4;
You can then switch on direction as you have started to do. Make sure that you consider all values that direction can take. Have a look at some of the diagrams that I posted earlier.

When I try to call the Boolean function it says too many arguments 

Whichever function(s) you are referring to, count the number of arguments in the definition of that function, the prototype of that function, and any call to that function: these numbers of arguments must all be the same (as must their types).

Have a good go at trying to get this to work first. Post full code (in code tags) if you are really struggling. Try to check the things that @kemort and I have been referring to.

I took your advice & got the A to print at (0,0).
will try the rest & let you guys know. Thanks a lot!
Does anyone know why this is not compiling and giving me a return error?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void set_current_position(int i, int j, char grid[M][N], char CurrentChar)
{
    int CurrentI = 0;
    int CurrentJ = 0;
    CurrentChar = 'A';
    grid[CurrentI][CurrentJ] = CurrentChar;
    if(can_go_down(i,j))
    {
        CurrentI++;
        CurrentJ;
        CurrentChar++;
        grid[CurrentI][CurrentJ] = CurrentChar;
    }
}
closed account (48T7M4Gy)
Pleas show us a full and tagged listing of your program.

BTW when do you have to hand your project in?
Last edited on
It was actually due a couple days ago, but i can always submit it 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
93
94
95
96
#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;
const int M = 10;
const int N = 6;

void initialize_grid(char grid[M][N]);
void set_current_position(int i, int j, char grid[M][N], char CurrentChar);
void print_grid(char grid[M][N]);
bool can_go_left(int i, int j);
bool can_go_right(int i, int j);
bool can_go_up(int i, int j);
bool can_go_down(int i, int j);


int main()
{
    srand(time(NULL));
    char grid[M][N];

int i = 0;
int j = 0;
char CurrentChar;
initialize_grid(grid);
set_current_position(i, j, grid, CurrentChar);
print_grid(grid);
}


bool can_go_left(int i, int j, char grid[M][N])
{
   if ( j > 0 && grid[j-1][i] == '.')
     return true;

   else
    return false;
}

bool can_go_right(int i, int j, char grid[M][N])
{
    if ( j < 0 && grid[j+1][i] == '.')
        return true;
    else
        return false;
}
bool can_go_down(int i, int j, char grid[M][N])
{
    if ( i < 0 && grid[j][i+1] == '.')
        return true;
    else
        return false;
}
bool can_go_up(int i, int j, char grid[M][N])
{
    if ( i > 0 && grid[j][i-1] == '.')
        return true;
    else
        return false;
}
void set_current_position(int i, int j, char grid[M][N], char CurrentChar)
{
    int CurrentI = 0;
    int CurrentJ = 0;
    CurrentChar = 'A';
    grid[CurrentI][CurrentJ] = CurrentChar;
    if(can_go_down(i,j))
    {
        CurrentI++;
        CurrentJ;
        CurrentChar++;
        grid[CurrentI][CurrentJ] = CurrentChar;
    }
}

void initialize_grid(char grid[M][N])
{
    for(int i = 0; i < M; i++)
    {
        for(int j = 0; j < N; j++)
        {
            grid[i][j] = '.';
        }
    }
}
void print_grid(char grid[M][N])
{
      for(int i = 0; i < M; i++) {
        for(int j = 0; j < N; j++) {
            cout << grid[i][j];
        }
        cout << endl;
}
}
closed account (48T7M4Gy)
Yeah, I thought it was due on the 13th. I was just curious, thanks.

Well, like lastchance said, do this in short steps. Don't repost any more just go back and edit this version. Otherwise this will go on forever.

First, delete lines 68-74 inclusive. It's BS.
Pages: 12