游戏课程:
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
会更改为在marblesAmount
(removeButton
)中输入的其他值。但是while while循环仍然是一个无限循环,函数将不返回任何内容,为什么?有人可以帮忙吗?感谢。
答案 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中设置的值,如果它不是零。