我目前有一个用于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) {}
}
}
答案 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)
首先将生成的序列保存在ButtonListener
中。在ButtonListener
:
Queue<Integer> generatedSequence = new Queue<Integer>();
在生成队列时使用randoms填充队列。
然后,在您的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();