• C

Draw a square

I have a function that is supposed to accept an odd number and draw a corresponding square with an '*' the square has two diagonals and all other spaces are left blank.Any ideas on how this can be done? I have started with a 2-d arrray

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
If you draw the output on paper and take note of the coordinates (your 2-d array indices), you'll see a pattern...
0
Commented:
looks like homework :)
here is an easy process, you can implement this.

declare an array [100][100] and initialize with space.
then take an input odd N from user.
make all the columns of row[1] = '*' using loop
make all the columns of row[N] = '*' using loop
make all the rows of column[1] = '*' using loop
make all the rows of column[N] = '*' using loop

finaly print all NxN into screen from (1,1)

~marchent~
0
Commented:
marchent: I think wkellya wants to draw the diagonals in the square and not the perimeter

wkellya: You don't need an array to do this. If you do what I suggested above, you'll see a pattern and the *'s will occur in two conditions:

1) row == column
2) row == N - column - 1

where N is the input. Then, in your code, set up two for loops (one to traverse each row and the other to traverse each column) each up to N and finally output a "*" when either of the above two conditions are met, or " " otherwise.
0
Author Commented:
I should have mentioned.The perimeter of the square has to be drawn and the diagonals. so I think what marchent was suggesting is on the right track a little more clarification would help though.

0
Commented:
since the indexing from (1,1) so the loop for diagonal should be
for(i=1;i<=N;i++)
A[i][i] = A[i][N - i + 1] = '*';

the patterns is as below
doagonal -1
(1,1) : (2,2) : (3,3) : (4:4) ... (N:N)
diagonal -2
(1,N): (2,N-1) : (3,N-2)  ... (N:1)

~marchent~
0
Author Commented:
Ok so at this point is it better to define the maximum square 19*19 fill that with zeros and  draw in the perimeter and the diagonals or fill the whole square with "*" and carve out the blank spots
0
Commented:
nope, fill with empty 19x19, and plot the *'s there using the loops.
0
Author Commented:
And what about the perimeter? How do I loop to fill just the first and last columns and rows I've been trying to do both in one loop but it isn't working out
0
Commented:
for(i=1;i<=N;i++)
A[1][i] = A[N][i] = '*';

first one is column 1 and last one is column N
0
Commented:
>> I've been trying to do both in one loop but it isn't working out
0
Author Commented:
for(int x=0;x<oddint;x++)
{
for(int y=0;y<oddint;y++)
{
square[x][0]='*';
square[x][oddint]='*';
square[y][0]='*';
square[y][oddint]='*';

}
}
0
Commented:
It's a start, but it doesn't really do what you want it to do. To understand what it's doing, try following the loops, and write on a piece of paper what it's outputting.

The easiest way to draw a square with its diagonals, is to do it in 3 steps :

1) draw the top line
2) draw the middle part (one line at a time in a loop)
3) draw the bottom line

1) and 3) are easy. The harder part is 2).
In each iteration of the loop in 2), you can draw the first and the last position. For the diagonals, you'll have to find the pattern for the cross. Take a look at this cross, and try to find a way how you could draw that one line at a time :

*     *
*   *
* *
*
* *
*   *
*     *
0
Author Commented:
so whats wrong with what I attempted?
0
Commented:
Take a look at what it does. I'll unroll the loops for oddint = 3 : First the innermost loop :

for(int x=0;x<oddint;x++)
{
square[x][0]='*';
square[x][oddint]='*';
square[0][0]='*';
square[0][oddint]='*';
square[x][0]='*';
square[x][oddint]='*';
square[1][0]='*';
square[1][oddint]='*';
square[x][0]='*';
square[x][oddint]='*';
square[2][0]='*';
square[2][oddint]='*';
}

And then completely :

square[0][0]='*';
square[0][oddint]='*';
square[0][0]='*';
square[0][oddint]='*';
square[0][0]='*';
square[0][oddint]='*';
square[1][0]='*';
square[1][oddint]='*';
square[0][0]='*';
square[0][oddint]='*';
square[2][0]='*';
square[2][oddint]='*';

square[1][0]='*';
square[1][oddint]='*';
square[0][0]='*';
square[0][oddint]='*';
square[1][0]='*';
square[1][oddint]='*';
square[1][0]='*';
square[1][oddint]='*';
square[1][0]='*';
square[1][oddint]='*';
square[2][0]='*';
square[2][oddint]='*';

square[2][0]='*';
square[2][oddint]='*';
square[0][0]='*';
square[0][oddint]='*';
square[2][0]='*';
square[2][oddint]='*';
square[1][0]='*';
square[1][oddint]='*';
square[2][0]='*';
square[2][oddint]='*';
square[2][0]='*';
square[2][oddint]='*';

Can you see what's not correct ?
0
Author Commented:
Not exactly it is supposed to fill the perimeter i was going to do the diagonals in another loop
0
Commented:
>> Not exactly it is supposed to fill the perimeter
And is it doing that ? Why not ? Take a look at the unrolled version of your loops in my last post to see wh yit's not working.
0
Author Commented:
i'm not seeing it
0
Commented:
>> i'm not seeing it

Well, then take a piece of paper and draw a 3 by 3 grid on that.
Then go over the unrolled loop I posted, and place mraks in the grid. Try to see what's going wrong.
0
Author Commented:
0
Commented:
Yes, the first line :

square[0][0]='*';

marks row 0, column 0.

That's right.

Now do the same for the other lines. And you'll immediately see where the problem lies.
0
Author Commented:
Its only assigning one '*'
0
Commented:
>> Its only assigning one '*'
To be more exact, it's marking the same positions over and over again, and it's only marking the left and right sides of the square.

So, follow the 3 steps I listed earlier, and try to come up with new code to do them.
0
Author Commented:
I'm just not getting this its just not working.Thanks for the help tho i'll split the points to be fair.
0
Commented:
wkellya, you don't have to close this question until your problem is solved
0
Commented:
>> I'm just not getting this its just not working.
How far did you get. What do you have now ?
0
Author Commented:
for(int x=0;x<oddint;x++)
{
for(int y=0;y<oddint;y++)
{
square[0][y]='*';
square[oddint][y]='*';
}
}
for the top and bottom rows but i'm only getting the top
0
Commented:
That's closer, but you don't need nested loops for this. Just this loop :

for(int y=0;y<oddint;y++)
{
square[0][y]='*';
square[oddint][y]='*';
}

will achieve the same, namely to draw the left and right borders of the square.
0
Author Commented:
so why isn't the bottom row being drawn with just this? won't I need to nest if I want to fill the left and right colomns?
0
Commented:
>> so why isn't the bottom row being drawn with just this?
This doesn't "draw" anything - it's just filling in a matrix.

Can you show the complete code you're using ?
0
Author Commented:
that is it other than the initialization  zeros and the print out

for( int i=0;i<oddint;i++)
{
for(int j=0;j<oddint;j++)

printf("%c  " ,square[i][j]);

}
0
Commented:
>> that is it other than the initialization  zeros and the print out
Can you show the code completely, please ?

You can already start by adding a newline in the output loops :

for( int i=0;i<oddint;i++)
{
for(int j=0;j<oddint;j++) {
printf("%c  " ,square[i][j]);
}
printf("\n");
}
0
Commented:
btw, is there a reason that you're using a matrix ? Why not just directly output ?
0
Author Commented:
isn't a 2d array easier?
0
Commented:
>> isn't a 2d array easier?
Well, it's an extra step. If you want to use it, fine - it's your choice.

Any progress ? How about the complete code ?
0
Author Commented:
no progress i just  just took a break complete function
void drawSquare(int oddint)
{

int square[row_size][col_size];

for(int i=0;i<row_size;i++)
{
for(int j=0;j<col_size;j++)
{
square[i][j]=0;
}
}

for(int x=0;x<oddint;x++)
{
for(int y=0;y<oddint;y++)
{
square[0][y]='*';
square[oddint-1][y]='*';

}
}

for( int i=0;i<oddint;i++)
{
for(int j=0;j<oddint;j++)

printf("%c " ,square[i][j]);

}

}
0
Author Commented:
i upped the points does anyone want to jump in here and tell me where i'm going wrong?
0
Commented:
>>                   square[i][j]=0;
For initializing, it's better to use a space like this :

square[i][j] = ' ';

And about the main part where you fill the matrix :

for(int x=0;x<oddint;x++)
{
for(int y=0;y<oddint;y++)
{
square[0][y]='*';
square[oddint-1][y]='*';

}
}

As I said earlier, there is no reason to have a nested loop here. I repeat : the following does exactly the same :

for(int y=0;y<oddint;y++)
{
square[0][y]='*';
square[oddint-1][y]='*';

}

It just draws the left and right side of the square.

Did you try with the 3 steps I suggested earlier ?

Just fyi : we are not allowed to do the work for you, since this is most likely homework, but we will help you find the solution yourself.
Please take note of the suggestions made, make some modifications to your code, and post it again if you have further questions/problems.

If something is not clear, then please tell us so, clearly indicating what it is that is not clear. Just saying that it still doesn't work, does not help us understand what problem you are having.
0
Author Commented:
the second loop is for the bottom line. Are u saying i can't draw the perimeter using the two existing loops?How many loop will i need?One for each line?

ps:i don't want anyone to tell me anything of course i wouldn't learn anything if they did i just need some pointers on what is wrong with my code since I'm not seeing it ur way.I saw ur three steps  and this is the approach i was always using but the problem lies in trying to implement them.
0
Commented:
>> and this is the approach i was always using but the problem lies in trying to implement them.

Ok, then explain me your approach. The code that you showed is not enough for me to understand what you're trying to do.
0
Author Commented:
for(int x=0;x<oddint;x++)
{
for(int y=0;y<oddint;y++)
{
square[0][y]='*';//Fill in all the columns in row 0
square[oddint-1][y]='*';//Fill in all the column in the last row
square[x][0]='*'; //Fill in all the rows in column 0 for left line
square[x][oddint-1]='*';//Fill in all the rows in  last column for the right line

}
}
0
Commented:
>>  isn't a 2d array easier?
If you don't use an array, then you'd have to output the image in a single pass. This is a little more difficult because you'd have to draw the diagonals and the perimeter at the same time. With an array, you can construct the image in it with multiple passes and finally one last pass to output. Using an array, one strategy might be to first construct the perimeter and then make a second pass to construct the diagonals.

>> int square[row_size][col_size];
Do you mean char array? You can also initialize the array without using for loops:
char square[row_size][col_size] = { ' ' };

>> Are u saying i can't draw the perimeter using the two existing loops?
He's saying the operations

square[0][y]='*';
square[oddint-1][y]='*';

don't depend on the outer loop (there is no x) so it is not needed. However, it is needed in order to draw the left and right sides, so including it as you did above is good.

>> square[x][0]='*'; //Fill in all the rows in column 0 for left line
>> square[x][oddint-1]='*';//Fill in all the rows in  last column for the right line
This code is correct but placed in a bad spot. It is being executed on every iteration of the inner loop. Although the output will be correct, the code redundantly writes to the same array indices (because x does not change).
0
Author Commented:
If it is correct why is the output wrong?
0
Commented:
You need to print a new line character ( '\n' ) after printing each row.
0
Commented:
>> If it is correct why is the output wrong?

I've already told you that, wkellya. See my earlier posts ...

>> Ok, then explain me your approach. The code that you showed is not enough for me to understand what you're trying to do.

You still didn't explain me your approach ... can you do that please. If you're not happy with the 3-step approach I suggested, then at least tell us yours, so we can help you implement it !
0
Commented:
>> If you don't use an array, then you'd have to output the image in a single pass. This is a little more difficult

And for the record, I don't agree with this for 3 reasons :

1) You have to use a 2d array, which makes the whole code more complicated.
2) Using my 3 steps to do it in a single pass is extremely easy to implement, so you don't need to be distracted by a 2d array.
3) I'm not sure that the assignment allows the use of a 2d array. It kind of defeats the purpose of the exercise.
0
Author Commented:
for(int x=0;x<oddint;x++)
{
for(int y=0;y<oddint;y++)
{

square[0][y]='*';//Fill in all the columns in row 0
square[oddint-1][y]='*';//Fill in all the column in the last row
square[x][0]='*'; //Fill in all the rows in column 0 for left line
square[x][oddint-1]='*';//Fill in all the rows in  last column for the right line

}
}

In this approach I'm trying to draw the perimeter. Once that is done correctly. I will implement a for loop to pass in the diagonals. Do you understand what I am saying? I understand in your step 2) you want me to draw the cross one line at a time but i have attempted that and it didn't work so so to want to try it this way.
0
Author Commented:
for(int i=0;i<=oddint;i++)

{
square[i][i] = square[i][oddint - i + 1] = '*';
}

This works for the first diagonal but only up to 5 beyond that it kind of overlaps
0
Commented:
You don't need the nested loop as I said earlier. Try just this :

for(int y=0;y<oddint;y++)
{
square[0][y]='*';//Fill in all the columns in row 0
square[oddint-1][y]='*';//Fill in all the column in the last row
square[y][0]='*'; //Fill in all the rows in column 0 for left line
square[y][oddint-1]='*';//Fill in all the rows in  last column for the right line
}

This will set the whole square (all 4 sides).

And for the cross, what you posted in your last code is very good :

for(int i=0;i<oddint;i++)
{
square[i][i] = square[i][oddint - i - 1] = '*';
}

I made only a minor modification, namely the upper limit for i in the for loop, and the column index.

That's it - you've got working code !!

Now, you could realise that you don't need two loops, and that you can just combine both loops into one loop.
0

Experts Exchange Solution brought to you by