0

游戏类:

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


}

图形界面类:

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(intileSize) 仅在变量不为零时返回变量 marbles(在 if(type == Type.HUMAN) 块内)。gui 类中的变量marblesToRemove通过调用函数分配给弹珠getMarblesToRemove()

marblesToRemove最初0在 gui 类的默认构造函数中设置为,这会导致函数 playTurn(int pileSize) 进入无限循环。但是当按 aa button( ) 时更改为在 a ( )marblesToRemove中输入的另一个值。但是 do while 循环仍然是一个无限循环,函数什么也不返回,为什么?有人可以帮忙吗?谢谢。JTextFieldmarblesAmountremoveButton

4

2 回答 2

2

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

第二个问题是你的阅读线程应该做一个“紧密”的循环。这是使一个 CPU 达到 100% 使用率的不良做法。应该使用某种形式的通知来完成。再次,同步浮现在脑海中。

在您解决这两个问题之前,您将始终得到不可靠的结果。

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

于 2013-04-27T19:52:24.163 回答
0

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

所以现在看起来像

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

我不知道为什么会这样,但确实如此。现在该函数实际上返回我在 JTextField 中设置的值(如果它不为零)。

于 2013-04-27T21:21:52.353 回答