You are on page 1of 5

import import import import

wheels.users.*; java.awt.Color; java.awt.event.MouseEvent; java.util.Vector;

/** * Poorly simulates the old hand-held version of Simon-Says. * * @author Zach Tomaszewski * @version 16 Nov 07 */ public class SimonSays { /* * Warning: Though it works, this game is still pretty rough. * It's certainly not release ready, and I'm a little uncertain about * my thread use. * * In other words, don't look to this code as a good example to * be emulated! */ /** How long (in milliseconds) a button stays hightlighted when pressed */ public static final int FLASH_LENGTH = 500; protected protected protected protected protected Frame window; Button red; Button green; Button blue; Button yellow;

protected boolean locked = false; //whether the interface should be frozen //holds the sequence to match protected Vector<Button> sequence = new Vector<Button>(); //holds the user's sequence of guesses protected Vector<Button> guesses = new Vector<Button>(); /** * Builds a SimonSays interface with four buttons * (red, green, blue, yellow) to click. */ public SimonSays() { window = new Frame(); //calculate dimensions of buttons int bWidth = Frame._dp.getWidth() / 2; int bHeight = Frame._dp.getHeight() / 2; //create buttons red = new Button("RED", 0, 0, bWidth, bHeight, Color.red, new Color(100, 0, 0)); green = new Button("GREEN", bWidth, 0, bWidth, bHeight, Color.green, new Color(0, 100, 0)); blue = new Button("BLUE", 0, bHeight, bWidth, bHeight, Color.blue, new Color(0, 0, 100)); yellow = new Button("YELLOW", bWidth, bHeight, bWidth, bHeight, Color.yellow, new Color(100, 100, 0)); }

/** * Returns one of this SimonSays' four buttons at random. * * @return a random button from this SimonSays */ public Button getRandomButton() { int random = (int) (Math.random() * 4); switch (random) { case 0: return this.red; case 1: return this.blue; case 2: return this.green; default: return this.yellow; } } /** * Visually animates the current sequence of random buttons. */ public void playSequence() { for (Button button : sequence) { //use do-while since want at least a little delay after each button do { //delay until the UI is free again try { Thread.sleep(200); }catch (InterruptedException ie){ //interrupted, which shouldn't happen System.err.println("PlaySquence thread interrupted."); } } while (locked); //UI finally free, so highlight next button button.highlight(); } } /** * Runs a game of SimonSays. */ public void run() { boolean userCorrect = true; //while user continues to guess right, continue extending sequence while (userCorrect) { //add next button to sequence and play Button next = this.getRandomButton(); this.sequence.add(next); this.playSequence(); //now let user guess at the sequence while (guesses.size() < sequence.size()) { try { //pause periodically to take it easy on CPU Thread.sleep(300); }catch (InterruptedException ie){ //interrupted, which shouldn't happen System.err.println("Delay thread interrupted."); }

//compare last guess int i = guesses.size() - 1; //index of last guess if (i >= 0 && sequence.get(i) != guesses.get(i)) { userCorrect = false; System.out.println("Incorrect!"); System.out.println("Sequence: " + sequence); System.out.println("Guesses: " + guesses); break; } } //clear guesses for next sequence guesses.clear(); } } /** * Creates an instance of Simon Says for the player to enjoy. */ public static void main(String[] args) { SimonSays game = new SimonSays(); game.run(); }

/** * A clickable button that changes color from on-to-off or * off-to-on each time it is clicked. */ protected class Button extends Rectangle { private Color onColor; private Color offColor; private String name; /** * Creates a new button with its upper-left corner * positioned at (xPos, yPos). The button has the given * width and height (in pixels), and it changes between * onColor and offColor when clicked. Its name is used * in toString() output. * <p> * A new button starts in the offColor. */ public Button(String name, int xPos, int yPos, int width, int height, Color onColor, Color offColor) { super(); this.setLocation(xPos, yPos); this.setSize(width, height); this.name = name; this.onColor = onColor; this.offColor = offColor; this.setColor(offColor); } /**

* When pressed, a Button will highlight itself and add itself to * the sequence of user guesses. * Overrides Recantangle's method to receive clicks. */ public void mousePressed(MouseEvent me) { if (!locked) { //ignore new clicks if UI is locked guesses.add(this); //add this button to user guesses this.highlight(); } } /** * This button toggles its color for FLASH_LENGTH * milliseconds, and then reverts to its current state. */ public void highlight() { this.toggle(); //delay using a separate thread, or else above toggle never completes new HighlightDelay(this).start(); } /** * Returns whether this button is currently showing * its on color (rather than its off color). */ public boolean isOn() { return (this.getColor().equals(onColor)); } /** * If this Button is on, it switches off; if off, it turns on. */ public void toggle() { if (this.isOn()){ this.setColor(offColor); }else { this.setColor(onColor); } } /** * Returns this button's name. */ public String toString() { return this.name; } /** * A separate delay thread so that the animation thread * is not suspended during a button flash. Will toggle * the given button again when it's done delaying. */ private class HighlightDelay extends Thread { private Button button; /** * Takes the button to toggle at the end of this delay. */

public HighlightDelay(Button b) { this.button = b; } /** * Locks the SimonSays user interface, delays FLASH_LENGTH, * and then unlocks the interface again and toggles the button * (which usually means turning it off). */ public void run() { locked = true; try { Thread.sleep(FLASH_LENGTH); }catch (InterruptedException ie) { //delaying interrupted, which shouldn't happen System.err.println("HighlightDelay thread interrupted."); } locked = false; button.toggle(); } }//end HighlightDelay }//end Button }//end SimonSays

You might also like