Java西蒙说

时间:2011-03-27 00:13:35

标签: java stack queue

我目前有一个用于simon游戏的GUI,我唯一的问题是实现游戏逻辑(我当前的代码将生成一个序列并显示用户输入,但不会保存生成的序列,或者将它与输入进行比较)。我知道我必须使用队列或堆栈,但我无法弄清楚如何实现其中任何一个来制作一个有效的游戏。

有人可以帮忙,这是我到目前为止所得到的:

驱动:

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);
   }
}

“位置面板”(Simon说游戏逻辑):

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 area 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) {}
    }

}

4 个答案:

答案 0 :(得分:6)

描述这看起来很复杂,所以我做了一个控制台示例:

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());
    }
}

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

你只需要重新连接播放方法。

答案 1 :(得分:5)

检查Javadoc for Queue

Queue (Java 2 Platform SE 5.0)

  1. 首先将生成的序列保存在ButtonListener中。在ButtonListener

    中创建一个队列
    Queue<Integer> generatedSequence = new Queue<Integer>();
    
  2. 在生成队列时使用randoms填充队列。

  3. 然后,在您的mouseClicked事件处理程序中,弹出项目离开队列并检查它们是否与鼠标单击区域相同。

答案 2 :(得分:4)

我会将生成的序列保存在List中。然后获得此列表的Iterator。 (*)现在,您只需将用户输入与Iterator指向的List项进行比较。如果不同:abort,如果它是相同的:在迭代器上调用next()并在*处重复该过程,直到您完成整个列表。 好吧,你可以使用Queue,就像gmoore写的那样。原则保持不变,而是使用迭代器,您可以从队列中调用remove()poll()

答案 3 :(得分:3)

您不应该只需要ArrayList以外的任何内容。将int[] target替换为:

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

当需要为序列添加新的随机目标编号时:

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

要显示,您可以通过以下方式获取当前目标号码:

int targetNum = targets.get(currTarget);

使用另一个变量来跟踪用户输入回放时的位置,例如int currUser。通过检查targets.get(currUser),每轮将其设置为0并在序列正确时将其递增。您也可以将numTargets替换为targets.size()

什么时候重新开始:

targets.clear();