Need homework help (Java)

psx2514

Junior Member
Oct 17, 2012
16
0
0
Okay, instead of me trying to explain the assignment, I'm going to just post it here verbatim from my class website. Then I'll post the code I have so far.

Instructions/Design
In this assignment we will refactor our work from the last Skyline program to add randomness and additional classes.



Note: Start by making copies of your Building.java, SkylinePanel.java and Skyline.java files. Always keep a copy of working code before making changes.

Update the Skyline application you wrote in the last programming assignment to include randomness in the size and number of the buildings and windows.Name your program RandomSkyline.java.Because of the randomness we will use loops to control how the skyline looks.Once again, the Splat example from Chapter 4 is useful; as well as the paintComponent() methods from Chpater 5 Bullseye and Boxes examples. Your program needs to make the following changes to the 3 classes from the Skyline application:
1) Change Building constructor to set the number of windows to a random number. The draw method now needs a loop to draw this random number of windows.Remember to keep the windows within the dimensions of the building.

2) SkylinePanel the constructor will no longer instantiate the buildings.Its only job is to set preferred size and background color.
The building instantiation will now be done within the paintComponent() method as part of a loop. Here is the algorithm (this is VERY high-level, you still have plenty of designing to do):

1. generate random number
for each number from one to random number
2. generate random width
generate random height
3. instantiate building
4. draw building
5. generate random gap between next building
6. update distance from left side of frame


First generate a random number.Instantiate that number of buildings. Generate a random width and height. Use these random numbers as parameters to the building's constructor. Also, have the gap between buildings be a random number of pixels. This gap plus width of buildings creates the x coordinate (left edge of skyline) parameter. You can choose how you want to calculate y coordinate parameter (it is OK of buildings are drawn past the bottom of the frame).

3)Rename the class called Skyline to RandomSkyline NO other changes are needed.

4) Additionally, you’ll need to name your city. Use your own name(s).

Extra Credit:
Create a fourth class called Star. Fill the skyline with a random number of stars. Put this into a file named Star.java. Note: you will need to draw the stars in the paintComponent() method of SkylinePanel.

I don't understand this at all (except for #s 3 and 4). I don't get how to add windows, and I especially don't get the #2. Will someone please show me how to do this. Also, I can't use arrays yet since we're not up to those in class yet. Here's my code for the original Skyline that was mentioned.

Code:
 import java.awt.*;

public class Building
{
   private int x, y, width, height;
   private Color color;
   private String string;

   //-----------------------------------------------------------------
   //  Constructor: Sets up this building with the specified values.
   //-----------------------------------------------------------------
   public Building (Color shade, int upperX, int upperY, int nWidth, int nHeight) {
      
      color = shade;
      x = upperX;
      y = upperY;
      width = nWidth;
      height = nHeight;
      
   }
   
   //-----------------------------------------------------------------
   //  Draws this building in the specified graphics context.
   //-----------------------------------------------------------------
   public void draw (Graphics page)
   {
      page.setColor (color);
      page.fillRect (x, y, width, height);
   }
 
   //-----------------------------------------------------------------
   //  Color mutator.
   //-----------------------------------------------------------------
   public void setColor (Color shade)
   {
      color = shade;
   }

   //-----------------------------------------------------------------
   //  X mutator.
   //-----------------------------------------------------------------
   public void setX (int upperX)
   {
      x = upperX;
   }


   //-----------------------------------------------------------------
   //  Y mutator.
   //-----------------------------------------------------------------
   public void setY (int upperY)
   {
      y = upperY;
   }
   //-----------------------------------------------------------------
   //  width mutator.
   //-----------------------------------------------------------------
   public void setWidth (int nWidth)
   {
      width = nWidth;
   }

   //-----------------------------------------------------------------
   //  height mutator.
   //-----------------------------------------------------------------
   public void setheight (int nHeight)
   {
      height = nHeight;
   }
   
  
   //-----------------------------------------------------------------
   //  width accessor.
   //-----------------------------------------------------------------
   public int getWidth ()
   {
      return width;
   }
   //-----------------------------------------------------------------
   //  height accessor.
   //-----------------------------------------------------------------
   public int getHeight ()
   {
      return height;
   }
   //-----------------------------------------------------------------
   //  Color accessor.
   //-----------------------------------------------------------------
   public Color getColor ()
   {
      return color;
   }

   //-----------------------------------------------------------------
   //  X accessor.
   //-----------------------------------------------------------------
   public int getX ()
   {
      return x;
   }

   //-----------------------------------------------------------------
   //  Y accessor.
   //-----------------------------------------------------------------
   public int getY ()
   {
      return y;
   }
   
   

}

import javax.swing.*;
import java.awt.*;

public class SkylinePanel extends JPanel
{
   private Building building1, building2, building3, building4, building5;
   
   //-----------------------------------------------------------------
   //  Constructor: Creates five Building objects.
   //-----------------------------------------------------------------
   public SkylinePanel()
   {
      building1 = new Building (Color.black, 100, 380, 40, 100);
      building2 = new Building (Color.black, 170, 290, 80, 190);
      building3 = new Building (Color.black, 285, 80, 100, 400);
      building4 = new Building (Color.black, 450, 270, 80, 210);
      building5 = new Building (Color.black, 580, 360, 45, 120);
      
      setPreferredSize(new Dimension(640, 480));
      setBackground (Color.cyan);
     
   }
  
   //-----------------------------------------------------------------
   //  Draws this panel by requesting that each building draw itself.
   //-----------------------------------------------------------------
   public void paintComponent (Graphics page)
   {
      super.paintComponent(page);

      building1.draw(page);
      building2.draw(page);
      building3.draw(page);
      building4.draw(page);
      building5.draw(page);
      
   
   }
   
}
 
Last edited:

postmortemIA

Diamond Member
Jul 11, 2006
7,721
40
91
I hope nobody is gonna do your homework for you. Because such devs become PITA needing help for every damn little problem once you graduate and get the job.
 
Last edited:

veri745

Golden Member
Oct 11, 2007
1,163
4
81
What don't you understand about point #2?

The assignement is basically to randomize the number, width, height, and spacing of the buildings in the city skyline, rather than having pre-defined characteristics. Therefore, the drawn city should look a little different each time you run your program.

I hope you have learned how to generate random numbers and use 'for' loops?
 

psx2514

Junior Member
Oct 17, 2012
16
0
0
What don't you understand about point #2?

The assignement is basically to randomize the number, width, height, and spacing of the buildings in the city skyline, rather than having pre-defined characteristics. Therefore, the drawn city should look a little different each time you run your program.

I hope you have learned how to generate random numbers and use 'for' loops?

Yeah, I know how to generate random numbers and use 'for' loops. It's just that when I do that, I just get a bunch of random rectangles (the buildings "float" above the ground, and they overlap each other).

I also don't understand if I'm supposed to generate random numbers first, then use those numbers in my building parameters? Or if I'm supposed to get the the program to randomly generate the size of the buildings every time it runs? (Meaning my buildings would look different each subsequent time I run the program). If it's the latter, I don't get how to do that without the buildings overlapping each other, and being weird sizes (i.e the width being noticeably larger than the height).
 

veri745

Golden Member
Oct 11, 2007
1,163
4
81
So once you place your first randomly generated building, you need to use the parameters of that building to determine where the next building should be placed.

Also, if you have floating buildings, maybe don't use a random number for the 'Y' coordinate of the building location.

If you actually have code written, post that, and ask questions about it.
 

psx2514

Junior Member
Oct 17, 2012
16
0
0
So once you place your first randomly generated building, you need to use the parameters of that building to determine where the next building should be placed.

Also, if you have floating buildings, maybe don't use a random number for the 'Y' coordinate of the building location.

If you actually have code written, post that, and ask questions about it.

This is what I don't get. How do I know what those parameters are if they are randomly generated each time the program runs?

Also, I think I'm only supposed to use random numbers for the width and height not for the x and y coordinates. Maybe I wasn't clear on what I meant. Lets say that the random generator constructs a building that ends up having the parameters (0, 0, 300, 100). Since my panel is 640 x 480, that would mean that there would be a 340 pixel gap between the base of the building and the "ground." I'm wondering how I can prevent that from happening.
 

veri745

Golden Member
Oct 11, 2007
1,163
4
81
Just because the parameters are random doesn't mean you can't store them in a variable a refer to them later (probably in later loop iterations)

Does the 'y' coordinate represent the base of the building or the top of the building? If it's the top, then you will have to calculate the 'y' coordinate based on the height.
 

Cerb

Elite Member
Aug 26, 2000
17,484
33
86
If it's the latter, I don't get how to do that without the buildings overlapping each other, and being weird sizes (i.e the width being noticeably larger than the height).
The only difference between them should be determinism of placement. You can, for instance, reduce the variations. Like so:
Code:
width = int(random(0,1)*multiplier)+min_width
Where min_width+multiplier results in the maximum allowed width. Overlapping buildings should be a non-issue with the given algorithm and problem hints. Really, the problem description is full of overt and subtle hints, and this is an ideal problem to show how to use OOP correctly, prior to worrying with inheritance (I'm a bonafide Java hater, and I can't find any issue to attack).

In my view, you need to sit down and think every value out as a predicate (or function, as in f(a) = x+a), then how they combine to define the use of the coordinate space in your skyline. Keep plenty of paper handy, to crumble and throw away (this is math, and you're not practiced enough to keep it all in your head). Don't think about all the state. Reason out the results, then work backwards from there.

As one basic example, your floating building problem clearly comes from not using the height to generate the top Y-value. Dig up that algebra and geometry in the back of your head, and start putting it on paper.
Code:
streetlevel = building.y - building.height
You need to make code that draws it, but that's not where your [main] problem is.
 
Last edited:

psx2514

Junior Member
Oct 17, 2012
16
0
0
Okay, this is what I did so far, and it keeps looking like there are less building then there should be (mainly because the buildings probably keep overlapping each other). Could you please show me what I'm doing wrong. Could someone PLEASE explain this to me in plain English? Just pretend that I don't have 15 years of programming experience, and that I'm just starting out.

Code:
 import java.awt.*;
import java.util.Random;

public class Building
{
   private int x, y, width, height;
   private Color color;
   private String string;

   //-----------------------------------------------------------------
   //  Constructor: Sets up this building with the specified values.
   //-----------------------------------------------------------------
   public Building (Color shade, int upperX, int upperY) {
      color = shade;
      x = upperX;
      y = upperY;
      width = (int) (Math.random() * 60) + 40; //I want to generate a random number from 40 to 100.  Is this right?
      height = (int) (Math.random() * 500) + 100; //I want to generate a random number between 100 to 600.  Is this right?
      
   }
   
   //-----------------------------------------------------------------
   //  Draws this building in the specified graphics context.
   //-----------------------------------------------------------------
   public void draw (Graphics page)
   {
      page.setColor (color);
      page.fillRect (x, y, width, height);
   }
 
   //-----------------------------------------------------------------
   //  Color mutator.
   //-----------------------------------------------------------------
   public void setColor (Color shade)
   {
      color = shade;
   }

   //-----------------------------------------------------------------
   //  X mutator.
   //-----------------------------------------------------------------
   public void setX (int upperX)
   {
      x = upperX;
   }


   //-----------------------------------------------------------------
   //  Y mutator.
   //-----------------------------------------------------------------
   public void setY (int upperY)
   {
      y = upperY;
   }
   //-----------------------------------------------------------------
   //  width mutator.
   //-----------------------------------------------------------------
   public void setWidth (int nWidth)
   {
      width = nWidth;
   }

   //-----------------------------------------------------------------
   //  height mutator.
   //-----------------------------------------------------------------
   public void setheight (int nHeight)
   {
      height = nHeight;
   }
   
  
   //-----------------------------------------------------------------
   //  width accessor.
   //-----------------------------------------------------------------
   public int getWidth ()
   {
      return width;
   }
   //-----------------------------------------------------------------
   //  height accessor.
   //-----------------------------------------------------------------
   public int getHeight ()
   {
      return height;
   }
   //-----------------------------------------------------------------
   //  Color accessor.
   //-----------------------------------------------------------------
   public Color getColor ()
   {
      return color;
   }

   //-----------------------------------------------------------------
   //  X accessor.
   //-----------------------------------------------------------------
   public int getX ()
   {
      return x;
   }

   //-----------------------------------------------------------------
   //  Y accessor.
   //-----------------------------------------------------------------
   public int getY ()
   {
      return y;
   }
   
   

}

import javax.swing.*;
import java.awt.*;
import java.util.Random;

public class SkylinePanel extends JPanel
{
   private final int MAX_BUILDINGS = 5, MAX_WIDTH = 100, MAX_HEIGHT = 400;
   private final int MAX_X = 580, MAX_Y = 360;
   private Random generator;
   
   //-----------------------------------------------------------------
   //  Constructor: Creates five Building objects.
   //-----------------------------------------------------------------
   public SkylinePanel()
   {
     generator = new Random();
      /*building1 = new Building (Color.black, 100, 380, 40, 100);
      building2 = new Building (Color.black, 170, 290, 80, 190);
      building3 = new Building (Color.black, 285, 80, 100, 400);
      building4 = new Building (Color.black, 450, 270, 80, 210);
      building5 = new Building (Color.black, 580, 360, 45, 120);*/
      
      setPreferredSize(new Dimension(640, 480));
      setBackground (Color.cyan);
     
   }
  
   //-----------------------------------------------------------------
   //  Draws this panel by requesting that each building draw itself.
   //-----------------------------------------------------------------
   public void paintComponent (Graphics page)
   {
      super.paintComponent(page);

      int x, y, width, height;
      
      for (int count = 0; count < MAX_BUILDINGS; count++) {
        x = generator.nextInt(MAX_X) + 10;
        y = generator.nextInt(MAX_Y) + 10;
        width = generator.nextInt(MAX_WIDTH) + 10;
        height = generator.nextInt();
        page.fillRect (x, y, width, height);
        
      }
      }
      
      
      /*building1.draw(page);
      building2.draw(page);
      building3.draw(page);
      building4.draw(page);
      building5.draw(page);
      page.drawString ("Ben's Skyline.", 110, 70); //Title*/
   
   }
The Building constructor, and the SkylinePanel class is where I did my edits. Did I do something wrong in my for loop, or what?
 
Last edited:

psx2514

Junior Member
Oct 17, 2012
16
0
0
JDK documentation:
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/Graphics.html#fillRect(int, int, int, int)

Google is your friend. Look at the documentation in the JDK and get a feel for how fillRect works and what parameters it expects. If your buildings are overlapping, that means that the parameters you are passing to fillRect are overlapping as well.

When did I say I didn't know how fillRect works? Just look at my ORIGINAL program, and you'll see I know how it works.
 

psx2514

Junior Member
Oct 17, 2012
16
0
0
All I'm asking is for someone to look at my code, and tell me what I'm doing wrong. Then point me in the right direction. THAT'S IT.

The hostility here is unwarranted and unappreciated. Before posting any further, please check your inbox, you have a PM from me.
-ViRGE
 
Last edited by a moderator:

psx2514

Junior Member
Oct 17, 2012
16
0
0
All I'm asking is for someone to look at my code, and tell me what I'm doing wrong. Then point me in the right direction. THAT'S IT.

The hostility here is unwarranted and unappreciated. Before posting any further, please check your inbox, you have a PM from me.
-ViRGE

I'm just sick and tired of people on forums (not just this one) answering questions that I didn't even ask,or implying that I don't know something when I do while having an arrogant "I know more than you, so you're stupid," attitude about it. All I'm doing is asking for help. I'm not asking for people to tell me that my future is screwed because I can't figure this out. Don't you think I know that? Why do you think I'm asking for help in the first place? I go to these forums as a last resort when Google doesn't work for me. This is a specific problem for me, hence I can't find an easy answer just by "Googling." I'm also sick and tired of people who don't really want to help you. They just want to prove that their better than you (mainly because of their own insecurities).
 

Cerb

Elite Member
Aug 26, 2000
17,484
33
86
Just pretend that I don't have 15 years of programming experience, and that I'm just starting out.
I see only two programming problems in your code--and only one that isn't also an algebra problem. You need to think about the problem statelessly, as a set of math problems.

Physically draw out, on paper, an example "skyline", and mark your shapes and edges. Mark relative 0-points, and how far away, and in what direction, other points are. Seriously. My scribbling pad is worth over $30 retail*.

Code:
      x = upperX;
      y = upperY;
      width = (int) (Math.random() * 60) + 40;
      height = (int) (Math.random() * 500) + 100;
The width and height are correct for 40-100 and 100 to 600, from what I can see. However, that's far from following the directions.
Code:
   public void draw (Graphics page)
   {
      page.setColor (color);
      page.fillRect (x, y, width, height);
   }
fillRect is filling from [x, y] to [x+width-1, y+height-1]
y+height should equal your street/horizon level, or 1px past the bottom if that level is the botto of the screen (drawing is left->right, top->down, and you need to account for that).

This is algebra, and maybe a bit of geometry. Yes, there's a programming problem, here, but what you are most stuck on is handling the coordinate system. There is no better solution to that than working it out, with diagrams, and referentially transparent functions.

http://www.mathsisfun.com/definitions/quadrant-graph-.html
Imagine drawing the scene in quadrant I (+,+), with the bottom/street/horizon on the axis. The problem's required coordinates are based on that, which is the intuitive way to look at it. Not just the buildings, mind you, but the whole height.

The coordinate system for the drawing inside your window has the Y axis reversed, going downward as it increases. To account for that, you must effectively convert Y values to the equivalent of frame_height-y.

When did I say I didn't know how fillRect works? Just look at my ORIGINAL program, and you'll see I know how it works.
You didn't have to say that. Your code says it. You do not compute upperY correctly (at all, really), nor upperX, and you pass the raw values, not computed correct values, to fillRect.

You need to be able to define Building.upperX as a function of all the prior buildings' xs and widths, and upperY as a function of heights.
f( x[0]...x, width[0]...width ) -> Building.upperX
Classic, yummy, high school algebra (w/ an ugly representation w/o [La]TeX). If you can get that and the height figured out, the rest should flow from that.

Now then, let's go back to the algorithm, which was given to you:
1. generate random number
for each number from one to random number
2. generate random width
generate random height
3. instantiate building
4. draw building
5. generate random gap between next building
6. update distance from left side of frame
Your code currently does this:
1. instantiate building with non-random inputs
2. apply random value to width
3. apply random value to height
4. draw building

P.S.
I'm also sick and tired of people who don't really want to help you. They just want to prove that their better than you
Like veri745?

* I buy my pens and ink online, way cheaper, but am using recent Office Depot prices, which were almost shocking to me, to make a point.
 
Last edited:

psx2514

Junior Member
Oct 17, 2012
16
0
0
I see only two programming problems in your code--and only one that isn't also an algebra problem. You need to think about the problem statelessly, as a set of math problems.

Physically draw out, on paper, an example "skyline", and mark your shapes and edges. Mark relative 0-points, and how far away, and in what direction, other points are. Seriously. My scribbling pad is worth over $30 retail*.

Code:
      x = upperX;
      y = upperY;
      width = (int) (Math.random() * 60) + 40;
      height = (int) (Math.random() * 500) + 100;
The width and height are correct for 40-100 and 100 to 600, from what I can see. However, that's far from following the directions.
Code:
   public void draw (Graphics page)
   {
      page.setColor (color);
      page.fillRect (x, y, width, height);
   }
fillRect is filling from [x, y] to [x+width-1, y+height-1]
y+height should equal your street/horizon level, or 1px past the bottom if that level is the botto of the screen (drawing is left->right, top->down, and you need to account for that).

This is algebra, and maybe a bit of geometry. Yes, there's a programming problem, here, but what you are most stuck on is handling the coordinate system. There is no better solution to that than working it out, with diagrams, and referentially transparent functions.

http://www.mathsisfun.com/definitions/quadrant-graph-.html
Imagine drawing the scene in quadrant I (+,+), with the bottom/street/horizon on the axis. The problem's required coordinates are based on that, which is the intuitive way to look at it. Not just the buildings, mind you, but the whole height.

The coordinate system for the drawing inside your window has the Y axis reversed, going downward as it increases. To account for that, you must effectively convert Y values to the equivalent of frame_height-y.

You didn't have to say that. Your code says it. You do not compute upperY correctly (at all, really), nor upperX, and you pass the raw values, not computed correct values, to fillRect.

You need to be able to define Building.upperX as a function of all the prior buildings' xs and widths, and upperY as a function of heights.
Classic, yummy, high school algebra (w/ an ugly representation w/o [La]TeX). If you can get that and the height figured out, the rest should flow from that.

Now then, let's go back to the algorithm, which was given to you:Your code currently does this:

P.S.
Like veri745?

* I buy my pens and ink online, way cheaper, but am using recent Office Depot prices, which were almost shocking to me, to make a point.

Well, if you look at my original post, which contains my original program before I attempted to randomize the width and height, you'll see that it should run fine. It's just when I try to randomize the width and height that things get all messed up.

Also, I made a mistake with the height. It should be from 100 - 400 (not 600; that would be too high).

And wouldn't the coordinate system in Java be like quadrant IV on your typical coordinate system since (0, 0) is in the top left corner, and the numbers on the Y axis go down and stay positive rather than being negative?
 

mv2devnull

Golden Member
Apr 13, 2010
1,539
169
106
Well, if you look at my original post, which contains my original program before I attempted to randomize the width and height, you'll see that it should run fine. It's just when I try to randomize the width and height that things get all messed up.
That original code has numeric values that have been pre-computed to generate expected output. Your task is to generate numbers while the program runs and dynamically compute appropriate numeric values.

You had previously a predetermined list of objects. Your task now is to create a dynamic list of objects and operate with that list. (I presume.)

psx2514 said:
Also, I can't use arrays yet since we're not up to those in class yet.
What?
 
Last edited:

exdeath

Lifer
Jan 29, 2004
13,679
10
81
hint: running sum of your random numbers to keep track of current location from left to right until the sum is > screen width. Or if you keep a list of previously generated objects to refer to, same thing. Your next object starting x position is always your previous_obj_x + previous_object_width + random space and your next width is just random, rinse repeat.

Really nothing special here at all. This really has nothing to do with Java or even math really, it's becoming comfortable with 2D coordinate systems and view layouts and positioning and tracking of multiple objects being drawn in a GUI with relative positions, some of which you will not have direct control over or be able to anticipate statically (eg: random position? or simply user input request?).
 
Last edited:

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
Okay, instead of me trying to explain the assignment, I'm going to just post it here verbatim from my class website. Then I'll post the code I have so far.

In my opinion this is where you went wrong with your request. If you don't understand the problem sufficiently well that you can explain it in your own words then you probably don't understand it well enough to solve it. The first reply that you got was a little curt, but not out of line given that you had pasted the assignment, and then pasted your code. Most of the people here are working programmers, and I've seen them give a lot of their time and effort to people who come here with the proper attitude and demonstrate that they've been trying hard to make something work, and just need a little help with it. I'm sure that's true of you as well, but your approach to the post made it seem like you weren't willing to put too much effort in, and your response to the first reply set an unfortunate tone. If you still want help then push the reset button and try a different approach.
 

Tweak155

Lifer
Sep 23, 2003
11,449
264
126
In my opinion this is where you went wrong with your request. If you don't understand the problem sufficiently well that you can explain it in your own words then you probably don't understand it well enough to solve it. The first reply that you got was a little curt, but not out of line given that you had pasted the assignment, and then pasted your code. Most of the people here are working programmers, and I've seen them give a lot of their time and effort to people who come here with the proper attitude and demonstrate that they've been trying hard to make something work, and just need a little help with it. I'm sure that's true of you as well, but your approach to the post made it seem like you weren't willing to put too much effort in, and your response to the first reply set an unfortunate tone. If you still want help then push the reset button and try a different approach.

I'm 8 days late but well said :thumbsup: