简体   繁体   English

Java textField无限循环

[英]Java textField infinite loop

Game class: 游戏类:

import java.util.Random;

public class Game {
public static void main(String args[]){

    //----------Sets up GUI----------

    GUI gameGUI = new GUI();
    gameGUI.setVisible(true);
    Player.setGUI(gameGUI);


    //----------Sets initial number of marbles, computer player and human player----------

    Random random = new Random();
    int initialNum;
    //loop makes sure initialNum of marbles is between 10 and 100
    do{                                 
        initialNum = random.nextInt(100);
    }while(initialNum < 10);
    //*****gameGUI.manageMarbles(initialNum, true);
    //end loop

    Pile pile = new Pile(initialNum);
    gameGUI.setPile(pile);

    int compChoice = random.nextInt(2) + 1; //number index (1 or 2) representing SIMPLE_COMPUTER or SMART_COMPUTER
    Player computer = new Player(Player.Type.values()[compChoice]);
    Player humanPlayer = new Player(Player.Type.HUMAN);


    //----------Game loop----------

    //Randomly determine first player
    Player currentPlayer;
    int playerIndex = random.nextInt(2); //will be used to determine next player in the loop
    if(playerIndex == 0){ currentPlayer = computer; }
    else { currentPlayer = humanPlayer; }

    //Loop
    while(pile.getNumMarbles() != 0){
        System.out.printf("%d marbles left.\n", pile.getNumMarbles());
        int removed = currentPlayer.playTurn(pile.getNumMarbles());
        pile.removeMarbles(removed);

        //Determine next player
        playerIndex = Math.abs(playerIndex - 1); //if playerIndex = 0, it becomes 1, and vice-versa
        if(playerIndex == 0){ currentPlayer = computer; }
        else { currentPlayer = humanPlayer; }

    }

    System.out.println(currentPlayer + " won");



}
}

Player class: 玩家类:

import java.util.Scanner;
import java.util.Random;
public class Player {

    public enum Type{HUMAN, SIMPLE_COMPUTER, SMART_COMPUTER}
    private Type type;
    static private GUI gui;

    public Player(Player.Type type){
         this.type = type;
    }

    public Player.Type getType(){
         return type;
    }

    public int playTurn(int pileSize){
          Random random = new Random();
          if(type == Type.HUMAN){

              int marbles;
          do{
             marbles = gui.getMarblesToRemove();
          }while(marbles < 0);
              return marbles;

          }

          else if(type == Type.SIMPLE_COMPUTER){
           if(pileSize == 1){
               return 1;
               }
           else{
           int remove = random.nextInt(pileSize/2) + 1;
               if(remove == (pileSize/2) + 1){ remove -= 1; }
               return remove;
               }
          }

          else if(type == Type.SMART_COMPUTER){ 
               if(pileSize == 1){
               return 1;
            }
               else if(pileSize == 3 || pileSize == 7 || pileSize == 15 || pileSize== 31 || pileSize== 63 || pileSize <= 3){
              int remove = random.nextInt(pileSize/2) + 1;
              if(remove == (pileSize/2) + 1){ remove -= 1; }
              return remove;
            }
           else{
               for(int i=1; i<=pileSize/2; i++){
                   int size = pileSize - i;
               if(size == 3 || size == 7 || size == 15 || size == 31 || size == 63){
                    return i;
                }
            }
        }
    }
    return 0;

   }


public String toString(){
    return ""+type;
}

public static void setGUI(GUI guii){
    gui = guii;
}


}

GUI class: GUI类:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class GUI extends JFrame {

  private JPanel panel;
  private JButton removeButton; //button to remove marbles
  private JTextField marblesAmount; //amount of marbles to remove
  private static final int FIELD_WIDTH = 2;
  private JLabel marblesLabel;
  private JLabel errorLabel;
  private Pile pile;
  private int marblesToRemove;
  private ClickListener listener;
  static final private int WIDTH = 700, HEIGHT = 600;

  public GUI(){
    super.setTitle("test");
    super.setSize(WIDTH, HEIGHT);
    super.setDefaultCloseOperation(EXIT_ON_CLOSE);
    panel = new JPanel();
    marblesLabel = new JLabel("How many marbles to remove?");
    errorLabel = new JLabel("");
    removeButton = new JButton("Remove");
    listener = new ClickListener();
    removeButton.addActionListener(listener);
    marblesAmount = new JTextField(FIELD_WIDTH);
    panel.add(removeButton);
    panel.add(marblesLabel);
    panel.add(marblesAmount);
    panel.add(errorLabel);
    super.add(panel);
    marblesToRemove = 0;
  }

  public void setPile(Pile pile){
    this.pile = pile;
  }



  private class ClickListener implements ActionListener{

    public void actionPerformed(ActionEvent event){
        marblesToRemove = Integer.parseInt(marblesAmount.getText());

    }
  }

  public int getMarblesToRemove(){
    return marblesToRemove;
  }


}

Pile Class: 桩类:

public class Pile { 公共类桩{

private int initialNum;
private int currentNum;

public Pile(int initialNum){
    setNumMarbles(initialNum);
    currentNum = initialNum;
}

public int getNumMarbles(){
    return currentNum;
}

public void removeMarbles(int numToRemove){
    currentNum = currentNum - numToRemove;
}

public void setNumMarbles(int amount){
    initialNum = amount;
}

public String toString(){
    return "Number of marbles: " + currentNum;
}

}

What I am trying to do is to get the function playTurn(int pileSize) in the Player class to return the variable marbles(inside the if(type == Type.HUMAN) block ) only when it is not zero. 我想要做的是在Player类中获取函数playTurn(int pileSize)以仅在它不为零时返回变量弹珠(在if(type == Type.HUMAN)块内)。 The variable marblesToRemove from the gui class is assigned to marbles, by calling the function getMarblesToRemove() . 来自gui类的变量marblesToRemove通过调用函数getMarblesToRemove()分配给大理石。

marblesToRemove is initially set to 0 in the default constructor for the gui class, and that causes the functionplayTurn(int pileSize) to go in an infinite loop. marblesToRemove最初在gui类的默认构造函数中设置为0 ,这导致functionplayTurn(int pileSize)进入无限循环。 But marblesToRemove is changed to another value that is input in a JTextField ( marblesAmount ) when aa button( removeButton ) is pressed. 但是当按下aa按钮( removeButton )时, marblesToRemove会更改为在JTextFieldmarblesAmount )中输入的另一个值。 But the the do while loop will still be an infinite loop and the function will return nothing, why? 但是while while循环仍然是一个无限循环,函数将不返回任何内容,为什么? Can someone please help? 有人可以帮忙吗? Thanks. 谢谢。

This is probably because of at least two issues that I can see. 这可能是因为我可以看到至少两个问题。 The first is that you are modifying the variable in one thread, and reading it in the other. 第一个是你在一个线程中修改变量,在另一个线程中读取它。 This should be done using either synchronization, or some other locking mechanism (Lock or AtomicInteger, etc.). 这应该使用同步或其他锁定机制(Lock或AtomicInteger等)来完成。

The second issue is that your reading-thread should not be doing a 'tight' loop. 第二个问题是你的阅读线程应该做一个“紧”循环。 This is bad practices that sends one CPU to 100% usage. 这是将一个CPU发送到100%使用率的不良做法。 It should be done using some form of notification. 应该使用某种形式的通知来完成。 Again, synchronization comes to mind. 再次,同步浮现在脑海中。

Until you fix these two issues, you will always have unreliable results. 在解决这两个问题之前,您将始终获得不可靠的结果。

For what it's worth, in your particular case, if I were to make an educated guess, I would guess that there are two important copies of the marblesAmount (and there are alsways multiple copies). 对于它的价值,在你的特定情况下,如果我做出有根据的猜测,我猜想有两个重要的marblesAmount副本(并且还有多个副本)。 There's the copy thati's in the L1 and registers of one CPU that's doing a tight loop waiting for that register to change, and the other is in another core on your CPU setting it to a new value. 在L1中的副本和一个CPU的寄存器正在进行紧密循环,等待该寄存器发生变化,而另一个CPU在CPU的另一个核心中将其设置为新值。 Unless you use some synchronization, or somethin from the java.util.concurrent.* library you ave no way to tell one copy of the variable to refresh the other. 除非你使用java.util.concurrent。*库中的某些同步或某些东西,否则你无法告诉变量的一个副本来刷新另一个。

I got it to work finally. 我终于开始工作了。 I just added a line of code "System.out.print("");" 我刚刚添加了一行代码“System.out.print(”“);” in the do-while loop in the Player class. 在Player类的do-while循环中。

So now it looks like 所以现在看起来像

 do{
         marbles = gui.getMarblesToRemove();
         System.out.print("");
      }while(marbles < 0); 

I have no idea why that works, but it does lol. 我不知道为什么会这样,但它确实大声笑。 Now the function actually returns the value that I set in the JTextField if it is not zero. 现在函数实际返回我在JTextField中设置的值,如果它不是零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM