【问题标题】:Infinite while loop and counting for loop errors in javajava中的无限while循环和循环错误计数
【发布时间】:2015-11-04 03:22:17
【问题描述】:

我正在尝试创建游戏 nim。我这样做是为了让计算机可以从随机行中随机抽取 1-3 张牌。不是电脑会做,但是当只剩下一三张牌时,它会无限循环。

主文件。不需要碰

package nimgame;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
 *
 * @author Angela
 */
public class NimApp extends JFrame implements ActionListener {

    private static final int ROWS = 3;
    private JTextField[] gameFields; // Where sticks for each row shown
    private JTextField rowField;     // Where player enters row to select
    private JTextField sticksField;  // Where player enters sticks to take
    private JButton playButton;      // Pressed to take sticks
    private JButton AIButton;        // Pressed to make AI's move

    private NimGame nim;

    public NimApp() {

        // Build the fields for the game play 
        rowField = new JTextField(5);
        sticksField = new JTextField(5);
        playButton = new JButton("PLAYER");
        AIButton = new JButton("COMPUTER");
        playButton.addActionListener(this);
        AIButton.addActionListener(this);
        AIButton.setEnabled(false);

        // Create the layout
        JPanel mainPanel = new JPanel(new BorderLayout());
        getContentPane().add(mainPanel);

        JPanel sticksPanel = new JPanel(new GridLayout(3, 1));
        mainPanel.add(sticksPanel, BorderLayout.EAST);

        JPanel playPanel = new JPanel(new GridLayout(3, 2));
        mainPanel.add(playPanel, BorderLayout.CENTER);

        // Add the fields to the play panel
        playPanel.add(new JLabel("Row: ", JLabel.RIGHT));
        playPanel.add(rowField);
        playPanel.add(new JLabel("Sticks: ", JLabel.RIGHT));
        playPanel.add(sticksField);
        playPanel.add(playButton);
        playPanel.add(AIButton);

        // Build the array of textfields to display the sticks
        gameFields = new JTextField[ROWS];
        for (int i = 0; i < ROWS; i++) {
            gameFields[i] = new JTextField(10);
            gameFields[i].setEditable(false);
            sticksPanel.add(gameFields[i]);
        }
        setSize(350, 150);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        nim = new NimGame(new int[]{3, 5, 7});
        draw();
    }

    // Utility function to redraw game
    private void draw() {
        for (int row = 0; row < ROWS; row++) {
            String sticks = "";
            for (int j = 0; j < nim.getRow(row); j++) {
                sticks += "|   ";
            }
            gameFields[row].setText(sticks);
        }
        rowField.setText("");
        sticksField.setText("");
    }

    public void actionPerformed(ActionEvent e) {

        // Player move
        if (e.getSource() == playButton) {

            // Get the row and number of sticks to take
            int row = Integer.parseInt(rowField.getText())-1;
            int sticks = Integer.parseInt(sticksField.getText());

            // Play that move
            nim.play(row, sticks);

            // Redisplay the board and enable the AI button
            draw();
            playButton.setEnabled(false);
            AIButton.setEnabled(true);

            // Determine whether the game is over
            if (nim.isOver()) {
                JOptionPane.showMessageDialog(null, "You win!");
                playButton.setEnabled(false);
            }
        }

        // Computer move
        if (e.getSource() == AIButton) {

            // Determine computer move
            nim.AIMove();

            // Redraw board
            draw();
            AIButton.setEnabled(false);
            playButton.setEnabled(true);

            // Is the game over?
            if (nim.isOver()) {
                JOptionPane.showMessageDialog(null, "You win!");
                playButton.setEnabled(false);
            }
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        NimApp a = new NimApp();
    }
}

这是主文件的支持类

package nimgame;
import java.util.Random;
/**
 *
 * @author Angela
 */
public class NimGame { 
     int[] Sticks; //creating an array of sticks
     int totalSticks=0;

    public NimGame(int[] initialSticks){
    Sticks = initialSticks;}

    public int getRow(int r){
        return Sticks[r];}

    public void play(int r, int s){
    Sticks[r]=Sticks[r]-s;}

这应该计算板上剩下的所有棍子。如果剩下一根棍子,它应该返回真,如果板上有不止一根棍子,它应该返回假。我在使用 for 循环并使其正确计算棒数时遇到问题。

public boolean isOver(){
    int theTotal = 0;
    for (int i =1; i<Sticks.length; i++){
         theTotal = totalSticks + Sticks[i];
            System.out.println(totalSticks);}
       totalSticks = theTotal;
       System.out.println(totalSticks);
        if (totalSticks<=1){
            return true;
        }
        return false;

此方法应该随机生成一行和一定数量的棍子以供计算机丢弃。这就是我得到无限循环的地方。

public void AIMove(){
    Random randomInt = new Random ();
    int RandomRow = randomInt.nextInt(3);
    int RandomDiscard = randomInt.nextInt(3-0)+1;
    int randomize=0;



    while (RandomDiscard >Sticks[RandomRow] && totalSticks>1){
        RandomRow = randomInt.nextInt(3);
        RandomDiscard = randomInt.nextInt(3-0)+1;
        Sticks[RandomRow]=Sticks[RandomRow]-RandomDiscard;
        randomize = 1;}

    if (randomize==0)
    Sticks[RandomRow]=Sticks[RandomRow]-RandomDiscard;

    if (totalSticks <= 1){
    Sticks[RandomRow]=Sticks[RandomRow]-1;}
    isOver();
    }

            }

【问题讨论】:

  • 你想用randomInt.nextInt(3-0)+1做什么?此外,您似乎在比较 RandomDiscard(and 也 modifying 它以及您在循环中比较的内容)。我认为您想注释掉该 while 循环的前两行。但我不确定,因为我不知道你在做什么。
  • 对于 randomint (3-0)+1 我得到 1-3 之间的随机数。在循环中,我需要检查我取出的数字(随机丢弃)是否大于我在行中的数字。如果它大于我需要选择一个新的随机新丢弃物和一个新的随机行

标签: java loops for-loop infinite-loop counting


【解决方案1】:

终止while 循环的条件是当循环主体上有RandomDiscard &gt; Sticks[RandomRow] 或totalSticks&gt;1 时Sticks[RandomRow] 的值至少小1,保持条件不变。

要在主体上中断循环,您需要增加 Sticks[RandomRow] 或减少 totalSticks 或将条件更改为 RandomDiscard &lt; Sticks[RandomRow] || totalSticks&gt;1

编辑(晚上 10 点 18 分): 查看问题和解决方案,我得到了解决问题的更好方法,这就是我所做的:

public void AIMove(){
    Random randomInt = new Random ();

    boolean tryRemove =  true;

    while(tryRemove && totalSticks > 1){
        int RandomRow = randomInt.nextInt(3);
        if(Sticks[RandomRow] <= 0)//the computer can't remove from this row
            continue;

        //the max number to remove from row
        int size = 3;
        if( Sticks[RandomRow] < 3)//this row have lest that 3 cards
            size = Sticks[RandomROw];//make the max number to remove from the row be the number of cards on the row 
        int RandomDiscard = randomInt.nextInt(size) + 1;
        Sticks[RandomRow] = Sticks[RandomRow] - RandomDiscard;
        //I don't know if this is needed, but since we remove a RandomDiscard amount lest decrease the totalSticks
        totalSticks = totalSticks - RandomDiscard;
        //exit loop
        tryRemove = false;
    }

    if(totalSticks <= 1){
        Sticks[RandomRow]=Sticks[RandomRow]-1;
        isOver();
    }


}

我所做的是将随机循环和 if 语句组合在一个循环中。

【讨论】:

    【解决方案2】:
    theTotal = totalSticks + Sticks[i];
    

    应该是

    theTotal = theTotal + Sticks[i];
    

    另外,for 循环可能应该从索引 0 而不是 1 开始:

    for (int i =1; i<Sticks.length; i++){
    

    【讨论】:

    • 谢谢!你能明白我为什么陷入无限循环吗??
    猜你喜欢
    • 2014-03-29
    • 1970-01-01
    • 2015-06-25
    • 2012-12-24
    • 2018-04-13
    • 2013-02-22
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多