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

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

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

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

}

Ответ 1

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

Очередь (платформа Java 2 Platform 5.0)

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

    Queue<Integer> generatedSequence = new Queue<Integer>();
    
  • Заполните очередь с помощью randoms по мере их создания.

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

Ответ 2

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

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

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

Ответ 3

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

Ответ 4

Вам не нужно ничего больше, чем 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();