Natasha The Robot

Currently learning... Swift!

You can follow me on Twitter here.

Subscribe via RSS here.

Subscribe to my Swift newsletter

Stanford CS106A Assignment 2 Target Solution

Posted on

This Target problem is pretty fun, and is great for understanding the basics of Java that were covered in the last few lectures. Here is the problem:

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

The Target consists of three circles of different radiuses. The hardest part of this problem is figuring out how to get the circles to display in the center of the window. Keep in mind that when you’re drawing a circle, the circle is drawn inside a square, where the starting coordinates are in the top left corner, so you have to move over your starting point by half a radius to center the circle.

<pre>/*
 * File: Target.java
 * Name: 
 * Section Leader: 
 * -----------------
 * This file is the starter file for the Target problem.
 */

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

public class Target extends GraphicsProgram {	
	public void run() {
		putOuterCircle();
		putMiddleCircle();
		putInnerCircle();
	}
	private void putOuterCircle() {
		int radius = 72;
		int x = getWidth()/2 - radius/2;
		int y = getHeight()/2 - radius/2;
		GOval OuterCircle = new GOval (x, y, radius, radius);
		OuterCircle.setColor(Color.RED);
		OuterCircle.setFilled(true);
		OuterCircle.setFillColor(Color.RED);
		add(OuterCircle);
	}
	private void putMiddleCircle() {
		double radius = 72*64/100;
		double x = getWidth()/2 - radius/2;
		double y = getHeight()/2 - radius/2;
		GOval MiddleCircle = new GOval (x, y, radius, radius);
		MiddleCircle.setColor(Color.WHITE);
		MiddleCircle.setFilled(true);
		MiddleCircle.setFillColor(Color.WHITE);
		add(MiddleCircle);
	}
	private void putInnerCircle() {
		double radius = 72*3/10;
		double x = getWidth()/2 - radius/2;
		double y = getHeight()/2 - radius/2;
		GOval InnerCircle = new GOval (x, y, radius, radius);
		InnerCircle.setColor(Color.RED);
		InnerCircle.setFilled(true);
		InnerCircle.setFillColor(Color.RED);
		add(InnerCircle);
	}
}</pre>

Subscribe to my Swift newsletter

  • http://twitter.com/MaxFusion Bigbird (@MaxFusion)

    Hi, I have a question. The circle has a radius of 10, why do you divide it by 2? I thought you suppose to take the radius and time by 2 to get the diameter. This is what I did, I take the width minus the diameter and divide by 2 but this isn’t correct. I know your logic is correct, however, I don’t get why you divide the radius by two. The radius is only half of the circle. Thanks

    • http://learning2program.wordpress.com Natasha Murashev

      @MaxFusion,
      You are correct! I realized this mistake later on in the course, and didn’t go back to correct it. I forgot that you’re supposed to multiply the radius by 2 to get the full width, so I treated the radius as my diameter. Great job for noticing :)

  • Mark Javier

    I’m taking the class on itunes U. It’s good to know Stanford is giving this away for free. :) here’s my answer to this assignment.

    /*
     * File: Target.java
     * Name: 
     * Section Leader: 
     * -----------------
     * This file is the starter file for the Target problem.
     */
    
    import acm.graphics.*;
    import acm.program.*;
    import java.awt.*;
    
    public class Target extends GraphicsProgram {
    	
    	public void run() {
    		add(solidCircle(1,Color.RED)); //adds outer circle
    		add(solidCircle(0.65,Color.WHITE)); //adds middle circle
    		add(solidCircle(0.3,Color.RED)); // adds inner circle
    	}
    	
    	/**
    	 * This creates a circle with specified radius
    	 * @param r Radius of the circle in inches
    	 * @param color Color of the circle 
    	 * @return circle at the center of screen with 
    	 * 'r' as radius and 'color' as it's color
    	 */
    	private GOval solidCircle(double r,Color color) {
    		r*=72; //pixel density or dots per inch
    		GOval circle = new GOval(getWidth()/2-r,getHeight()/2-r, r*2, r*2);
    		circle.setColor(color);
    		circle.setFillColor(color);
    		circle.setFilled(true);
    		return circle;
    	}
    }
    
    • http://learning2program.wordpress.com Natasha Murashev

      Thanks for posting! Your solution is a lot better than mine is :)

    • http://www.thegympress.net Valentin

      thanks for sharing this… this is very cool, great to see.. I thought about doing it like this, but didn’t know how.. saw this, and BAM i can see how… great use of method

  • ss

    While discussion in CS is important, posting solutions to assignments on this blog is in clear violation of Stanford’s code of ethics. Public solutions to CS106A assignments facilitate academic dishonesty by providing students who are taking this course with unfair aid. Please remove these solutions so that no student obtains an unfair advantage.

    • http://natashamurashev.com Natasha Murashev

      For those students who want to cheat, they’ll find answers regardless of whether I keep this blog or not. In addition, my solutions are not necessarily “the correct” ones, so if students do decide to copy them, they probably won’t get the best grade either way.

      My goal with posting these solutions is to help out all the people who are taking this course online. I personally found it very useful to refer to other people’s code to come up with my own answers (since I didn’t have a TA to help me out).

      • http://www.thegympress.net Valentin

        I agree.. thank you for the blog. I am doing the course online and do not have much help, so having this blog as a reference is great.

  • Daniel Rediger

    I did something very simular to you.

    Except having setFillColor and setColor is redundant if they’re the same color.

    Because you want the oval to be a pure color with the same color for the outer edge so you can simply put setColor.

    I also made a private static fill int called “size” and then plugged that into my methods instead of “72” that way you could change the “size” and effect the entire image.

    Thanks for putting up your code it was a great verification that i was on the right track!

    • http://natashamurashev.com Natasha Murashev

      Love it when someone writes better code than I did!

  • robbie

    Hiya

    Here’s my solution;

    
        import acm.program.*;
        import acm.graphics.*;
        import java.awt.*;
    
        public class Target extends GraphicsProgram {
    
        private static final double CIRCLE1_RADIUS = 144;
        private static final double CIRCLE2_RADIUS = 93.6;
        private static final double CIRCLE3_RADIUS = 10;
    
        public void run() {
    
        GOval circle1 = new GOval (getWidth() / 2 – CIRCLE1_RADIUS, getHeight() / 2 – CIRCLE1_RADIUS, 2 * CIRCLE1_RADIUS, 2 * CIRCLE1_RADIUS);
        circle1.setFilled(true);
        circle1.setColor(Color.RED);
        add(circle1);
        GOval circle2 = new GOval (getWidth() / 2 – CIRCLE2_RADIUS, getHeight() / 2- CIRCLE2_RADIUS, 2 * CIRCLE2_RADIUS, 2 * CIRCLE2_RADIUS);
        circle2.setFilled(true);
        circle2.setColor(WHITE);
        add(circle2);
        GOval circle3 = new GOval (getWidth() / 2 – CIRCLE3_RADIUS, getHeight() / 2- CIRCLE3_RADIUS, 2 * CIRCLE3_RADIUS, 2 * CIRCLE3_RADIUS);
        circle3.setFilled(true);
        circle3.setColor(RED);
        add(circle3);
        }
        }
    

    I doubled the sizes cos it looked small in my screen.

    It had a putCircle(); etc at the beginning, but I removed it, even if it is correct top down decomposition. I guess I was looking to do something like Mark Javier has done but he actually knows what he’s doing.

    I have a couple of questions;

    1. I tried to do the pyramid problem way too early, and fled to your blog in despair, which made me realize I hadn’t progressed far enough through the book and lectures to tackle it. Now that I’ve progressed further through the course, I’d like to try a similar problem, but not that one because I’ve looked at too many other solutions to it. Are there any problems which have a similar difficulty for that level that you may have come across elsewhere? The class guide on github you link to, btw, is a big help in how to pace the course!

    2. When I was looking at other people’s solutions to the pyramid problem, there was a lot of funky stuff going on with method calling- all sorts of weird and wonderful stuff in the brackets after the name. That seems way ahead of where I’m at- chapter 4 in the book and lecture 7 on video. I’m assuming that stuff is coming up, I haven’t missed something thats implied by whats been taught so far? Your solution to the pyramid thing is not only elegant but actually understandable at the level I’m at…

    Thanks alot! This is a great resource for people studying on their own, well done!

    Robbie

  • ignat980

    I don’t know what I am doing wrong… The first one that I did was the pyramid and I have it working. I recently switched computers, and my new one is 64-bit windows 7. Every time I quick-run a program, my eclipse crashes. Every time I run my program, (unfinished) I get the error

    “EventDispatchThread.run() line: not available [local variables unavailable]
    Source not found”.

    I’ll post my unfinished program anyway.

    /*
     * File: Target.java
     * Name: 
     * Section Leader: 
     * -----------------
     * This file is the starter file for the Target problem.
     */
    
    import acm.graphics.*;
    import acm.program.*;
    import java.awt.*;
    
    public class Target extends GraphicsProgram {
    	
    	/* The size of an inch in pixels. */
    	private static final double INCH = 72;
    	
    	/* The size,in pixels, of the outside Oval. */
    	private static final double SIZEOUTSIDEOVAL = INCH; 
    	
    	/* The size,in pixels, of the middle Oval. */
    	private static final double SIZEMIDDLEOVAL = INCH / (65 / 100);
    	
    	/* Runs the prigram. */
    	public void run() {
    		drawOutside();
    		drawMiddle();
    	}
    	
    	/* Draws the middle oval on the canvas. */
    	private void drawMiddle() {
    		GOval middle = new GOval (MiddleWidthMiddle(),MiddleHeightMiddle(),SIZEMIDDLEOVAL,SIZEMIDDLEOVAL);
    		middle.setColor(Color.WHITE);
    		middle.setFilled(true);
    		middle.setFillColor(Color.WHITE);
    		add(middle);
    	}
    	
    	/* The center of the canvas, width-wise, Middle oval-wise. */
    	private double MiddleWidthMiddle() {
    		double x = getWidth()/2;
    		x -= SIZEMIDDLEOVAL/2;
    		return x;
    	}
    	
    	/* The center of the canvas, height-wise, middle oval-wise. */
    	private double MiddleHeightMiddle() {
    		double x = getHeight()/2;
    		x -= SIZEMIDDLEOVAL/2;
    		return x;
    	}
    	
    	/* Draws the outside oval on the canvas. */
    	private void drawOutside() {
    		GOval outside = new GOval(MiddleWidthOutside(),MiddleHeightOutside(),SIZEOUTSIDEOVAL,SIZEOUTSIDEOVAL);
    		outside.setColor(Color.RED);
    		outside.setFilled(true);
    		outside.setFillColor(Color.RED);
    		add(outside);
    	}
    	
    	/* The center of the canvas, width-wise, outside oval-wise. */
    	private double MiddleWidthOutside() {
    		double x = getWidth()/2;
    		x -= SIZEOUTSIDEOVAL/2;
    		return x;
    	}
    	
    	/* The center of the canvas, height-wise, outside oval-wise. */
    	private double MiddleHeightOutside() {
    		double x = getHeight()/2;
    		x -= SIZEOUTSIDEOVAL/2;
    		return x;
    	}
    }
    
  • Nathan

    yeah Eclipse is annoying on x64 machines. Some of those crashes can randomly corrupt your libraries (had my acm library corrupted a few times). I’ve taken to keeping a working copy of my libraries in my project space both in my project space and workspace directories for backup. From what I’ve read its a known issue. Many times you can have running instances of the application window behind eclipse and when you change code while its running it can trigger those crashes too on x64.

    • Nathan

      What I’d do is create a simple hello world project and tinker with your IDE until it doesn’t crash as much that way you know its not your code thats causing the crash and you can work around it a little.

  • Nathan

    Here’s my solution if anyones interested:

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

    public class DefaultGraphics extends GraphicsProgram{
    public static int RADIUS = 72;
    public void run(){
    dTarget();
    }

    public void dTarget()
    {
    dCircle(1, Color.red );
    dCircle(0.65, Color.white);
    dCircle(0.3, Color.red);
    }

    public void dCircle(double scale, Color argC)
    {
    int rBox = (int)((double)RADIUS*2*scale);
    int centerX = (getWidth()/2)-(int)((double)RADIUS*scale);
    int centerY = (getHeight()/2)-(int)((double)RADIUS*scale);
    GOval label = new GOval(centerX, centerY, rBox, rBox);
    label.setFillColor(argC);
    label.setFilled(true);
    add(label);
    }
    }

  • filmibuff

    Here’s my code. By setting a max_circles constant, this program can be possibly extended to draw more circles with just a minor change on adding a calculation to determine each circle’s radius which could be radius-=(radius/MAX_CIRCLES).

    import acm.graphics.*;
    import acm.program.*;
    import java.awt.*;
    public class Target2 extends GraphicsProgram {
    private static final int MAX_CIRCLES=3;
    private static final int PIXELS_PER_INCH=72;
    public void run() {
    /* Set Initial Radius */
    double radius=1;
    drawTarget(radius);

    }
    private void drawTarget(double radius){
    radius*=PIXELS_PER_INCH;

    for(int i=0; i<MAX_CIRCLES; i++){
    double x=(getWidth()/2)-radius;
    double y=(getHeight()/2)-radius;
    GOval circle=new GOval(x, y, 2*radius, 2*radius);
    circle.setFilled(true);
    if (i%2==0){
    circle.setColor(Color.RED);
    }
    else{
    circle.setColor(Color.WHITE);
    }
    add(circle);
    radius-=0.35*PIXELS_PER_INCH;
    }
    }

  • Guest

    Here’s my code. By setting a max_circles constant, this program can be possibly extended to draw more circles with just a minor change on adding a calculation to determine each circle’s radius which could be radius-=(radius/MAX_CIRCLES).

  • Guest

    Here’s my code. By setting a max_circles constant, this program can be possibly extended to draw more circles with just a minor change on adding a calculation to determine each circle’s radius which could be radius-=(radius/MAX_CIRCLES).

    import acm.graphics.*;

    import acm.program.*;

    import java.awt.*;

    public class Target2 extends GraphicsProgram {

    private static final int MAX_CIRCLES=3;

    private static final int PIXELS_PER_INCH=72;

    public void run() {

    /* Set Initial Radius */

    double radius=1;

    drawTarget(radius);

    }

    private void drawTarget(double radius){

    radius*=PIXELS_PER_INCH;

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

    double x=(getWidth()/2)-radius;

    double y=(getHeight()/2)-radius;

    GOval circle=new GOval(x, y, 2*radius, 2*radius);

    circle.setFilled(true);

    if (i%2==0){

    circle.setColor(Color.RED);

    }

    else{

    circle.setColor(Color.WHITE);

    }

    add(circle);

    radius-=0.35*PIXELS_PER_INCH;

    }

    }

  • http://twitter.com/madclassix madclassix

    I appreciate this site as a resource for checking answers so I figured i’d post mine as well as I think it’s different (better?) than many already posted.


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

    public class Target extends GraphicsProgram {

    // Sets length of radius to one inch (72 pixels)
    private static final int INITIAL_RADIUS = 72;

    // Specifies number of circles in target. For target to have red bullseye must be odd number.
    private static final int CIRCLES = 3;

    public void run() {

    // For loop runs 3 times. 'i' begins at 3 because I want to use i to calculate the diameter of the circles,
    // beginning with the largest. So at i = 3 the circle is full size, at i = 2 the circle is 2/3 of the full size
    // and at i = 1 the circle is 1/3 of the full size.

    for (int i = CIRCLES; i > 0; i--) {

    // 'radius' variable decreases by a third for each iteration of for-loop. Drawing circles from biggest to

    // smallest allows layering to take place.

    double radius = ( (double) i / CIRCLES) * INITIAL_RADIUS;

    // 'diameter' variable used for defining size of circle

    double diameter = radius * 2;

    // The x and y values ensure that the circle is centered in the window. 'radius' variable is used so that

    // circle stays centered despite changing size.

    double x = (getWidth() / 2) - radius;

    double y = (getHeight() / 2) - radius;

    // Create circle.

    GOval circle = new GOval(x, y, diameter, diameter);

    // 'setFilled' is always true.

    circle.setFilled(true);

    // If 'i' is an odd number the circle will be painted red, if it is an even number it will be painted white.

    // This does not work when an even number of circles are specified in the CIRCLES constant.

    if (i % 2 != 0) {

    circle.setColor(Color.RED);

    } else {

    circle.setColor(Color.WHITE);

    }

    add(circle);

    }

    }

    }

    // Replace lines 48 to 53 with the code below and targets with an even number for CIRCLES will invert colors, giving a white

    // bullseye, but making the outer circle colored and therefore visible. An odd number of circles will continue to appear as

    //expected.

    //if (CIRCLES % 2 != 0) {

    // if (i % 2 != 0) {

    // circle.setColor(Color.RED);

    // } else {

    // circle.setColor(Color.WHITE);

    // }

    //} else {

    // if (i % 2 != 0) {

    // circle.setColor(Color.WHITE);

    // } else {

    // circle.setColor(Color.RED);

    // }

    //

  • Guest
  • Sancho Sanchez

    here is mine :


    import acm.graphics.*;
    import acm.program.*;
    import java.awt.*;
    public class Target extends GraphicsProgram {

    //General variables
    private static final int MAX_CIRCLES=3;

    public void run() {
    double r = 72;

    for(int i=0; i<MAX_CIRCLES; i++){/* loop until 3 circles are drawn*/

    double x=(getWidth()/2-r);
    double y=(getHeight()/2-r);
    GOval circle=new GOval(x, y, 2*r, 2*r);
    circle.setFilled(true);

    if (i%2 == 0){
    circle.setColor(Color.RED);
    r = 46.8;
    } else {
    circle.setColor(Color.WHITE);
    r = 21.6;
    }

    add(circle);
    }
    }
    }