I am asked to increase the sequence length of the game Simon, which is written i
ID: 3535205 • Letter: I
Question
I am asked to increase the sequence length of the game Simon, which is written in the java. However I am not able to do this and am looking for help on completing the program using the instructions inlcuded in the code.
import java.awt.*;
import java.util.*;
/*
* This program implements a version of the Simon memory game.
* In this version, the game has one row of colored squares.
* The game starts when the program flashes a random sequence of
* squares. Then the user is supposed to click on the squares
* in the same exact order. If the user succeeds, then the
* game should repeat with a sequence that is one square longer.
* The game ends when the user clicks the squares in the wrong
* order.
*/
public class Simon {
public static void main(String[] args) { // main method
Scanner console = new Scanner(System.in);
int numberOfSquares = getInt(console);
DrawingPanel panel = new DrawingPanel(numberOfSquares * 175, 300);
Graphics g = panel.getGraphics();
g.setFont(new Font("Serif", Font.BOLD, 24));
int [] xArray = new int [numberOfSquares];
for( int i= 0; i< numberOfSquares; i++){
xArray[i] = 50 + 150*i;
g.drawRect(xArray[i],100,100,100);
}
Color[] colors = {Color.BLUE, Color.RED, Color.GREEN, Color.YELLOW, Color.CYAN, Color.MAGENTA};
// Fill square 0 with its color
for( int i= 0; i< numberOfSquares; i++){
g.setColor(colors[i]);
g.fillRect(xArray[i]+1, 101, 99, 99);
}
int sequenceLength = 2;
Random rand = new Random();
// prime the loop
boolean userSucceeds = true;
while (userSucceeds) {
// decide on a random sequence of squares
/* Project 3 Need To Do
* Create an array of length sequenceLength, and
* write a method that fills this array with
* values from rand.nextInt(numberOfSquares).
*/
int [] length = new int [sequenceLength];
for ( int i = 0; i < sequenceLength ; i++ ) {
length[i] = rand.nextInt(numberOfSquares);
}
// Which square should be flashed first?
int square0 = rand.nextInt(numberOfSquares);
// Which square should be flashed second?
int square1 = rand.nextInt(numberOfSquares);
int square2 = rand.nextInt(numberOfSquares);
//int[] square = {square0, square1, square2,square3}
//for (int i = 0; i< 4 ; i++) {
// flash the squares
/* Project 3 Need To Do
* Instead of two pieces of code to flash two squares,
* you should have a loop to flash sequenceLength
* squares. Your array with random numbers tells
* you which square to flash at each point in the
* sequence.
*/
int upperLeftX;
Color squareColor;
upperLeftX = xArray[square0];
squareColor = colors[square0];
flashSquare(panel, g, 1, upperLeftX, squareColor);
panel.sleep(1000);
// Flash the square that should be flashed second.
/* Lab 9 Need To Do
* This if statement can be replaced with a single assignment
* using the x-coordinate array with square1 as the index.
*/
upperLeftX = xArray[square1];
squareColor = colors[square1];
flashSquare(panel, g, 2, upperLeftX, squareColor);
panel.sleep(1000);
upperLeftX = xArray[square2];
squareColor = colors[square2];
flashSquare(panel, g, 3, upperLeftX, squareColor);
// get the sequence of user clicks
/* Project 3 Need To Do
* Instead of separate pieces of code for each click,
* you should have a loop that gets the sequence of
* squares that the user clicks.
* You should store this sequence in an array of
* length sequenceLength.
*/
// Get the first click.
int[] click = busyWait(panel);
// What square did the user click?
int user0 = getSquareClicked(xArray, numberOfSquares,click[0], click[1]);
// Get the second click.
click = busyWait(panel);
// What square did the user click?
int user1 = getSquareClicked(xArray, numberOfSquares,click[0], click[1]);
// Get the third click.
click = busyWait(panel);
// What square did the user click?
int user2 = getSquareClicked(xArray, numberOfSquares,click[0], click[1]);
// Check if the user's clicks are correct.
/* Project 3 Need To Do
* Use a loop to check that the user's sequence of clicks
* matches the correct sequence of clicks. If any click
* is incorrect, then userSucceeds should be set to false.
*/
// Was the first click wrong?
if (square0 != user0) {
userSucceeds = false;
}
// Was the second click wrong?
if (square1 != user1) {
userSucceeds = false;
}
// message about success or failure
if (userSucceeds) {
g.setColor(Color.BLACK);
g.drawString("You won! Try Again!", 10, 30);
} else {
// erase old message
g.setColor(Color.WHITE);
g.drawString("You won! Try Again!", 10, 30);
g.setColor(Color.RED);
g.drawString("You lost!", 10, 30);
}
panel.sleep(1000);
/* Project 3 Need To Do
* Increment sequenceLength.
* Do this when you have finished all the other
* Project 3 Need To Do's
*/
}
}
// Flashes the square as indicated by the parameters.
public static void flashSquare(DrawingPanel panel, Graphics g, int sequenceNumber,
int upperLeftX, Color squareColor) {
g.setColor(Color.WHITE);
g.fillRect(upperLeftX + 1, 101, 99, 99);
g.setColor(Color.BLACK);
g.drawString("" + sequenceNumber, upperLeftX + 50, 150);
panel.sleep(500);
g.setColor(squareColor);
g.fillRect(upperLeftX + 1, 101, 99, 99);
}
public static int getSquareClicked(int[] xArray, int numberOfSquares, int x, int y) {
for (int i = 0; i < numberOfSquares; i++) {
if (x > xArray[i] && x< xArray[i] +150 && y> 100 && y <200) {
return i;}
}
return -1;
}
// Loop until the user has pressed and released the mouse.
// Return the coordinates of the click as an int array
// of length 2.
// Neither Lab 9 nor Project 3 need to change this code..
public static int[] busyWait(DrawingPanel panel) {
// loop until mouse is pressed
boolean pressed = panel.mousePressed();
while (pressed == false) {
pressed = panel.mousePressed();
}
// loop until mouse is released
while (pressed == true) {
pressed = panel.mousePressed();
}
int[] result = new int[2];
result[0] = panel.getClickX();
result[1] = panel.getClickY();
while (result[0] == -1 || result[1] == -1) {
result[0] = panel.getClickX();
result[1] = panel.getClickY();
}
return result;
}
public static int getInt(Scanner console) { // retrieves the integer to be used from the user, uses getInt
int numberOfSquares = getInt(console, "How many boxes would you like to play with today?");
while (numberOfSquares < 2 || numberOfSquares > 6) {
System.out.println("This is an invalid entry");
numberOfSquares = getInt(console, "Please enter a number between 2 and 6:");
}
return numberOfSquares;
}
// continues to prompt until a positive integer is entered
public static int getInt(Scanner console, String prompt) { // the method will deny the user if their answer is not an integer
System.out.print(prompt);
while (!console.hasNextInt()) {
console.next(); // input discarded
System.out.println("Not a number; please try again.");
System.out.println(prompt);
}
return console.nextInt();
}
}
here is also a link to more detailed instructions
http://www.cs.utsa.edu/~cs1063/laboratories/lab9/lab9.html
(only look at project 3, other part has been done)
Explanation / Answer
import java.awt.GridLayout;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.event.*;
public class ButtonPanel extends JPanel
{
private JButton[] buttons;
private int sleepTime = 1000;
private ArrayList<Character> simonSequence; // Simon's sequence of numbered buttons
private ArrayList<Character> playerSequence; // sequence pressed by player
private ImageIcon pressed;
private int nextClick;
private boolean playerCorrect; // player correct so far
private static final Character firstChar = 'A';
private static final Character lastChar = 'D';
/** Creates a new instance of ButtonPanel */
public ButtonPanel()
{
buttons = new JButton[4];
simonSequence = new ArrayList<Character>();
playerSequence = new ArrayList<Character>();
pressed = createImageIcon("smile.gif"); // icon to show button being pressed
setLayout(new GridLayout(2,2)); // two rows two columns for the buttons
Character label = firstChar;
for (JButton b: buttons)
{
b = new JButton("" + label);
buttons[label - firstChar]= b;
b.setActionCommand("" + label); // for use in ButtonWatcher
label++;
add(b);
//is this how to create and add a ButtonWatcher for each of the buttons
b.addActionListener(new ButtonWatcher());
}
setButtonsEnabled(true);
}
public class ButtonWatcher implements ActionListener
{
public void actionPerformed(ActionEvent b)
{
Object clicked = b.getActionCommand();
if(clicked.equals("A"))
{
playerSequence.add('A');
Utility.playSound(1);
}
if(clicked.equals("B"))
{
playerSequence.add('B');
Utility.playSound(2);
}
if(clicked.equals("C"))
{
playerSequence.add('C');
Utility.playSound(3);
}
if(clicked.equals("D"))
{
playerSequence.add('D');
Utility.playSound(4);
}
}
}
//returns an ImageIcon or null if the path was invalid
private ImageIcon createImageIcon(String path)
{
java.net.URL imgURL = ButtonPanel.class.getResource(path);
if (imgURL != null)
{
return new ImageIcon(imgURL);
}
else
{
System.err.println("Couldn't find file: " + path);
return null;
}
}
//reset everything
public void resetAll()
{
sleepTime = 1000;
setNextClick(0);
playerCorrect = true;
simonSequence.clear(); // redundant on first use
playerSequence.clear();
}
public void speedUp()
{
System.out.println("speeding up");
sleepTime = (int) (sleepTime / 2);
}
public void simonTurn()
{
setButtonsEnabled(false);
addCharToSimonSequence();
playSimonSequence();
System.out.println("Simon's turn done");
setButtonsEnabled(true);
}
//enable or disable all buttons
private void setButtonsEnabled(boolean v)
{
for (JButton b: buttons)
{
b.setEnabled(v);
}
}
private void addCharToSimonSequence()
{
simonSequence.add(nextChar());
System.out.println("current sequence is " + simonSequence);
}
// choose the next button for Simon's sequence
private Character nextChar()
{
int i = firstChar + (int) (4 * Math.random());
return (char) i;
}
//play Simon's sequence - plus sounds
private void playSimonSequence()
{
Utility.pause(sleepTime);
for(Character i: simonSequence)
{
buttons[i-firstChar].setIcon(pressed);
Utility.playSound(i-firstChar+1);
Utility.pause(sleepTime);
buttons[i-firstChar].setIcon(null);
Utility.pause(sleepTime);
}
sleepTime = (int) (sleepTime * 0.95); // get progressively faster
}
public boolean playerTurn()
{
resetPlayer(); // so start storing from first player click
waitForCompletePlayerSequence();
return checkSequencesMatch();
}
//to support playerTurn()
private boolean checkSequencesMatch()
{
// check sequences
playerCorrect = true;
int checkIndex = 0;
while (checkIndex < playerSequence.size() && playerCorrect)
{
int seqNext = simonSequence.get(checkIndex);
int playerNext = playerSequence.get(checkIndex);
if (seqNext != playerNext)
{
System.out.println("a click didn't match ");
playerCorrect = false; // mismatch - so stop checking
}
checkIndex ++;
}
return playerCorrect;
}
//just resets player
private void resetPlayer()
{
setNextClick(0);
playerSequence.clear();
playerCorrect = true;
}
private void setNextClick(int v)
{
nextClick = v;
}
private void waitForCompletePlayerSequence()
{
System.out.println("player sequence " + playerSequence);
System.out.println("sequence length" + simonSequence.size());
System.out.println("player length " + playerSequence.size());
do
{
System.out.println("in waitForcompletePlayerSequence loop");
Utility.pause(500);//note this is in the main thread
}
while (playerSequence.size() < simonSequence.size());
}
public ArrayList<Character> getPlayerSequence()
{
return playerSequence;
}
}
import java.awt.GridLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import java.awt.event.*;
public class GameFrame extends JFrame
{
private MessagePanel messagePanel; //for writing messages underneath the buttons
private ButtonPanel buttonPanel; // for buttons
private JMenuBar bar;
private JMenu menuOptions;
private JMenuItem speed;
private JMenuItem restart;
private boolean finished;
private boolean restarting;
/** Creates a new instance of GameFrame */
public GameFrame()
{
finished = false;
restarting = false;
setSize(300,300);
setTitle("SIMON - Repeat after me!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(2,1));
buttonPanel = new ButtonPanel(); // button area
messagePanel = new MessagePanel(); // message area
add(buttonPanel);
add(messagePanel);
//set up menu
bar = new JMenuBar();
menuOptions = new JMenu("Edit");
speed = new JMenuItem("Speed up the game");
restart = new JMenuItem("Restart");
menuOptions.add(speed);
menuOptions.add(restart);
speed.setEnabled(true);
restart.setEnabled(true);
setJMenuBar(bar);
bar.add(menuOptions);
// TODO: add listeners for the menu options
speed.addActionListener(new MenuSelection());
restart.addActionListener(new MenuSelection());
}
//play the game
public void play()
{
Utility.playSound(0);// initial gong to get started
messagePanel.setText("Welcome to SIMON - let's start!");
Utility.pause(3000);
while(!finished)
{
messagePanel.setText("Here comes the sequence of " + (buttonPanel.getPlayerSequence().size() + 1));
buttonPanel.simonTurn();
messagePanel.setText("Your turn!");
speed.setEnabled(true);
restart.setEnabled(true);
finished = !buttonPanel.playerTurn();
if (!finished && !restarting)
{
messagePanel.setText("Well done! Now get ready for the next turn!");
Utility.pause(2000);
}
if (restarting)
{
restarting = false;
messagePanel.setText("restarting");
Utility.pause(5000);
}
speed.setEnabled(false);
restart.setEnabled(false);
}
// finish with feedback on score
messagePanel.showEndMessages(buttonPanel.getPlayerSequence().size()-1);
Utility.pause(100000);
System.exit(0);
}
private class MenuSelection implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Object menuOptions = e.getSource();
ButtonPanel button = new ButtonPanel();
if(menuOptions == restart)
{
button.resetAll();
}
else if(menuOptions == speed)
{
button.speedUp();
}
}
}
}
public class Main
{
public static void main(String[] args)
{
GameFrame game = new GameFrame();
game.setVisible(true);
System.out.println("about to invoke play");
game.play();
}
}
import java.awt.Graphics;
import javax.swing.JPanel;
public class MessagePanel extends JPanel
{
private String text;
/** Creates a new instance of MessagePanel */
public MessagePanel()
{
text = "";
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawString(text,50,50);
}
public void setText(String s)
{
this.text = s;
repaint();
}
public void showEndMessages(int howManyCorrect)
{
Utility.pause(3000);
setText("‘Whoops, got one wrong there!’");
Utility.pause(3000);
setText("You managed " + howManyCorrect + " correctly!");
Utility.pause(3000);
switch (howManyCorrect)
{
case 0:
case 1:
case 2: setText("Oh dear, not very good :-("); break;
case 3:
case 4:
case 5: setText("Okay for a beginner"); break;
case 6:
case 7:
case 8: setText("Pretty good!"); break;
case 9:
case 10:
case 11: setText("Very good! :-)"); break;
case 12:
case 13:
case 14: setText("Excellent! ;-)"); break;
default: setText("Amazing!"); break;
}
}
public java.awt.Component add(java.awt.Component comp, int index)
{
java.awt.Component retValue;
retValue = super.add(comp, index);
return retValue;
}
}
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.MalformedURLException;
public class Utility
{
private static String[] sounds = {"gong.au", "bleep_1.au", "cork.au", "ding.au", "beep_1.au"};
private static java.io.File currentDir = new java.io.File(System.getProperty("user.dir"));
public static void pause(int ms)
{
try
{
Thread.sleep(ms);
}
catch (InterruptedException e)
{
System.out.println("thread interrupted");
}
}
//this method can be invoked from the event dispatching thread (or elsewhere)
//this method will play the sound whose name is stored at index num of the sounds array.
public static void playSound(int num)
{
AudioClip clip = null;
if (num < 0 || num > sounds.length)
return;
try
{
clip = Applet.newAudioClip(new java.net.URL(currentDir.toURL(),sounds[num]));
clip.play();
}
catch (MalformedURLException e)
{
System.out.println("bad url " + e);
}
pause(250); // give the sound a chance to play
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.