开发者

Java Simon Says

I currently have the GUI made for a simon says game, the only problem I'm having is implementing the game logic (my current code will generate a sequence and display user input, but won't save the generated sequence, or compare it to the input). I know I have to use either a queue or a stack, but I can't figure out how to implement either of these to make a working game.

Can someone please help, here's what I got so far:

Driver:

import javax.swing.JFrame;

public class Location 
{
   public static void main (String[] args) 
   {
      JFrame frame = new JFrame ("Location");
      frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new LocationPanel());
      frame.pack();
      frame.setVisible(true);
   }
}

"Location Panel" (Simon says game logic):

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.Random;

public class LocationPanel extends JPanel 
{

    private final int WIDTH =300, HEIGHT=300;   // dimensions of window
    private int[] xLoc, yLoc;       // locations for target boxes
        /*      0       1
                2       3   */

    private int timer;      // timer for displaying user clicks
    private int xClick, yClick; // location of a user click

    private int sTimer;     // timer for displaying target
    private int[] target;       // choice of target

    private int currTarget;
    private int numTargets;

    private JButton pushButton; // button for playing next sequence

    public LocationPanel() 
    {
        xLoc = new int[4];
        yLoc = new int[4];
        xLoc[0] = 100;  yLoc[0] = 100;
        xLoc[1] = 200;  yLoc[1] = 100;
        xLoc[2] = 100;  yLoc[2] = 200;
        xLoc[3] = 200;  yLoc[3] = 200;

        timer = 0;
        sTimer = 0;

        xClick = -100;  yClick = -100;
        target = new int[10];
        currTarget = -1;

        pushButton = new JButton("Next Sequence");
        pushButton.addActionListener(new ButtonListener());
        add(pushButton);

        addMouseListener(new MouseHandler()); 
        setPreferredSize (new Dimension(WIDTH, HEIGHT));
        setBackground (Color.white);
    }

    public void paintComponent(Graphics page) 
    {
        super.paintComponent(page);

        // draw four target are开发者_运维知识库a boxes
        page.setColor(Color.black);
        for (int i=0; i<4; i++) 
        {
            page.drawRect(xLoc[i]-20, yLoc[i]-20, 40, 40);
        }

        // if are displaying a target, draw it
        if (sTimer>0)
        {
            page.setColor(Color.blue);
            page.fillOval(xLoc[target[currTarget]]-15, yLoc[target[currTarget]]-15, 30, 30);
            sTimer--;
            repaint();
        }
        if (sTimer == 0) 
        {
            if (currTarget < numTargets - 1) 
            {
                currTarget++;
                sTimer = 500;
            } 
            else 
            {
                sTimer--;
            }
        }

        // if are displaying a user click, draw it
        if (timer>0) 
        {
            page.setColor(Color.red);
            page.fillOval(xClick-15, yClick-15, 30, 30);
            timer--;
            repaint();
        }
    }

    // when the button is pressed, currently the program selects a single
    // random target location and displays the target there for a short time
    private class ButtonListener implements ActionListener 
    {
        public void actionPerformed(ActionEvent event) 
        {
            Random gen = new Random();
            numTargets = target.length;
            for (int i = 0; i < target.length; i++) 
            {
                int insert = gen.nextInt(4);

                if(i == 0)
                    target[i] = insert;
                else
                {
                    while(insert == target[i - 1])
                            insert = gen.nextInt(4);

                    target[i] = insert;
                }
            }
            currTarget = 0;
            sTimer = 500;
            repaint();
        }
    }

    // when the user clicks the mouse, this method registers the click and
    // draws a circle there for a short time
    private class MouseHandler implements MouseListener, MouseMotionListener 
    {
        // the method that is called when the mouse is clicked - note that Java is very picky that a click does
        // not include any movement of the mouse; if you move the mouse while you are clicking that is a
        // "drag" and this method is not called
        public void mouseClicked(MouseEvent event) 
        {
            // get the X and Y coordinates of where the  mouse was clicked 
            xClick = event.getX();
            yClick = event.getY();
            System.out.println("(" + xClick + "," + yClick + ")");

            // the repaint( ) method calls the paintComponent method, forcing the application window to be redrawn
            timer = 50;
            repaint();
        }
        // Java requires that the following six methods be included in a MouseListener class, but they need
        // not have any functionality provided for them
        public void mouseExited(MouseEvent event) {}
        public void mouseEntered(MouseEvent event) {}
        public void mouseReleased(MouseEvent event) {}
        public void mousePressed(MouseEvent event) {}
        public void mouseMoved(MouseEvent event) {}
        public void mouseDragged(MouseEvent event) {}
    }

}


Describing this seemed complex, so I made a console example:

public static class SimonSays {
    private final Random r;
    private final int simonNR = 4;
    private final ArrayList<Integer> nrs = new ArrayList<Integer>();
    private final Queue<Integer> hits = new LinkedList<Integer>();

    public SimonSays(Random r, int nr) {
        this.r = r;

        for (int i = 0; i < nr - 1; i++)
            this.nrs.add(r.nextInt(this.simonNR));
    }
    private void next() {
        this.nrs.add(r.nextInt(this.simonNR));
        this.hits.clear();
        this.hits.addAll(this.nrs);
    }
    public boolean hasTargets() {
        return hits.size() > 0;
    }
    public Integer[] targets() {
        return nrs.toArray(new Integer[nrs.size()]);
    }
    public boolean hit(Integer i) {
        Integer val = hits.poll();
        if (val.compareTo(i) == 0) return true;
        return false;
    }
    public void play() {
        Scanner sc = new Scanner(System.in);
        boolean b = true;

        do {
            this.next();
            System.out.println("Simon says: " + 
                Arrays.toString(this.targets()));
            while (hasTargets()) {
                System.out.print("You say: ");
                if ((b = hit(sc.nextInt())) == false) break;
            }
        } while (b);

        System.out.println("\nYou made to size: " + this.nrs.size());
    }
}

To play : new SimonSays(new Random(/*for fixed results enter seed*/), 3).play();.

You just need to rewire play method.


Check the Javadoc for Queue

Queue (Java 2 Platform SE 5.0)

  1. Start by saving the generated sequence inside your ButtonListener. Create a Queue Inside your ButtonListener:

    Queue<Integer> generatedSequence = new Queue<Integer>();
    
  2. Populate the queue with the randoms as you generate them.

  3. Then, inside your mouseClicked event handler, pop items off of the queue and check to see if they are the same as the mouse clicked region.


I would save the generated sequence in a List. Then get an Iterator of this List. (*) Now you just compare the user input with the List item the Iterator points to. If it's different: abort, if it's the same: call next() on the iterator and repeat the process at * until you walked through the complete list. Well you could use a Queue, too as gmoore wrote. The principle remains the same, instead using an iterator you would call remove() or poll() from the queue.


You shouldn't need anything more than an ArrayList. Replace your int[] target with:

private List<Integer> targets = new ArrayList<Integer>();

When it's time to add a new random target number to the sequence use:

targets.add(new Random().nextInt(4));

For display you can get the current target number with:

int targetNum = targets.get(currTarget);

Use another variable to track the position of the user input as they play it back, e.g. int currUser. Set it to 0 each round and increment it as they get the sequence right, by checking with targets.get(currUser). You can also replace numTargets with targets.size().

When it's time to start over:

targets.clear();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜