无限 while 循环并计算 java 中的循环错误

Infinite while loop and counting for loop errors in java

我正在尝试创建游戏 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();
    }
}

这是对主文件class的支持

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

这应该是计算板上剩余的所有木棍。如果还剩 1 根棍子,它应该 return 为真,如果棋盘上有一根以上的棍子,它应该为假。我在使用 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();
    }

            }
theTotal = totalSticks + Sticks[i];

应该是

theTotal = theTotal + Sticks[i];

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

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

终止 while 循环的条件是当你在循环主体上有 RandomDiscard > Sticks[RandomRow]totalSticks>1Sticks[RandomRow] 的值至少变小一、保持​​状态。

要在主体上打破循环,您需要增加 Sticks[RandomRow] 或减少 totalSticks 或将条件更改为 RandomDiscard < Sticks[RandomRow] || totalSticks>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 语句组合在一个循环中。