Java textField无限循环

时间:2013-04-27 19:32:38

标签: java jtextfield infinite-loop

游戏课程:

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");



}
}

玩家类:

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类:

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


}

桩类:

公共类桩{

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

}

我想要做的是在Player类中获取函数playTurn(int pileSize)以仅在不为零时返回变量弹珠(在if(type == Type.HUMAN)块内)。 gui类中的变量marblesToRemove通过调用函数getMarblesToRemove()分配给大理石。

marblesToRemove最初在gui类的默认构造函数中设置为0,这会导致functionplayTurn(int pileSize)进入无限循环。但是,当按下按钮(marblesToRemove)时,JTextField会更改为在marblesAmountremoveButton)中输入的其他值。但是while while循环仍然是一个无限循环,函数将不返回任何内容,为什么?有人可以帮忙吗?感谢。

2 个答案:

答案 0 :(得分:2)

这可能是因为我至少可以看到两个问题。第一个是你在一个线程中修改变量,在另一个线程中读取它。这应该使用同步或其他锁定机制(Lock或AtomicInteger等)来完成。

第二个问题是你的阅读主题应该做一个'紧凑'循环。这是将一个CPU发送到100%使用率的不良做法。应该使用某种形式的通知来完成。再一次,想到了同步。

在解决这两个问题之前,您的结果总是不可靠。

对于它的价值,在你的特定情况下,如果我做出有根据的猜测,我猜想有两个重要的marblesAmount副本(并且还有多个副本)。在L1中的副本和一个CPU的寄存器正在进行紧密循环,等待该寄存器发生变化,而另一个CPU在CPU的另一个核心中将其设置为新值。除非你使用java.util.concurrent。*库中的某些同步或某些东西,否则你无法告诉该变量的一个副本来刷新另一个。

答案 1 :(得分:0)

我终于开始工作了。我刚刚添加了一行代码“System.out.print(”“);”在Player类的do-while循环中。

所以现在看起来像

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

我不知道为什么会这样,但它确实大声笑。现在函数实际返回我在JTextField中设置的值,如果它不是零。