Stanford CS106A Assignment 2 Pyramid Solution

The pyramid problem in Assignment 2 is actually pretty difficult for beginners, so I recommend you do the Target problem first. If you were able to figure out the Target problem, move on to this one. Be warned though, this one takes some time to figure out. Here is the problem:

Here is my solution, which you can also find on github:


The key here is to create 2 loops, one for the height part of the pyramid, and one for the width. The height-based loop needs to start with one, while the width-based loop can start with 0. I found it helpful by first writing out the code manually for the first 3 rows that needed to be built and then figuring out the small differences, after which I started over and created the two loops.

<pre>/*
 * File: Pyramid.java
 * Name: 
 * Section Leader: 
 * ------------------
 * This file is the starter file for the Pyramid problem.
 * It includes definitions of the constants that match the
 * sample run in the assignment, but you should make sure
 * that changing these values causes the generated display
 * to change accordingly.
 */

import acm.graphics.*;
import acm.program.*;
import java.awt.*;

public class Pyramid extends GraphicsProgram {

/** Width of each brick in pixels */
	private static final int BRICK_WIDTH = 30;

/** Width of each brick in pixels */
	private static final int BRICK_HEIGHT = 12;

/** Number of bricks in the base of the pyramid */
	private static final int BRICKS_IN_BASE = 14;

	public void run() {
		putAllBricks();
	}
	private void putAllBricks()
	{
		//row - 0-based index of the row 
		//row+1 - The 1-based index of the row
		//brickNum - 0-based index of the brick

		//Loop through the 0-based index of the rows
		for( int row = 0; row < BRICKS_IN_BASE; row++ )
		{
			int bricksInRow = BRICKS_IN_BASE - row;

			//
			// Total number of bricks = row
			//
			for( int brickNum = 0; brickNum < bricksInRow; brickNum++ )
			{
				//1. Calculate the center
				//2. Calculate the starting point based on the center
				//3. Add the number of bricks * brick width to find this brick's location
				int x = ( getWidth()/2 ) - (BRICK_WIDTH * bricksInRow) / 2 + brickNum * BRICK_WIDTH;

				// 
				// Calculate the vertical location of the brick based on the row
				//
				int y = getHeight() - BRICK_HEIGHT * (row+1);

				//
				// Draw the brick
				//
				GRect brick = new GRect( x , y , BRICK_WIDTH , BRICK_HEIGHT );
				add(brick);
			}
		}
	}
}</pre>

Enjoy the article? Join over 17,500+ Swift developers and enthusiasts who get my weekly updates.

  • thegympress

    can you explain a little better how the bricks are draw in from the center. for example for brickN in the base, the x and y are still the top left corner right? but if you have found the center of the base for the pyramid how are bricks draw on the left side ? (does that make sense?

    Woudl really appreciate it.

    • I did this a while ago, and am not sure how to answer your question. Try copying and pasting the code and see how the bricks are drawn. Then try to replicate on your own πŸ™‚

  • thegympress

    Thanks, good idea.

  • This is my solution to the problem…can anyone care to comment, suggest improvements..

  • Holly

    Hmmm, I came up with a much different solution, that I think is simplier then yours, trying to figure out how github works so I can post a link to see what you think…will post once I figure it out! πŸ™‚

    • Great! I love when people come up with better solutions than mine πŸ™‚ Feel free to also just copy and paste the code in the comments here!

      • Holly

        Thanks Natasha, see below. Interested to hear your thoughts (or anyone else’s), as to whether you think it’s a simpler solution or not (maybe it just a different solution!). πŸ™‚

        public class Pyramid extends GraphicsProgram {
        
        /** Width of each brick in pixels */
        	private static final int BRICK_WIDTH = 30;
        
        /** Width of each brick in pixels */
        	private static final int BRICK_HEIGHT = 12;
        
        /** Number of bricks in the base of the pyramid */
        	private static final int BRICKS_IN_BASE = 14;
        	
        	public void run() {
        		pyramidBricks();
        		
        	}
        	private void pyramidBricks(){
        		int numOfBricks = BRICKS_IN_BASE;
        		int numOfRows = BRICKS_IN_BASE;
        		double y = getHeight() - BRICK_HEIGHT;	
        		while (numOfRows > 0) {
        			double x = (getWidth()/2) - ((numOfBricks*BRICK_WIDTH)/2);		
        				for (int i = numOfBricks; i > 0; i--) {
        					GRect brick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
        					add(brick);
        					x +=BRICK_WIDTH;
        		}
        				numOfBricks--;
        				numOfRows--;
        				y -= BRICK_HEIGHT;
        		
        			
        		}
        		
        	}
        }
        
      • Holly

        > should be the ‘greater then’ symbol, not sure why it doesn’t display correctly here…

      • Holly

        Ack, ok, that didn’t work! Now I’m seeing the correct symbol, I’ll try once more ‘>’ should be the ‘greater then’ (>) symbol.

      • Holly

        Ack, still didn’t work, I’ll try this, then I’ll stop (hoping this displays with the correct symbol rather then the html code for the symbol):

        while (numOfRows > 0)
        for (int i = numOfBricks; i > 0; i–)

      • Holly, this looks really similar to my code πŸ™‚ You just used a while loop instead of a for loop for one of the loops. I think mine looks a lot more complicated than it is because I put so many comments in it.

  • Sung Wook Choi

    Can you help me out with this???
    I have tried to solve pyramid assignment which you completed.
    But I can’t figure out what is wrong with my codes…
    So could you look over and give me some advice??

    
    import acm.graphics.*;
    import acm.program.*;
    
    public class Pyramid extends GraphicsProgram {
    	
    	private static final int Brick_Width = 30;
    	private static final int Brick_Height = 12;
    	private static final int Bricks_In_Base = 14;
    	public void run() {
    		// You fill this in
    		int ctrX = getWidth()/2;
    		int row = Bricks_In_Base;
    		int bricks = Bricks_In_Base;
    		int startY = getHeight()-Brick_Height; //first position of point Y
    		int startX = ctrX-Brick_Width*(Bricks_In_Base/2);//first position of point X
    		for(int j=0;j<row;j++){              /*change row*/
    			int Y=startY+j*(Brick_Height);
    			int X1=startX+j*(Brick_Width/2);
    			for(int i=0;i<bricks;i++){       /*change bricks number*/
    				int X2=X1+i*(Brick_Width);
    				GRect Pyramid=new GRect (X2, Y,Brick_Width,Brick_Height);
    				add(Pyramid);
    			}
    			bricks--;   //change bricks number
    		}
    	}
    }
    
    • Sung Wook Choi

      oh I found it ~~!!!! I’m sorry ^^;;

  • Hi Natasha,
    I am a complete noob to programming/java and struggle to learn it via Stanford’s SEE course. I am extremely grateful for your site providing solutions to the assignments. This really helps me to learn and see what I did wrong/right.
    Here is my solution to the problem. I feel your code is much better than mine, because I declared my variables called x_coor and y_coor outside of the loop, while you declare your x_coor and y_coor (for each rectangle) in the heart of your loop. Essentially I set up the first rectangle’s initial value (the x/y coordinate of the very first rectangle of the bottom row) outside of the loop, then start drawing one by one from left to right, bottom to up. i just feel my code better reflects my thought process, and struggle to write more succinct code like yours that seems counter intuitive to my way of thinking.
    Do you know what I mean? Shall we always strive to write the most succinct code instead of code that reflect our brain?

    public void run() {
    		int canvas_h = getHeight();
    		int canvas_w = getWidth();
    		int y_coor = canvas_h - BRICK_HEIGHT;
    		int x_coor = (canvas_w / 2) - ((BRICKS_IN_BASE*BRICK_WIDTH) / 2);
    		int brick_count = BRICKS_IN_BASE;
    				
    		while (brick_count > 0)
    		{ 
    		
    			for (int i = 0; i < brick_count; i++)
    			{
    				add(new GRect(x_coor, y_coor, BRICK_WIDTH, BRICK_HEIGHT));
    				x_coor = x_coor + BRICK_WIDTH;
    			}
    
    			brick_count = brick_count - 1;
    			x_coor = (canvas_w / 2) - ((brick_count*BRICK_WIDTH) / 2);
    			y_coor = y_coor - BRICK_HEIGHT;
    		}
    
    • Hi Ladeer,

      In this case, your code is probably better than mine because I write out your x_coor and y_coor variables 2 times, while you write it out once and just use the simplified x_coor and y_coor version, saving yourself the extra work or rewriting. The only thing I would say is to make sure you have clear comments in your code to clarify what x_coor and y_coor means.

      The best programmers are lazy – this means they figure out clever ways to write the least code.

      Keep up the great work!
      Natasha

  • Hi Natasha,

    Your site looks like an excellent resource. I noted your link to the Ruby On Rails course with interest.

    There are lots of germinal coders out there, so I am sure you could provide a great hub, if you felt like starting a Google group or something….oh, here’s my solution…

    
    /*
     * File: Pyramid.java
     * ------------------
     * This program is a stub for the Pyramid problem, which draws
     * a brick pyramid.
     */
    
    import acm.program.*;
    import acm.graphics.*;
    
    /* This class draws a pyramid built of uniformly sized bricks  
     */
    
    public class Pyramid extends GraphicsProgram {
    
    	/*The width of each brick in pixels */
    	 private static final int BRICK_WIDTH = 30;
    
    	/*The height of each brick in pixels*/
    	private static final int BRICK_HEIGHT = 12;
    
    	/* The number of bricks in the base */
    	private static final int BRICKS_IN_BASE = 14;
    
    /* runs program*/
    public void run() {
    	
    		for (int h = 0; h < BRICKS_IN_BASE; h++)
    		{
    				for (int i = 0; i < BRICKS_IN_BASE + (-h); i++)
    				{
    					int k = i * BRICK_WIDTH;
    					int m = h * BRICK_HEIGHT;
    		int x = ((getWidth() - ((BRICKS_IN_BASE + (-h)) * BRICK_WIDTH)) / 2) + k;
    		int y = getHeight() - ((BRICK_HEIGHT + 1) + m);
    		GRect brick = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT);
    		add(brick);
    			}
    		}				
    	}	
    }
    
    • Thanks! Now that I’m able to build stuff, I’ll think of something to help everyone.

  • Good stuff…what do you have in mind?

    in the code examples, less than, (the v on its side) , ‘ < ' , is coming out as ' < '

  • I mean < is coming out as <

  • marcus

    lol…ok, I am losing this battle with html, or whatever it is

    < is coming out as & l t ;

    • Haha, no worries. That’s just how it formats the less than and greater than signs.

      Maybe I’ll create a Stackoverflow for beginners + a list of resources or something? Will think about this.

  • /*
     * File: Pyramid.java
     * Name: 
     * Section Leader: 
     * ------------------
     * This file is the starter file for the Pyramid problem.
     * It includes definitions of the constants that match the
     * sample run in the assignment, but you should make sure
     * that changing these values causes the generated display
     * to change accordingly.
     * 
     * 
     * This one was done on 14.7.2012 by Maciek Grischke - twitter.com/_zyx
     */
    
    import acm.graphics.*;
    import acm.program.*;
    import java.awt.*;
    
    public class Pyramid extends GraphicsProgram {
    	
    /** Width of each brick in pixels */
    	private static final int WIDTH = 28;
    
    /** Width of each brick in pixels */
    	private static final int HEIGHT = 11;
    
    /** Number of bricks in the base of the pyramid */
    	private static final int BRICKS_IN_BASE = 14;
    	
    /**useless */
    	private static final int STEP = 0;
    	
    /** pause time in ms - so you can see the animation */
    	private static final int PAUSE_TIME = 250;
    	
    	public void run() {
    		int baseCenter = getWidth() - ((BRICKS_IN_BASE / 2) * WIDTH); /* baseCenter is where the first brick on the left appears */
    		int bottom = getHeight() - HEIGHT; /* bottom is to get the size of the window vertically, minus the height of the brick */
    		int brix = 14; /* a number for the loop of the main FOR - also required for 'step' */
    		for (int bricks = 14; bricks &gt;= 1; bricks--) { 
    			for (int step = 1; step &lt;= brix; step++) {
    				add(new GRect(baseCenter,bottom,WIDTH,HEIGHT)); /* this places the brick on the left at the bottom */
    				baseCenter += WIDTH; /* this moves the baseCenter one WIDTH horizontically, to the right, 28 pixels in this case */
    				pause(PAUSE_TIME); /* again, this is so you can see the animation πŸ˜‰ */
    			}
    			brix -= 1; /* minus one brick/loop/ */
    			baseCenter -= ((brix * WIDTH) + (WIDTH / 2)); /* moves baseCenter-the point where the new brick starts on each row-half the WIDTH - 14 pixels */
    			bottom -= HEIGHT; /* moves one row up */
    		}
    	}
    }
    
  • Sorry, coding is great πŸ˜€

    Here is my code here as well http://pastie.org/private/ppm9bchd7oujvni9fczmq

  • A. Sengor

    What do you think of this solution? I wanted to code it as simple as possible.

    	public void run() {
    		for (int j=BRICKS_IN_BASE;j&gt;=1;j--) {
    			for (int i=0;i&lt;j;i++) {
    				double cx = getWidth()/2 - ((double)j/2)*BRICK_WIDTH;
    				double cy = getHeight()-BRICK_HEIGHT;
    				double dx = BRICK_WIDTH;
    				double dy = BRICK_HEIGHT;
    				cx = cx + i*dx;
    				cy = cy - Math.abs(j-BRICKS_IN_BASE)*dy;
    				GRect brick = new GRect(cx,cy,BRICK_WIDTH,BRICK_HEIGHT);
    				add (brick);
    				pause(30);
    			}	
    		}
    	}	
    	
    	private static final int BRICK_WIDTH = 30;
    	private static final int BRICK_HEIGHT = 12;
    	private static final int BRICKS_IN_BASE = 14;
    }
    
    

    After thinking for half an hour why it was building a whole brick's width to the right on every stage instead of half, I just figured that the cast (double) was missing in cx declaration line. Wasn't it supposed to be unnecessary if the value is not losing information? (Beginning of CS106A Lecture 7 by Mehran Salami) It seems that, if the operation (here, division) in which the integer is an operand loses information, you should also cast it.

    • A. Sengor

      Comparison operators in for loops don’t show in the upper code. Just replace “&gt” with greater sign and “&lt” with less than sign.

  • Casius

    Man oh man, this stuff makes my head explode a bit. I have not finished the assignment on my own and I wouldn’t dare post my code out of shame. I am mostly writing this because I’m starting to feel that I just don’t have the brains for this.

    I am also following the free Stanford course and I think it’s great, I feel giddy when I think of the possibilities of learning to code but there’s only so much ‘head vs wall’ I can take before I feel completely demoralized. I used to be smart but that was so damn long ago I think my brain is just mush by now. I guess my main issue with my ‘progress’ so far is that even though I push my way from assignment to assignment I just don’t understand the ‘method to the madness’. My code is so rudimentary, primitive and long by the time I’m done with an assignment. Then I read other people’s answers and it blows my mind to see the simpler way that everyone else comes up with.

    Guess my question is if maybe this is not for everyone, regardless of how much ‘hard work’ you invest into it.

    • Casius,

      You can do it!!!!!! Keep in mind that the Stanford course is a weeder course. The assignments are hard b/c they’re trying to weed out the weaker CS students (not sure how this benefits anyone).

      After you finish the breakout game assignment, they get a lot easier. I also almost gave up more than a few times, but that’s the easy answer. I got help online and from friends and was able to power through it. I’m glad I did, b/c I now absolutely LOVE coding.

      If you’re looking for a simpler course meant for online learning and with a community you can reach out to, check out Udacity.com and Coursera.com.

      Just the fact that you’ve gotten this far shows a lot about your tenacity. I started a group of 45 people when I first started to learn to code, and only about 5 people actually made it past the downloading Eclipse part of the course, and I think only 1 person even made it to Assignment2. So you’re doing an amazing job whether you think so or not.

      This stuff is hard, but it is also one of the most rewarding things you’ll do for yourself. If it was easy, everyone would do it. You’re not alone in feeling this way!!!!! The internet is only documenting people who made it, there are 100s if not 1000s of people who gave up for every person who made it this far.

      • Casius

        Hey Natasha,

        Thanks for your reply, I was really overwhelmed when I wrote my post but your reply gave me some much needed perspective.

        I knew learning how to code would be hard but at at times I think I just get myself lost in the shuffle. I just found the link to the book used in the class so I hope that helps me fill the gaps.

        Anyhow thanks again for your reply, it was exactly what I needed to hear.

        P.S. love the blog, specially the entry where you mention gaining employment as a software engineer. Very inspirational.

      • HI Casius,

        Nice to hear you’ll keep learning! Check out the CS106A resources I have listed on the sidebar, specifically the CS106A Wiki I made: https://github.com/NatashaTheRobot/Stanford-CS-106A/wiki/Stanford-Introduction-To-Computer-Science-Programming-Methodology-CS106A-Class-Guide.

        Also, here’s my full journey of learning: http://www.women2.com/how-i-learned-to-code/. As you can see, I’ve definitely quit a few times, but having a community has really helped me keep going!

  • Nathan

    Hi Natasha, ran across your github page before I ran across this site. I’m working my way through the stanford course as well.
    This is what my solution looks like:
    public static double BRICK_WIDTH=30; //default 30
    public static double BRICK_HEIGHT=12; //default 12
    public static double BRICKS_IN_BASE=14; //default 14

    public void run(){
    int startLocX = (getWidth()/2) – (((int)BRICKS_IN_BASE/2) * (int)BRICK_WIDTH);
    int startLocY = (getHeight()) -(int)BRICK_HEIGHT;

    if (BRICKS_IN_BASE * BRICK_WIDTH < getWidth()) // Will Bricks Fit Window Width?
    if (BRICKS_IN_BASE * BRICK_HEIGHT < getHeight()) // Will Bricks Fit Window Height?
    layPyramid(startLocX, startLocY, (int)BRICKS_IN_BASE);
    else
    error("Bricks to High");
    else
    error("Bricks to Wide");
    }

    public void layBrick(int x, int y)
    {
    GRect label = new GRect((double)x, (double)y, BRICK_WIDTH, BRICK_HEIGHT);
    add(label);
    }
    public int layRow(int x, int y, int blocks)
    {
    for (int i=0; i 0);
    }
    public void error(String msg){
    GLabel label1 = new GLabel( msg, (getWidth()-130), (getHeight()/2-20));
    label1.setFont(“SansSerif-36”);
    add(label1);
    }

  • Mike

    Hi Natasha, I am still trying to write up the commands, though I was wondering how your code accounts for the odd and even number of bricks on the base. If it is an odd number of bricks than the starting point would be different than an even amount, because we are always trying to find the center of the canvas and adding half the amount of brick length of base and that is the starting. I am not entirely sure about this, but I would like to hear your input. Great resource for newbs such as me.

    • Mike, you’re right. I probably didn’t take that into account. My answers are more of suggestions, and I cannot guarantee that there is no better or more correct way of doing these assignments πŸ™‚ Looking forward to seeing your solution!

      • mike

        This makes sense in my head though I am having such a difficult time trying to figure out even and odd brick bases. First there will be a dead code error, which is very annoying. But I try and replace my brick base with even and odd numbers and its not doing what i want it to do. Every time I use an odd number of bricks its off center and even numbers it looks perfect. I have been working on this for many hours getting me annoyed at this point…

        • Mike

          This is going to look stupid, but I figured it out and I will be uploading the my solution it works fine. I am not entirely sure if it is right though it works on my computer fine. Please leave some things that I can fix in this code.

          /*

          * File: Pyramid.java

          * ——————

          * This program is a stub for the Pyramid problem, which draws

          * a brick pyramid.

          */

          import acm.graphics.*;

          import acm.program.*;

          public class Pyramid extends GraphicsProgram {

          //The bricks width that can be changed

          private static final int BRICK_WIDTH = 30;

          //THe bricks height that can be changed

          private static final int BRICK_HEIGHT = 12;

          //the amount of bricks in the base that can be changed

          private static final int BRICKS_IN_BASE = 13;

          //the amount of bricks on only one side

          private static final int BRICKS_ON_ONE_SIDE = BRICKS_IN_BASE/2;

          //before i start i think there is a difference between an odd and even amount of bricks so i will take care of

          //that too but it should not directly affect the method on how the rows are created

          public void run() {

          //this will be the start of and the next processes of how to create a pyramid

          make_A_Pyramid();

          }

          //the actuall nity grity of how to make a pyramid like the rows and and base

          public void make_A_Pyramid() {

          //this might actually correlate to the create base but i want to keep them separate because my mind cannot connect the two in code

          make_Base();

          lay_Row();

          }

          public void make_Base() {

          //this if loop is to check if the amount of bricks in the base is even or odd

          if (BRICKS_IN_BASE%2 == 0) {

          //this for loop is to determine the order when the amount of bricks in the base is even

          for (int brick_Count = 0 ; brick_Count < BRICKS_IN_BASE ; brick_Count++) {

          double x = getWidth()/2 – BRICKS_ON_ONE_SIDE*BRICK_WIDTH + BRICK_WIDTH*brick_Count;

          double y = getHeight() – BRICK_HEIGHT;

          GRect base_Square = new GRect ( x , y , BRICK_WIDTH , BRICK_HEIGHT);

          add(base_Square);

          }

          }else {

          //this for loop is to determine the order of the bricks when it is odd because odd bricks

          //will have a different start at the bottom compared to even amount

          for (int brick_Count = 0 ; brick_Count < BRICKS_IN_BASE ; brick_Count++) {

          //the way i decided to calculate the new width is by adding half a brick length to the x cord

          int x = (int) (getWidth()/2 – BRICKS_ON_ONE_SIDE*BRICK_WIDTH – BRICK_WIDTH*.5 + BRICK_WIDTH*brick_Count);

          int y = getHeight() – BRICK_HEIGHT;

          GRect base_Square = new GRect ( x , y , BRICK_WIDTH , BRICK_HEIGHT);

          add (base_Square);

          }

          }

          }

          //this too will have to be an if statement or the pyramid will be of by 1 brick

          public void lay_Row() {

          //this first half of the if statement is for the even number of bricks

          if (BRICKS_IN_BASE%2 == 0) {

          for (double row_Count = 1 ; row_Count < BRICKS_IN_BASE ; row_Count++){

          double amount_Of_Bricks_Per_Row = BRICKS_IN_BASE – row_Count;

          for (double brick = 0 ; brick < amount_Of_Bricks_Per_Row ; brick++){

          double x = getWidth()/2 – BRICKS_ON_ONE_SIDE*BRICK_WIDTH + .5*BRICK_WIDTH*row_Count + brick*BRICK_WIDTH;

          double y = getHeight() – BRICK_HEIGHT*(row_Count+1);

          GRect row_Layer = new GRect ( x , y , BRICK_WIDTH , BRICK_HEIGHT);

          add (row_Layer);

          }

          }

          }

          //this part of the if else statement is for the odd number of bricks by just adding an additional half a brick length

          else {

          for (double row_Count = 1 ; row_Count < BRICKS_IN_BASE ; row_Count++){

          double amount_Of_Bricks_Per_Row = BRICKS_IN_BASE – row_Count;

          for (double brick = 0 ; brick < amount_Of_Bricks_Per_Row ; brick++){

          double x = getWidth()/2 – BRICKS_ON_ONE_SIDE*BRICK_WIDTH – BRICK_WIDTH*.5 + .5*BRICK_WIDTH*row_Count + brick*BRICK_WIDTH;

          double y = getHeight() – BRICK_HEIGHT*(row_Count+1);

          GRect row_Layer = new GRect ( x , y , BRICK_WIDTH , BRICK_HEIGHT);

          add (row_Layer);

          }

          }

          }

          }

          }

          • Hey,

            I don’t have much time to look into the details for your solution right now, since I did this a while ago and would have to really dive back into Java to go through it, but here is what I can tell you:

            You read the instructions with a programmers mind, thinking of all the abstract use cases the problem requires. You ran into an obstacle and stuck it out. And you’re here asking for an even better solution. You’re going to make an incredible programmer.

          • Mike

            I just wanted to say this because it could save someone a lot of time ( where I wasted). If you are watching the videos. Finish lecture 11 before doing this. I didn’t and did not know about GCompound. It makes makes the code look so much neater. And for those who get a weird looking pyramid due to the rows being added on try .5, rather than 1/2. MATLAB it is okay for 1/2, but this bites you in the a**. I really do hope this helps someone. Good luck to everyone.

  • Rahul Sharma

    Hey Guys, I hav found out another solution of this problem. In this solution number of rows can even or odd. Let me know if it works.

    import acm.graphics.*;
    import acm.program.*;
    import java.awt.*;

    public class Pyramid extends GraphicsProgram {

    /** Width of each brick in pixels */
    private static final int BRICK_WIDTH = 40;

    /** Height of each brick in pixels */
    private static final int BRICK_HEIGHT = 15;

    /** Number of bricks in the base of the pyramid */
    private static final int BRICKS_IN_BASE = 13;

    public void run() {
    int x = (( getWidth() /2) – (BRICK_WIDTH * (BRICKS_IN_BASE /2) ));

    // x would be the starting co-ordinate of the row. to calculate that I had
    //used some math. First calculate the center of the row. Then subtract
    //the half length of the row.
    int y = getHeight() – BRICK_HEIGHT;

    // y starting co-ordinate of the y brick.

    int temp = x;

    // allocating the value of x to temp variable.

    int row = BRICKS_IN_BASE;

    // as BRICKS_IN_BASE is constant hence allocating its value for calculation in another variable.

    for (int j=0; j0; i–){

    // for horizontal movement from top to bottom

    GRect rect = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT);
    add (rect);

    x = x + BRICK_WIDTH;

    }
    y = y – BRICK_HEIGHT;
    x = temp + (BRICK_WIDTH/2);
    temp = x;
    row –;
    }
    }
    }

  • Justin Bosman

    Hi Natasha, spent 2 weeks doing this, took your advice and did the Target yesterday (a lot easier, and gave me the impetus to try the Pyramid again). Herewith my attempt…(not commented, still need to work on that part of my programming)

    /*

    * File: Pyramid.java

    * Name:

    * Section Leader:

    * ——————

    * This file is the starter file for the Pyramid problem.

    * It includes definitions of the constants that match the

    * sample run in the assignment, but you should make sure

    * that changing these values causes the generated display

    * to change accordingly.

    */

    import acm.graphics.*;

    import acm.program.*;

    public class Pyramid extends GraphicsProgram {

    /** Width of each brick in pixels */

    private static final int BRICK_WIDTH = 30;

    /** Height of each brick in pixels */

    private static final int BRICK_HEIGHT = 12;

    /** Number of bricks in the base of the pyramid */

    private static final int BRICKS_IN_BASE = 14;

    public void run() {

    int startX = (getWidth() – (BRICKS_IN_BASE * BRICK_WIDTH))/2;

    int startY = getHeight() – BRICK_HEIGHT;

    int brickCols = BRICKS_IN_BASE;

    for (int i = 0; i < BRICKS_IN_BASE; i++) {

    for (int j = 0; j < brickCols ; j++) {

    int x = startX + (j * BRICK_WIDTH);

    int y = startY – (i * BRICK_HEIGHT);

    GRect myBrick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);

    add(myBrick);

    }

    startX += BRICK_WIDTH / 2;

    brickCols -=1;

    }

    }

    }

  • parth patel

    Hey Natasha spent hours trying to debug this, can you tell me what the problem is. I can’t figure it out as every time I run it the screen is blank.

    import acm.graphics.*;

    import acm.program.*;

    import java.awt.*;

    public class Pyramid extends GraphicsProgram {

    /** Width of each brick in pixels */

    private static final int BRICK_WIDTH = 30;

    /** Width of each brick in pixels */

    private static final int BRICK_HEIGHT = 12;

    /** Number of bricks in the base of the pyramid */

    private static final int BRICKS_IN_BASE = 14;

    public void run() {

    builtPyramid();

    }

    private void builtPyramid() {

    for (int i=0; i<14; i++); {

    int level_counter = 1;

    int number_of_bricks = (BRICKS_IN_BASE) + (- 1 + 1) ;

    int x = (getWidth()/2) – (number_of_bricks/2);

    int y = (-1*getHeight())+ (number_of_bricks * BRICK_HEIGHT);

    GRect brick = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT);

    add(brick);

    }

    }

    }

  • Sancho Sanchez

    public void run() {

    int BricksPerLine = BRICKS_IN_BASE;//bricks per line
    int y = getHeight();
    int x = 0;

    while (BricksPerLine > 0) {
    //looping until Bricks per line reach 0

    x = (getWidth()-BricksPerLine*BRICK_WIDTH)/2;
    //Calculating the x position
    for (int i=0; i<BricksPerLine; i++) {
    //Building a line, loops until line is constructed
    GRect rect =new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
    add(rect);
    x = x + BRICK_WIDTH;
    }
    y = y – BRICK_HEIGHT;
    BricksPerLine–;

  • Cruel_Samaritan

    Here is simpler version IMO and closer to what Stanford people actually wanted to focus on (variables scope etc.):

    import acm.graphics.*;
    import java.awt.*;
    import acm.program.*;

    public class Pyramid extends GraphicsProgram {

    private static final int BRICK_WIDTH = 30;
    private static final int BRICK_HEIGHT = 12;
    private static final int BRICKS_IN_BASE = 14;

    public void run() {

    int w = getWidth() / 2;
    int x = 0;
    int j = BRICKS_IN_BASE;
    int y = getHeight();

    for (int k = 1; k <= 14; k++) {

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

    GRect brick = new GRect(w + x + (i * BRICK_WIDTH), y, BRICK_WIDTH, BRICK_HEIGHT);

    add (brick);
    }
    y = getHeight() – (BRICK_HEIGHT * k);
    x = k * (BRICK_WIDTH / 2);
    j–;

    }
    }
    }

    • Thanks for posting! There are definitely MUCH better ways of completing these challenges than the answers I have here.

      • Cruel_Samaritan

        Naaah πŸ˜‰ Thanks Natasha!

  • Jason Coltrin

    Marcus, I really like this solution and I know it was written a long time ago, but especially this line:

    for (int i = 0; i < BRICKS_IN_BASE + (-h); i++)

    Does this mean that 'repeat i for this number of times' is added' to 'h minus 1'? More specifically what is (-h)?

  • rafiks

    I got it. However it’s a little bit different from your solution. πŸ™‚

    • Awesome! There are tons of solutions, and my solution is definitely not the best one πŸ™‚

  • wordfreud

    Hi, I have newer version of the book where the pyramid should be centered to the middle of the screen (both X and Y), and the assignment shows up earlier in the book so I am not familiar with some stuff you are using. I also reversed the process and built the pyramid from the top to bottom.

    /*
    * File: Pyramid.Java
    * ——————
    * This program displays a graphical Pyramid that is centered on the screen.
    */

    import acm.program.*;
    import acm.graphics.*;

    public class Pyramid extends GraphicsProgram {

    private static final double BRICK_WIDTH = 20;
    private static final double BRICK_HEIGHT = 10;
    private static final int BRICKS_IN_BASE = 12;

    public void run () {

    //These variables locates the center of the canvas.
    double canvas_X_Center = (getWidth() / 2);
    double canvas_Y_Center = (getHeight() /2);

    /* This part sets the X and Y coordinates for the first top brick of the Pyramid.
    * The X coordinate of the first brick is centered to the middle of the screen.
    * The Y coordinate of the first brick is placed in the middle of the screen
    * minus half the the size of the pyramid. Doing so will center the rest of the
    * pyramid as it builds from the top to bottom.
    */
    double BrickIn_X_Center = (canvas_X_Center) – (BRICK_WIDTH / 2);
    double BrickIn_Y_Center = (canvas_Y_Center – BRICKS_IN_BASE * (BRICK_HEIGHT / 2));

    /* The variable “increaseLoopByOne” adds an extra loop to the for loop “j” every
    * time the for loop “i” is run. Doing so increases the number of bricks for each
    * row by one as it builds down.
    */

    int increaseLoopByOne = 0;

    for (int i = 0; i < BRICKS_IN_BASE; i++) {

    increaseLoopByOne++;

    /*This part centers the new rows of the Pyramid as new bricks are added
    *by moving the new row one half of a brick width to the left.
    */

    BrickIn_X_Center -= (BRICK_WIDTH / 2);

    for (int j = 0; j < increaseLoopByOne; j++){

    //These variables moves the position of the new brick one brick size from its previous location.
    double change_X_BrickPosition = j * BRICK_WIDTH;
    double change_Y_BrickPosition = i * BRICK_HEIGHT;

    /*This part adds the brick to the canvas. The part of the line that sets the location for
    * the X and Y coordinates contains two variables. The first variable that sets the location
    * of the first brick and the second variable is added to the location of the previous brick
    * to set the location of the new brick.
    */
    GRect brick = new GRect((BrickIn_X_Center + change_X_BrickPosition),(BrickIn_Y_Center + change_Y_BrickPosition),
    BRICK_WIDTH, BRICK_HEIGHT);
    add(brick);
    }

    }

    }

    }

  • Saul

    My version of top down style:

    import acm.graphics.*;

    import acm.program.*;

    import java.awt.*;

    public class Pyramid extends GraphicsProgram {

    /** Width of each brick in pixels */

    private static final int BRICK_WIDTH = 30;

    /** Width of each brick in pixels */

    private static final int BRICK_HEIGHT = 12;

    /** Number of bricks in the base of the pyramid */

    private static final int BRICKS_IN_BASE = 14;

    public void run() {

    /* Initializes y-coordiante */

    int n = 1;

    /* BRICKS_IN_BASE = Rows in pyramid; only do action for as many expected row */

    /* n is row count from the bottom, for y-coordinate */

    for (int m = BRICKS_IN_BASE; m > 0; m–) {

    addCenteredRowOfBricks(m, n);

    n++;

    }

    }

    private void addCenteredRowOfBricks(double m, double n) {

    /* Start at center, subtract half m bricks to start brick laying at x */

    double x = getWidth() / 2 – m / 2 * BRICK_WIDTH;

    /* Start at bottom for subtract n bricks for brick laying at y */

    double y = getHeight() – n * BRICK_HEIGHT;

    addBrick(x, y);

    /* Makes sure that the right count of bricks will be laid */

    for (double i = m; i > 1; i–) {

    /* Increments x coordinate for next brick by brick width */

    x += BRICK_WIDTH;

    addBrick(x, y);

    }

    }

    private void addBrick(double x, double y) {

    /* Adds brick with static width/height at x, y */

    GRect brick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);

    add(brick);

    }

    }