Ява Саймон говорит - PullRequest
       13

Ява Саймон говорит

12 голосов
/ 27 марта 2011

В настоящее время у меня есть графический интерфейс, созданный для игры «Симон говорит», единственная проблема, с которой я сталкиваюсь, - реализация логики игры (мой текущий код будет генерировать последовательность и отображать пользовательский ввод, но не будет сохранять сгенерированную последовательность, или сравните это с входом). Я знаю, что должен использовать очередь или стек, но я не могу понять, как реализовать любой из них, чтобы сделать работающую игру.

Может кто-нибудь помочь, вот что я получил до сих пор:

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

«Панель локаций» (Саймон говорит игровую логику):

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 ]

6 голосов
/ 30 марта 2011

Описание этого показалось сложным, поэтому я сделал пример консоли:

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

Вам просто нужно изменить метод игры.

5 голосов
/ 28 марта 2011

Проверьте Javadoc для очереди

Очередь (Java 2 Platform SE 5.0)

  1. Начните с сохранения сгенерированной последовательности внутри вашего ButtonListener. Создайте очередь внутри вашего ButtonListener:

    Queue<Integer> generatedSequence = new Queue<Integer>();
    
  2. Заполните очередь случайными числами по мере их создания.

  3. Затем, внутри вашего mouseClicked обработчика событий, вытолкните элементов из очереди и проверьте, совпадают ли они с областью, по которой щелкнули мышью.

4 голосов
/ 28 марта 2011

Я бы сохранил сгенерированную последовательность в List. Затем получите Iterator этого списка. (*) Теперь вы просто сравниваете пользовательский ввод с элементом списка, на который указывает итератор. Если он другой: прервать, если он тот же: вызвать next() на итераторе и повторять процесс до *, пока вы не пройдете весь список Ну, вы могли бы использовать Queue, как писал gmoore. Принцип остается тем же, вместо этого используя итератор, который вы бы назвали remove() или poll() из очереди.

3 голосов
/ 30 марта 2011

Вам не нужно ничего больше, чем ArrayList.Замените ваш int[] target на:

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

Когда пришло время добавить новый случайный целевой номер в последовательность, используйте:

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

Для отображения вы можете получить текущий целевой номер с помощью:

int targetNum = targets.get(currTarget);

Используйте другую переменную для отслеживания позиции пользовательского ввода при его воспроизведении, например, int currUser.Установите его равным 0 в каждом раунде и увеличивайте по мере правильной последовательности, проверяя с помощью targets.get(currUser).Вы также можете заменить numTargets на targets.size().

Когда пришло время начать все сначала:

targets.clear();
...