Reputation: 21
I am currently working on a project for a CS class and I have been tasked with printing out a ASCII model of a building. The objective of this project is to allow the user to input an integer and have that integer be the amount of "sections" the building has. Below I have broken down the example given to me into sections. Any help would be greatly appreciated, thank you to anyone taking the time to read this.
The pattern is as follows. Section x = ((x * 2) + 2) = amount of lines of code & "width" of building. (x = any integer value)
|\/|
|/\| //section 0 ((section * 2) + 2)
/--\ 0 + 2 = 2
|\::/|
|:\/:| //section 1 ((section * 2) + 2)
|:/\:| 2 + 2 = 4
|/::\|
/----\
|\::::/|
|:\::/:|
|::\/::| //section 2 ((section * 2) + 2)
|::/\::| 4 + 2 = 6
|:/::\:|
|/::::\|
/------\
I managed to figure out the pattern, but am having a really hard time with embedding several loops within one another. The best representation of this building I have so far is this.
int i = 0;
int j = 0;
int size = 2;
int sizeAdj = (size * 2) + 2;
int leftMost = sizeAdj;
for(i = 0; i <= size; i++){
for(j = 0; j < 1; j++){
cout<<setw(leftMost + 1)<<"|";
cout<<"\\";
cout<<"/";
cout<<"|";
cout<<endl;
for(j = 0; j < 1; j++){
cout<<setw(leftMost + 1)<<"|";
cout<<"/";
cout<<"\\";
cout<<"|";
}
leftMost = leftMost - 1;
}
cout<<endl;
}
And this prints out the following.
|\/|
|/\|
|\/|
|/\|
|\/|
|/\|
Once more, thank you.
Upvotes: 2
Views: 95
Reputation: 16853
but am having a really hard time with embedding several loops within one another.
From the looks of it, you are having a hard time writing effective loops and just didn't notice until you tried nesting them. Take a look at your loops using j
as the loop control variable:
for(j = 0; j < 1; j++)
Technically, this is a looping statement. However, it sets j
to 0
, runs the loop once, then increments j
to 1
and exits the loop. It's hard to consider this a real loop when there is always just one iteration. You'd have less busywork for the computer if you skipped the for
statement and just set j = 0
.
Still, there is a problem with the way you have loops nested. Your looping structures (ignoring the other statements in the loop bodies) is the following.
for(i = 0; i <= size; i++){ for(j = 0; j < 1; j++){ for(j = 0; j < 1; j++){
Notice that the middle and innermost loops both use j
? That's a disaster waiting to happen. Don't have a nested loop mess with the loop control variable of a containing loop.
Even better, try to avoid nesting loops. Think about what you want to happen with each iteration of a loop, then delegate that functionality to a different function. For example, your outermost loop might look like:
for(i = 0; i <= size; i++)
printSection(i, size);
Then you could write a printSection
function to handle each section of the building. This would be the intent of your middle loop, right? (If not, adjust the details to match your intent. The point is to avoid jumbling a lot of steps into one chunk of code.) You could easily test this function by itself. Have your main function, for example, call printSection(1,2);
instead of using a loop, and make sure the output matches what's in your problem description. Repeat for printSection(2,2);
and as many other examples as you need to be confident that this function works as intended.
// Print section number `section` for a building with `size` sections.
void printSection(int section, int size)
{
for(int i = 0; i <= section; i++) {
// Handle the indent here, since it is the same throughout the section.
cout << setw(size - section) << ' ';
// Delegate the floor details to another function.
printFloor(i, section);
// End the line. Alternatively, this could be delegated to printFloor.
cout << '\n';
}
}
You might notice that I used i
in both loops. Didn't I say that's a problem? It would be if the loops were directly nested. However, they are in separate functions, so no problem.
Next, you would write the printFloor
function. I would
start simple; have printFloor(int floor, int section)
initially just write a pipe character ('|'
), followed by 2*section + 2
colons, followed by another pipe character. Once you get that working, you can worry about the X through the building. Start small, divide-and-conquer, and make sure each piece works before joining things together.
Upvotes: 1
Reputation: 64682
I did this in C for fun.... for whatever its worth:
#include <stdio.h>
#include <string.h>
void print_section(int n, int z)
{
char dots[2*n+1];
memset(dots,':',2*n+1);
dots[2*n+1]=0;
for(int r=0;r<n+1;++r)
{
printf("%*.s|%.*s\\%.*s/%.*s|\n",z-n,"",r,dots,2*(n-r),dots,r,dots);
}
for(int r=n;r>=0;--r)
{
printf("%*.s|%.*s/%.*s\\%.*s|\n",z-n,"",r,dots,2*(n-r),dots,r,dots);
}
memset(dots,'-',2*(n+1));
printf("%*.s/%.*s\\\n",z-n,"",2*(n+1),dots);
}
int main(void) {
int sections;
printf("Please enter number of sections: \n");
scanf("%d", §ions);
for(int s=0; s<sections; ++s)
{
print_section(s, sections);
}
return 0;
}
for 5 sections
Success #stdin #stdout 0s 4276KB
Please enter number of sections: 5
|\/|
|/\|
/--\
|\::/|
|:\/:|
|:/\:|
|/::\|
/----\
|\::::/|
|:\::/:|
|::\/::|
|::/\::|
|:/::\:|
|/::::\|
/------\
|\::::::/|
|:\::::/:|
|::\::/::|
|:::\/:::|
|:::/\:::|
|::/::\::|
|:/::::\:|
|/::::::\|
/--------\
|\::::::::/|
|:\::::::/:|
|::\::::/::|
|:::\::/:::|
|::::\/::::|
|::::/\::::|
|:::/::\:::|
|::/::::\::|
|:/::::::\:|
|/::::::::\|
/----------\
Upvotes: 0
Reputation: 122458
To be honest, I dont see the pattern in your code.
Start simpler. First dont worry about the space at the front:
|\/|
|/\| //section 0 ((section * 2) + 2)
/--\ 0 + 2 = 2
|\::/|
|:\/:| //section 1 ((section * 2) + 2)
|:/\:| 2 + 2 = 4
|/::\|
/----\
|\::::/|
|:\::/:|
|::\/::| //section 2 ((section * 2) + 2)
|::/\::| 4 + 2 = 6
|:/::\:|
|/::::\|
/------\
if you have that you just need to add x
spaces in front.
Next, the symmetry is more obvious when we add a "fake" line:
\----/
|\::/|
|:\/:| //section 1 ((section * 2) + 2)
|:/\:| 2 + 2 = 4
|/::\|
/----\
Now width and height are the same and we can use
int width(int x) { return (x*2)+2; }
Write a function that returns the right character for a given position
char get_simple_pattern(int x,int row,int col) {
if (row == col) return '\\';
// ...
return ':';
}
Use two loops to print it
void print_simple_pattern(int x) {
for (int row=0; row < width(x); ++row) {
for (int col=0; col < width(x); ++col) {
std::cout << get_simple_pattern(x,row,col);
}
std::cout << "\n";
}
}
Once you have this correct you have to
x
spaces in front of each row: std::cout << std::string(x,' ');
x
Upvotes: 1