Correcting a grid map display

Been trying to solve this for hours but has been futile. Below is a reproducible code

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
    #include <stdio.h>
    #include <iomanip>
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int grid_x_length = 6;
    	int grid_y_length = 6;
    	int y_counter = 6;
    	int x_counter = 0;
    	
    	int xArray[4];
    	xArray[0] = 1;
    	xArray[1] = 1;
    	xArray[2] = 1;
    	xArray[3] = 2;
    	
    	int yArray[4];
    	yArray[0] = 1;
    	yArray[1] = 2;
    	yArray[2] = 3;
    	yArray[3] = 1;
    	
    	for(int row = grid_y_length+2; row >= -1; row--)
    	{
    		for(int col = 0; col <= grid_x_length+3; col++)
    		{
                        // print empty space at the start and end
    			if((col == 0) && (row == 0) || (col == 0) && (row == grid_y_length+2))
    				cout << setw(3) << left << "   ";

                        // print y axis scale
    			else if ((col == 0) && (row >= 1) && (row < grid_y_length+3))
    				cout << setw(3) << left << y_counter--;

                        // print empty space at the start 
    			else if ((col == 1) && (row == -1) || (col == grid_x_length+3) && (row == -1))
    				cout << setw(3) << left << "   ";
         
                        // print x axis scale
    			else if ((col >= 1) && (row == -1))
    				cout << setw(3) << left << x_counter++;

    			else if ((row == grid_y_length+2) && (col > 0) && (col <= grid_x_length+3)) // top border
    				cout << setw(3) << left << "#";
    			else if ((row == 0) && (col > 0) && (col <= grid_x_length+3)) // bottom border
    				cout << setw(3) << left << "#";
    			else if ((col == 1) && (row > 0) && (row < grid_y_length+2)) // left border
    				cout << setw(3) << left << "#";
    			else if ((col == grid_x_length+3) && (row > 0) && (row < grid_y_length+2)) // right border
    				cout << setw(3) << left << "#";
    			else
                                // print X location
    				for(int i = 0; i < 4; i++)
    				{
    					if (row == yArray[i]+1 && col == xArray[i]+2)
    					{
    						cout << setw(3) << left << "X";
    					}
    				}
                   
                    // attempted attempt to resolve the issue
    				//if(row >= 2 && col >= 1)
    				//	cout << "   ";

    			//	cout << "   "; // use this when you omit the for loop to print perfect map
    		}
    		cout << endl;    
    	}
        return 0;
    }


Output using above code:


       #  #  #  #  #  #  #  #  #                                                                                                  
    6  #  #                                                                                                                       
    5  #  #                                                                                                                       
    4  #  #                                                                                                                       
    3  #  X  #                                                                                                                    
    2  #  X  #                                                                                                                    
    1  #  X  X  #                                                                                                                 
    0  #  #                                                                                                                       
       #  #  #  #  #  #  #  #  #                                                                                                  
       0  1  2  3  4  5  6  


Expected output:


       #  #  #  #  #  #  #  #  #                                                                                                  
    6  #                       #      
    5  #                       #                                                                                                                       
    4  #                       #                                                                                                                       
    3  #     X                 #                                                                                                                    
    2  #     X                 #                                                                                                                    
    1  #     X  X              #                                                                                                                 
    0  #                       #                                                                                                                       
       #  #  #  #  #  #  #  #  #                                                                                                  
          0  1  2  3  4  5  6 


The objective is to use the X/Y arrays to pinpoint the coordinates on the map with `X`. The grid map display perfectly when I omit the `for loop` in the `else` block. However once I include it , the map will not display properly because there is no empty spaces. I have attempted to add another `if` in the `else` block but this did not produce the expected result (see commented portion in the code).

I have also tried to replace the `for loop` and putting the conditions in the `else if` but the `X` will only print once (the last x,y coordinate from the array).

Does anyone has any suggestion on how to get the expected results?
Last edited on
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
#include <iostream>
#include <string>
using namespace std;

int main()
{
   const int N = 7;
   string grid[N+3];   for ( string &s : grid ) s = string(3*N+7,' ');
   int left = 3, right = 3 * N + 6;
   int bottom = N + 1, top = 0;

   int x[] = { 1, 1, 1, 2};
   int y[] = { 1, 2, 3, 1};
   int NPTS = sizeof x / sizeof x[0];

   // Border
   for ( int j = left; j <= right; j += 3 ) grid[top][j   ] = grid[bottom][j    ] = '#';
   for ( int i = 1   ; i <= N    ; i++    ) grid[i  ][left] = grid[i     ][right] = '#';

   // Numbers
   for ( int j = 0; j < N; j++ ) grid[bottom+1  ][left+3*(j+1)] = '0' + j;
   for ( int i = 0; i < N; i++ ) grid[bottom-1-i][0           ] = '0' + i;

   // Initial points
   for ( int n = 0; n < NPTS; n++ ) grid[bottom-1-y[n]][left+3*(x[n]+1)] = 'X';

   for ( string s : grid ) cout << s << '\n';
}


   #  #  #  #  #  #  #  #  #
6  #                       #
5  #                       #
4  #                       #
3  #     X                 #
2  #     X                 #
1  #     X  X              #
0  #                       #
   #  #  #  #  #  #  #  #  #
      0  1  2  3  4  5  6   
Thanks for the reply.

Is there no other ways to solve my issue other than to rewrite the code?

Also can you explain on how you build your border? It's the first time I am seeing such syntax (maybe its all in one liner)
newbie812 wrote:
Is there no other ways to solve my issue other than to rewrite the code?

I can't decipher your code.



This one's a bit more flexible; (you can adapt the bordering by adjusting functions ival and jval). Same output.

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

int main()
{
   const int N = 7;
   vector<string> grid( N + 3, string( 3 * N + 7, ' ' ) );

   auto ival = [N]( int y ){ return N - y; };
   auto jval = [N]( int x ){ return 3 * ( x + 2 ); };

   int XPT[] = { 1, 1, 1, 2};
   int YPT[] = { 1, 2, 3, 1};
   int NPTS = sizeof XPT / sizeof XPT[0];

   // Border (effectively, top corresponds to y=N, bottom to y=-1 etc)
   for ( int x = -1; x <= N; x++ ) grid[ival(-1)][jval( x)] = grid[ival(N)][jval(x)] = '#';
   for ( int y =  0; y <  N; y++ ) grid[ival( y)][jval(-1)] = grid[ival(y)][jval(N)] = '#';

   // Numbers (effectively placed at y=-2 or x=-2)
   for ( int x = 0; x < N; x++ ) grid[ival(-2)][jval( x)] = '0' + x;
   for ( int y = 0; y < N; y++ ) grid[ival( y)][jval(-2)] = '0' + y;

   // Initial points
   for ( int n = 0; n < NPTS; n++ ) grid[ival(YPT[n])][jval(XPT[n])] = 'X';
   
   // Output
   for ( string s : grid ) cout << s << '\n';
}
Last edited on
Is there no other ways to solve my issue other than to rewrite the code?

you can debug and fix it, most likely. I mean, it looks to me like your only issue is not padding spaces internally?
Fixing it may take some doing, but that is the alternative.

Everyone has a throw out and redo moment sometimes. You get a block the size of a page, maybe 2 pages, that does not work and is difficult to debug and fix, and you throw it out, using what you learned from your mistakes and what went well, and build it again doing better the second time. Happens to everyone, and some coders expect to rewrite complex things a time or 2 before calling it done.
Last edited on
Hi everyone. Thank you for your responses so far.

Indeed, I am more keen to work on the set of my code and trying to rectify it.

You are also right, the issue lies with padding the spaces internally after 'X' is place inside the map. I do not know how to manipulate the map to tell it to look at (if its empty, put space, if condition is met (x and y), put X).

I have added comments to my if else if it helps someone to understand what the code is. The idea is to understand how to effectively use for loop and if else to do this.
Last edited on
I am more keen to work on the set of my code and trying to rectify it.
Here is a start to you fixing your abominable code. All you need is another couple of convoluted if's and judicious use of left and right - if you must

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
#include <stdio.h>
#include <iomanip>
#include <string>
#include <iostream>

using namespace std;

int main()
{
    int grid_x_length = 6;
    int grid_y_length = 6;
    int y_counter = 6;
    int x_counter = 0;
    
    int xArray[4];
    xArray[0] = 1;
    xArray[1] = 1;
    xArray[2] = 1;
    xArray[3] = 2;
    
    int yArray[4];
    yArray[0] = 1;
    yArray[1] = 2;
    yArray[2] = 3;
    yArray[3] = 1;
    
    for(int row = grid_y_length+2; row >= -1; row--)
    {
        for(int col = 0; col <= grid_x_length+3; col++)
        {
            // print empty space at the start and end
            if(((col == 0) && (row == 0)) || ((col == 0) && (row == grid_y_length+2)))
                cout << setw(5) << right << "   ";
            
            // print y axis scale
            else if ((col == 0) && (row >= 1) && (row < grid_y_length+3))
                cout << setw(3) << right << y_counter--;
            
            // print empty space at the start
            else if (((col == 1) && (row == -1)) || ((col == grid_x_length+3) && (row == -1)))
                cout << setw(8) << right << " ";
            
            // print x axis scale
            else if ((col >= 1) && (row == -1))
                cout << setw(3) << left << x_counter++;
            
            else if ((row == grid_y_length+2) && (col > 0) && (col <= grid_x_length+3)) // top border
                cout << setw(3) << left << "#";
            else if ((row == 0) && (col > 0) && (col <= grid_x_length+3)) // bottom border
                cout << setw(3) << left << "#";
            else if ((col == 1) && (row > 0) && (row < grid_y_length+2)) // left border
                cout << setw(3) << right << "#";
            else if ((col == grid_x_length+3) && (row > 0) && (row < grid_y_length+2)) // right border
                cout << setw(24) << right << "#";
            else
                // print X location
                for(int i = 0; i < 4; i++)
            {
                if (row == yArray[i]+1 && col == xArray[i]+2)
                {
                    cout << setw(6) << right << "X";
                }
            }
        }
        cout << endl;
    }
    return 0;
}


   #  #  #  #  #  #  #  #  #  
  6  #                       #
  5  #                       #
  4  #                       #
  3  #     X                       #
  2  #     X                       #
  1  #     X     X                       #
  0  #                       #
     #  #  #  #  #  #  #  #  #  
        0  1  2  3  4  5  6          
Program ended with exit code: 0


The only sense I can make out of your 'graphic' is you are plotting bar charts.

If that's the case and the data is changing, rather than being a one-off, then like @jonnin indicates you need to consider stop digging because it's the very hard way to go about it. Your 'hours to solve it' are better spent on setting up an array of characters and then after that's done displaying the complete array line by line. That way you can throw out most, if not all, of your if's, set's, left's and right's because you won't need them.

It's your decision needless to say, so happy excavating if you like.
:)
Newbie812, your logic is inside out. You have generic loops and the within the loop, a ton of if statements to decide where you are the diagram. Here's a version that prints the pieces one at a time:
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
#include <stdio.h>
#include <iomanip>
#include <string>
#include <iostream>

using namespace std;

int
main()
{
    int grid_x_length = 6;
    int grid_y_length = 6;

    int xArray[4];
    xArray[0] = 1;
    xArray[1] = 1;
    xArray[2] = 1;
    xArray[3] = 2;

    int yArray[4];
    yArray[0] = 1;
    yArray[1] = 2;
    yArray[2] = 3;
    yArray[3] = 1;

    // Top border
    cout << setw(8) << right << "#";
    for (int col = 0; col <= grid_x_length+1; col++) {
	cout << setw(3) << right << '#';
    }
    cout << '\n';
    for (int row = grid_y_length; row >= 0; row--) {
	// Print empty space at start of each row. No need for width
	// and alignment specifiers since it's exactly 3 spaces
	cout << "  ";

	// print y axis scale and left border
	cout << setw(3) << right << row << "  #";

	for (int col = 0; col <= grid_x_length; col++) {
	    // Get the character to  print
	    char printChar = ' ';
	    for (int i = 0; i < 4; i++) {
		if (row == yArray[i] && col == xArray[i]) {
		    printChar = 'X';
		    break;
		}
	    }

	    cout << "  " << printChar; // print it
	}
	cout << "  #\n";	// right border
    }
    // Bottom border
    cout << setw(8) << right << "#";
    for (int col = 0; col <= grid_x_length+1; col++) {
	cout << setw(3) << right << '#';
    }
    cout << '\n';

    // X axis scale
    cout << setw(8) << ' ';
    for (int col = 0; col <= grid_x_length; col++) {
	cout << setw(3) << right << col;
    }
    cout << '\n';

    return 0;
}

Topic archived. No new replies allowed.