Dice Game – Part 2

Dice Game – Part 2.

And here are the Extensions

  • Add a high score feature. Save the top ten highest scores and names to a file and make it persistent between runs of the program. Read the file when you start and print out the hall of fame. If a player gets a score that preempts one of the early high scores, congratulate them and update the file before you quit so it is recorded for next time.
  • Incorporate the bonus scores for multiple Yahtzees in a game. As long as you have not entered a 0 in the Yahtzee box, the rules of the game give you a bonus chip worth 100 points for each additional Yahtzee you roll during the same game.
  • Beef up your Yahtzee to the variant called “Triple Yahtzee.” In this variant, each player manages three simultaneous scorecard columns, as if they were playing for three players at once. The player can assign a roll to any one of their three columns. All entries are scored normally with respect to categories and validity, but the values in the second column are doubled, and the third column values are tripled. The player

Yahtzee

Yahtzee

Category 9 – Full house

Once again, I am going to bubble sort (bubble sort at the bottom of this post) the dice values, so that I can check to see if there are 3 of the same values and 2 of other values that are the same. This is very similar to counting how many values are the same with three/four of a kind, but this time need to make sure that there are only 3 / 2 split of different values, and for the scoring value we only need to return true/false since the value if it is a full house it is 25 points or 0 for nothing.

So, the way that I have done it, is with checking to see if values are the same within the array (whilst scanning from the start to end) and if they are increment the count (counting of similar values), if the values changes then check to see if the count is equal to 3 or 2 (which is the full house requirements) and if so set a boolean value to true and keep on checking. To get to return true, need to see if both the 3 and 2 boolean values are true then we know that we have a full house.

	// need to check for 3 of the same value and then 2 of the same value
	private Boolean checkFullHouse(int[] dice)
	{
		int count =1;
		Boolean found3 = false, found2 = false;
		for (int i=1; i < YahtzeeConstants.N_DICE;i++)
		{
			if (dice[i] == dice[i-1]) 
				count++;
			else
			{
				if (count == 3)
					found3 = true;
				else if (count == 2)
					found2 = true;
				count=1;
			}
		}
		if (count == 3)
			found3 = true;
		else if (count == 2)
			found2 = true;
		if (found3 && found2) return true;
		return false;
	}

Categories 10,11 – Small/Large straight

The last two are very similar and because once again I am using the bubble sort to organise the array into a order then we just need to check the array by going through it from start to finish checking to make sure that the value before is 1 minus the present value in the array ( e.g. array being 3,4,5, present value is the 4 and the previous value is 3 which is correct), then add up these correct placements within the array and if the consecutive values are either 4 (small straight) or 5 (large straight) return true or false accordingly.

	// consecutiveValues = how many in a straight line
	private Boolean checkStraight(int[] dice, int consecutiveValues)
	{
		int inLine =1;
		for (int i =1; i < YahtzeeConstants.N_DICE; i++)
		{
			if ((dice[i-1]+1) == dice[i]) inLine++;
		}
		if (inLine >= consecutiveValues) return true;
		return false;
	}

The main thing within the program is to make sure that you are always accounting for the difference with the categories numbers (which start from 1) and the scoring values (which start from 0) or the dice numbers (which start from 0 again), of course could make the size of those arrays 1 bigger.

To create the score array and also so we know what is a score value of 0 or not, then the score array is setup with all values of -1.

	/* setup the scores to a value of -1, default value */
	private void setupScores(int[][] scoresSetup, int playersNum, int totalValues)
	{
		for (int i=0; i < playersNum; i++)
			for (int j=0; j < totalValues;j++)
				scoresSetup[i][j] = -1;
	}

So that when you are selecting a category to place the score of your dice and you try to select a category already selected, then just need to check the score for -1 and if so we know it is a category not already used.

	private Boolean updateScore(int[] scoresUpdate, int category, int score)
	{
		// default is -1, since cannot get this score value
		if (scoresUpdate[category] == -1)
		{
			scoresUpdate[category] = score;
			return false;
		}
		else
		{
			display.printMessage("Category already selected, please select another");
			return true;
		}
	}

Also within the source code, I have included a cheat mode so that you can insert the values of the dice in runtime (when you are asked about the number of players type in -99 and the cheat mode is activated and there is only 1 player setup).

The next post is the extensions of this assignment.

Yahtzee

Yahtzee, over the next two posts going to explain about the thoughts behind working out the categories within the game, e.g. yahtzee, straight etc. And then in the 3rd post I am going to do the extensions of the assignment.

So to start with here are the different types of categories that the 5 dice can fall into with also there score associated value. ( the number at the start is the category that the dice would fall into)

  • 1. Ones. Any dice configuration is valid for this category. The score is equal to the sum of all of the 1

Breakout – Part 1

Breakout is a classic game. The original game of Breakout was invented by Steve Wozniak before he founded Apple with Steve Jobs.

The main part of the game is to have bricks at the top of the screen, in x rows going downwards, and you have a paddle (bat) and a ball which you hit with the paddle at the bottom of the screen to try and direct the ball to hit the bricks to get rid of them all. The name breakout comes from when you knock down one part of the wall (e.g. left hand side) you can direct the ball to go up that side and then it would have broken out of the bricks and start to knock down the wall from the top.

It is a classic game, and also a game that most people can do, but it is like most things and that is you have to break things into pieces of the puzzle.

To start with, the assignment documentation does make a good start with breaking things down in the pieces, here the main parts that I thought of as well added into the list from the assignment documentation.

  • Build the bricks (wall)
  • Paddle (bat), mouse to move the paddle
  • Bat to hit, and collide with objects
  • Make the ball move around the screen
  • Whilst the ball is moving, check for collisions (with the bricks/paddle)
  • If the ball collides with a brick, remove it and reverse the y direction to go in the opposite direction
  • If the ball collides with the paddle, alter the direction for the ball depending on where it hits the paddle
  • Create some textural information, e.g. score, click to start, etc
  • Extras, music, extra scores/life’s balls that are generated when you hit a brick with the ball
  • When all of the bricks are knocked out, display a message

So to start with, the bricks (wall of bricks), since there is some declarations already setup in the source file

/** Number of bricks per row */
	private static final int NBRICKS_PER_ROW = 10;
 
/** Number of rows of bricks */
	private static final int NBRICK_ROWS = 10;

then we can create a rows of bricks accordingly to the constant (final) values

		int startX, startY = BRICK_Y_OFFSET;
		GRect bricks;
		// iRow = going downwards
		for (int iRow =0; iRow < NBRICK_ROWS; iRow++)
		{
			startX = BRICK_SEP;
			// iAisle = going across
			for (int iAisle = 0; iAisle < NBRICKS_PER_ROW; iAisle++)
			{
				bricks = new GRect(startX,startY, BRICK_WIDTH,BRICK_HEIGHT);
				bricks.setFillColor(colours[iRow]);
				bricks.setFilled(true);
				bricks.setColor(colours[iRow]);
				add(bricks);
				startX += BRICK_WIDTH + BRICK_SEP;
			}
			startY += BRICK_HEIGHT + BRICK_SEP;
		}

here are my private variables so that the rest of the methods can use them to move/create that object in questions

	private GRect paddleObject;
	private GOval ballObject, extraScore, extraLife;
	private GLabel textDisplay, status;
	private double ballVX, ballVY, ballX, ballY;
	private int lifesLeft, score, pauseDelay;
	private RandomGenerator rgen = RandomGenerator.getInstance();
	private Color colours[] = new Color[NBRICK_ROWS];

The next thing, is to create a paddle and also a mouse listener for the mouse movement on the screen to move the paddle in the x direction (left and right). (paddleObject being the paddle from the private variables)

// mouse listener
	public void mouseMoved(MouseEvent e)
	{
		Point movePos = e.getPoint();
		if (movePos.x < (WIDTH- PADDLE_WIDTH))
			paddleObject.setLocation(movePos.x,HEIGHT - (PADDLE_Y_OFFSET + PADDLE_HEIGHT));
	}
// create the paddle
	private void addPaddle()
	{
		paddleObject = new GRect((WIDTH/2) - (PADDLE_WIDTH/2), HEIGHT - (PADDLE_Y_OFFSET + PADDLE_HEIGHT),
								PADDLE_WIDTH, PADDLE_HEIGHT);
		paddleObject.setColor(Color.BLACK);
		paddleObject.setFillColor(Color.BLACK);
		paddleObject.setFilled(true);
		add(paddleObject);
	}

I am not going to go through all of the source code, but just in parts of the interesting stuff, so collisions, to start with we need to know if a object X has any colliding parts to it to another object and thus return the object that it has collided with, why returning the object and also passing in a object reference ? , because then we are able to use a different graphics object (e.g. the ball or a extras) and also return the actual object that we are colliding with.

	// get any Graphics Object surrounding the ball Object, be it the bat and ball, or bat and extras
	private GObject getCollidingObject(GObject ballObj)
	{
		if (!ballObj.isVisible()) return null;
		GPoint ballPoint = ballObj.getLocation();
		GObject coll;
		Point addingPoints[] = new Point[4];
		addingPoints[0]= new Point(0,0);
		addingPoints[1]= new Point(0,BALL_RADIUS);
		addingPoints[2]= new Point(BALL_RADIUS,BALL_RADIUS);
		addingPoints[3]= new Point(BALL_RADIUS,0);
		for (int i =0; i< 4; i++)
		{
			coll = getElementAt(ballPoint.getX()+addingPoints[i].x, ballPoint.getY()+addingPoints[i].y);
			if (coll != null)
					return coll;
		}
		return null;
	}

the reason why I am doing the check to see if we have collided with 4 points, if you think about it, there are 4 points that the object can collide with, top left/right, bottom left/right and if any of those points are not null (e.g. a object) then just exit the for loop and return that object, there is no need to keep on checking because we have found a object.

Next is if we have collided with a brick, and thus see if there is any bricks left, we can either use the number of bricks and every time we collide with one use a local variable to minus from until we reach 0, or go through the list of graphical objects on the screen and see if there is any bricks (GRect) left on the screen if not then all the bricks are gone (of course there still will be one left because that is the paddle (paddleObject)). either way is a good way, just that I use bricks minus way because it uses less speed (e.g. not finding graphics objects).

			bricksLeft--;
			if (bricksLeft == 0) 
			{ 
			        emptyBricks = true; 
				break;
			}
			/*//another way of checking to see if there is any GRects left.!!.
			emptyBricks = true;
			for (int i =0; i < getElementCount(); i++)
			{
				if (getElement(i).getClass().getSimpleName().equalsIgnoreCase("GRect"))
				{
					if (!getElement(i).getClass().equals(paddleObject))
					{
						emptyBricks= false;
						break;
					}
				}
			}
			if (emptyBricks) break;
								 */

the other is if we have collided with the paddle, then move the ball in another direction depending on where on the paddle we hit

	// difference between two points.
	private GPoint differenceBetween(GPoint a, GPoint b)
	{
		return new GPoint(a.getX() - b.getX(), a.getY() - b.getY());
	}
.....
	GPoint difBetween = differenceBetween(ballObject.getLocation(), colliding.getLocation());
	ballVX = (difBetween.getX() - (PADDLE_WIDTH/2))/2;
	ballVY = -(difBetween.getY()/BALL_SPEED);
	// for when the ball may try and bounce of the side of the bat and then the wall!!.
	if (ballVY == 0.0) ballVY = 1.0;
	// move in the opposite direction
	ballVY = -ballVY;

so basically we need to the point on the bat where the ball has hit, left/right top/side, (how far from the middle of the bat) and then alter the balls velocity accordingly.

The rest of the assignment is creating more of the same and textural information (making sure that the ball is not colliding with them and move !!!) and also any extra’s that you can think of, I thought that I would create extras balls that had either extra points (score) or another one that is a extra life if you catch them with your paddle.

Here is the output of the breakout game and also the full source code (I have included the full source code in the zip file above and also the PDF assignment which has more details inside).

Breakout – Part 2

Breakout – Part 2, I have broken it down into 2 parts because of the size of the source code and also the post in general, the first is the problem and solution and this is the solution in code and images.

Here is the screen output of the start of the game.

Breakout  - the start
Breakout - the start

Here is the screen output of the extra life coming down the screen, (the one in grey!!) and also the ball as well, can you catch them both ?

Breakout - extra life coming down
Breakout - extra life coming down

And here is the end of the game with the display information about how much you have scored.

Breakout - the end
Breakout - the end

Here is the full source code from the break out assignment 3, I have included it in the zip file above and also the PDF of the assignment.

/*
 * File: Breakout.java
 * -------------------
 * Name:
 * Section Leader:
 * 
 * This file will eventually implement the game of Breakout.
 */
 
import acm.graphics.*;
import acm.program.*;
import acm.util.*;
 
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
 
public class Breakout extends GraphicsProgram implements MouseListener {
 
/** Width and height of application window in pixels */
	public static final int APPLICATION_WIDTH = 400;
	public static final int APPLICATION_HEIGHT = 600;
 
/** Dimensions of game board (usually the same) */
	private static final int WIDTH = APPLICATION_WIDTH;
	private static final int HEIGHT = APPLICATION_HEIGHT;
 
/** Dimensions of the paddle */
	private static final int PADDLE_WIDTH = 60;
	private static final int PADDLE_HEIGHT = 10;
 
/** Offset of the paddle up from the bottom */
	private static final int PADDLE_Y_OFFSET = 30;
 
/** Number of bricks per row */
	private static final int NBRICKS_PER_ROW = 10;
 
/** Number of rows of bricks */
	private static final int NBRICK_ROWS = 10;
 
/** Separation between bricks */
	private static final int BRICK_SEP = 4;
 
/** Width of a brick */
	private static final int BRICK_WIDTH =
	  (WIDTH - (NBRICKS_PER_ROW - 1) * BRICK_SEP) / NBRICKS_PER_ROW;
 
/** Height of a brick */
	private static final int BRICK_HEIGHT = 8;
 
/** Radius of the ball in pixels */
	private static final int BALL_RADIUS = 10;
 
/** Offset of the top brick row from the top */
	private static final int BRICK_Y_OFFSET = 70;
 
/** Number of turns */
	private static final int NTURNS = 3;
 
	/** the starting pause delay between paddle hits **/ 
	private static final int PAUSE_DELAY = 20;
	/** text size of the display text */
	private static final int TEXT_SIZE = 5;
	/** ball speed */
	private static final double BALL_SPEED = 3.0;
	/** extras - if you catch the extra score, this is the extra value */
	private static final int EXTRA_SCORE_VALUE = 100;
	/** extras speed coming down the screen */
	private static final double EXTRAS_SPEED = 3.0;
 
	public void mouseMoved(MouseEvent e)
	{
		Point movePos = e.getPoint();
		if (movePos.x < (WIDTH- PADDLE_WIDTH))
			paddleObject.setLocation(movePos.x,HEIGHT - (PADDLE_Y_OFFSET + PADDLE_HEIGHT));
	}
 
	// setup the bricks, with different colours
	private void CreateBricks()
	{
// if there is any more colours, rows or less then this could be a problem of creating the list of colours.
		colours[0] = Color.RED;
		colours[1] = Color.RED;
		colours[2] = Color.ORANGE;
		colours[3] = Color.ORANGE;
		colours[4] = Color.YELLOW;
		colours[5] = Color.YELLOW;
		colours[6] = Color.GREEN;
		colours[7] = Color.GREEN;
		colours[8] = Color.CYAN;
		colours[9] = Color.CYAN;
 
		int startX, startY = BRICK_Y_OFFSET;
		GRect bricks;
		// iRow = going downwards
		for (int iRow =0; iRow < NBRICK_ROWS; iRow++)
		{
			startX = BRICK_SEP;
			// iAisle = going across
			for (int iAisle = 0; iAisle < NBRICKS_PER_ROW; iAisle++)
			{
				bricks = new GRect(startX,startY, BRICK_WIDTH,BRICK_HEIGHT);
				bricks.setFillColor(colours[iRow]);
				bricks.setFilled(true);
				bricks.setColor(colours[iRow]);
				add(bricks);
				startX += BRICK_WIDTH + BRICK_SEP;
			}
			startY += BRICK_HEIGHT + BRICK_SEP;
		}
	}
 
	private void addPaddle()
	{
		paddleObject = new GRect((WIDTH/2) - (PADDLE_WIDTH/2), HEIGHT - (PADDLE_Y_OFFSET + PADDLE_HEIGHT),
								PADDLE_WIDTH, PADDLE_HEIGHT);
		paddleObject.setColor(Color.BLACK);
		paddleObject.setFillColor(Color.BLACK);
		paddleObject.setFilled(true);
		add(paddleObject);
	}
 
	private void setUpBall()
	{
		// middle !!
		ballX = WIDTH / 2;
		ballY = HEIGHT / 2;
		// ballVX / VY are the velocity of movement 
		ballObject = new GOval(ballX, ballY, BALL_RADIUS, BALL_RADIUS);
		ballObject.setFillColor(Color.BLACK);
		ballObject.setFilled(true);
		add(ballObject);
		// setup the ball to move a random direction
		ballVX = rgen.nextDouble(1.0, 3.0);
		if (rgen.nextBoolean(0.5)) ballVX -= ballVX;
		ballVY = BALL_SPEED;
	}
 
	// move the ball and check for collision around the screen, if gone to the bottom return true else false
	private Boolean moveBall()
	{
		GPoint ballPoint = ballObject.getLocation();
		if (ballPoint.getX() > WIDTH) ballVX = -ballVX;
		if (ballPoint.getX() <= 0) ballVX = -ballVX;
		if (ballPoint.getY() <= 0) ballVY = -ballVY;
		if (ballPoint.getY() > HEIGHT) return true;//ballVY = -ballVY; // basically lost
		ballObject.move(ballVX,ballVY);
		return false;
	}
 
	// get any Graphics Object surrounding the ball Object, be it the bat and ball, or bat and extras
	private GObject getCollidingObject(GObject ballObj)
	{
		if (!ballObj.isVisible()) return null;
		GPoint ballPoint = ballObj.getLocation();
		GObject coll;
		Point addingPoints[] = new Point[4];
		addingPoints[0]= new Point(0,0);
		addingPoints[1]= new Point(0,BALL_RADIUS);
		addingPoints[2]= new Point(BALL_RADIUS,BALL_RADIUS);
		addingPoints[3]= new Point(BALL_RADIUS,0);
		for (int i =0; i< 4; i++)
		{
			coll = getElementAt(ballPoint.getX()+addingPoints[i].x, ballPoint.getY()+addingPoints[i].y);
			if (coll != null)
					return coll;
		}
		return null;
	}
 
	// display the text on the screen to give some information.
	private void displayText(String text)
	{
		textDisplay = new GLabel(text,(WIDTH/2 - (text.length() * TEXT_SIZE)), HEIGHT/2);
		textDisplay.setFont(Font.SANS_SERIF);
		add(textDisplay);
	}
 
	// display the status , score and also lives left
	private void displayStatus()
	{
		if (status != null) remove(status);
		status = new GLabel("Score : "+score +" : Lives : "+lifesLeft,WIDTH/2, (BRICK_HEIGHT*2));
		add(status);
	}
 
	// difference between two points.
	private GPoint differenceBetween(GPoint a, GPoint b)
	{
		return new GPoint(a.getX() - b.getX(), a.getY() - b.getY());
	}
 
	// type = true - extra life, false - extra score (+100) 
	private void generateExtra(Boolean type, GObject startingPoint)
	{
		if (type)
		{
			// create a extraLife object if not one already
			extraLife.setLocation(startingPoint.getX(), startingPoint.getY());
			extraLife.setColor(Color.MAGENTA);
			extraLife.setFilled(true);
			extraLife.setVisible(true);
			add(extraLife);
		}
		else
		{
			// create a extraScore object if not one already
			extraScore.setLocation(startingPoint.getX(), startingPoint.getY());
			extraScore.setColor(Color.GRAY);
			extraScore.setFilled(true);
			extraScore.setVisible(true);
			add(extraScore);
		}
	}
 
	/* move the extraLife/Score if they are visible.*/
	private void moveExtras()
	{
		if (extraLife.isVisible())
		{
			extraLife.move(0, EXTRAS_SPEED);
			if (extraLife.getLocation().getY() > HEIGHT) remove(extraLife);
		}
		if (extraScore.isVisible())
		{
			extraScore.move(0,EXTRAS_SPEED);
			if (extraScore.getLocation().getY() > HEIGHT) remove(extraScore);
		}
	}
/* Method: run() */
/** Runs the Breakout program. */
	public void run() {
		/* You fill this in, along with any subsidiary methods */
		getGCanvas().setSize(WIDTH, HEIGHT);
		GObject colliding;
		AudioClip bounceSound = MediaTools.loadAudioClip("bounce.au");
		Boolean bottomHit, emptyBricks = true;
		int bricksLeft=0, paddleHit, randomExtra;
 
		extraLife = new GOval(0, 0, BALL_RADIUS,BALL_RADIUS);
		extraScore = new GOval(0,0, BALL_RADIUS, BALL_RADIUS);
		score = 0;
		lifesLeft = NTURNS;
		pauseDelay = PAUSE_DELAY;
		// loop through for the amount of lives
		while (lifesLeft > 0)
		{
			/* setup the display and then ask the user to click to start */
 
			if (emptyBricks)
			{
				/* clear the screen and rebuild the bricks, if come to the end of that level, or just starting*/
				removeAll();
				bricksLeft = NBRICKS_PER_ROW * NBRICK_ROWS;
				CreateBricks();
				addPaddle();
				addMouseListeners();
				emptyBricks = false;
			}
			displayText("Click to start");
			displayStatus();
			waitForClick();
			remove(textDisplay);
			setUpBall();
			paddleHit =0;
			bottomHit =false;
			randomExtra = rgen.nextInt(5);
			/* end of setup display*/
			while (true)
			{
				// moveBall returns true if the bottom has been hit.
				if (moveBall()) {
					bottomHit = true;
					break;
				}
				moveExtras();
				colliding = getCollidingObject(ballObject);
				// if the ball has collided with anything
				if (colliding != null)
				{
					if (!colliding.equals(paddleObject))
					{
						if (!colliding.equals(status))
						{
							if (randomExtra <=0)
							{
								randomExtra = rgen.nextInt(5);
								// create a extra life if next random extra is even else extra score
								if ((randomExtra % 2)==0)
									generateExtra(true,colliding);
								else
									generateExtra(false,colliding);
							}
							// delete the object that we just collided with, e.g. the brick
							if (colliding.getClass().getSimpleName().equalsIgnoreCase("GRect"))
							{
								// decrement the randomExtra 
								randomExtra--;
								// increment the score by finding out the colour of brick that we hit.
								Color collidColor = colliding.getColor();
								for (int i = (NBRICK_ROWS-1); i > 0; i--)
								{
									score++;
									if (colours[i] == collidColor) break;
								}
								displayStatus();
								remove(colliding);
								/* if no more bricks.. exit */
								bricksLeft--;
								if (bricksLeft == 0) 
								{ 
									emptyBricks = true; 
									break;
								}
								/*//another way of checking to see if there is any GRects left.!!.
								emptyBricks = true;
								for (int i =0; i < getElementCount(); i++)
								{
									if (getElement(i).getClass().getSimpleName().equalsIgnoreCase("GRect"))
									{
										if (!getElement(i).getClass().equals(paddleObject))
										{
											emptyBricks= false;
											break;
										}	
									}
								}
								if (emptyBricks) break;
								 */
								ballVY = -ballVY;
							}
						}
					}
					else
					{
						// handle the increase of speed (less delay)
						paddleHit++;
						if ((paddleHit % 7) ==0) pauseDelay--;
 
						bounceSound.play();
						GPoint difBetween = differenceBetween(ballObject.getLocation(), colliding.getLocation());
						ballVX = (difBetween.getX() - (PADDLE_WIDTH/2))/2;
						ballVY = -(difBetween.getY()/BALL_SPEED);
						// for when the ball may try and bounce of the side of the bat and then the wall!!.
						if (ballVY == 0.0) ballVY = 1.0;
						// move in the opposite direction
						ballVY = -ballVY;
					}
				}
				/* extra items */
				colliding = getCollidingObject(extraLife);
				if (colliding != null)
				{
					if (colliding.equals(paddleObject))
					{
						extraLife.setVisible(false);
						lifesLeft++;
						displayStatus();
					}
				}
				colliding = getCollidingObject(extraScore);
				if (colliding != null)
				{
					if (colliding.equals(paddleObject))
					{
						extraScore.setVisible(false);
						score+=EXTRA_SCORE_VALUE;
						displayStatus();
					}
				}
				pause(pauseDelay);
			}
			if (bottomHit) 
			{
				lifesLeft--;
				displayStatus();
				if (lifesLeft > 0)
				{
					displayText("Bottom hit : lives left = " + lifesLeft);
				}
				else 
					displayText("End of Game : your score " + score);
			}
			if (emptyBricks)
				displayText("Yeppy you do it!! click to start again");
			waitForClick();
			remove(textDisplay);
		}
	}
 
	private GRect paddleObject;
	private GOval ballObject, extraScore, extraLife;
	private GLabel textDisplay, status;
	private double ballVX, ballVY, ballX, ballY;
	private int lifesLeft, score, pauseDelay;
	private RandomGenerator rgen = RandomGenerator.getInstance();
	private Color colours[] = new Color[NBRICK_ROWS];
}

Problem 5

The problem is “Determining the Range, Write a ConsoleProgram that reads in a list of integers, one per line, until a sentinel value of 0 (which you should be able to change easily to some other value). When the sentinel is read, your program should display the smallest and largest values in the list.

Your program should handle the following special cases:

  • If the user enters only one value before the sentinel, the program should report that value as both the largest and smallest.
  • If the user enters the sentinel on the very first input line, then no values have been entered, and your program should display a message to that effect.

So once again broken down the problem into parts, first part need to read in the values from the keyboard and the next part is to set the lowest and the highest values (whilst making sure that no value takes the sentinel value).

Here is a example of the output from the running program

This program finds the smallest and largest integers in a list.  Enter values, one per line, using a 0 to signal the end of the list
?32
?2
?4
?5
?45
?1
?0
Smallest value was 1
Largest value was 45

source code in full, I have included within zip file and also the PDF file of the full assignment problems.

/*
 * File: FindRange.java
 * --------------------
 * This program is a stub for the FindRange problem, which finds the
 * smallest and largest values in a list of integers.
 */
 
import acm.program.*;
import java.io.Console;
 
public class FindRange extends ConsoleProgram {
 
	public void run() {
		int readInValue=sential;
		println("This program finds the smallest and largest integers in a list.  Enter values, one per line, using a "+sential+" to signal the end of the list");
		do 
		{
			readInValue = readInt("?");
			if (readInValue != sential)
			{
				if (readInValue > largestValue)
					largestValue = readInValue;
				if (readInValue < smallestValue || smallestValue == sential)
					smallestValue = readInValue;
			}
		} while (readInValue != sential);
		if (largestValue == smallestValue && largestValue == sential)
		{
			println("No values inputted");
		}
		else
		{
			println("Smallest value was "+ smallestValue);
			println("Largest value was " + largestValue);
		}
	}
 
	private int largestValue = 0, smallestValue = 0;
	private static final int sential = 0;
}