我有一项创建game of Nim的作业。
我创建了两个类,一个用于游戏:
import java.util.*;
/**
*
* @author Surge
*/
public class Nim implements InteractiveGame
{
private int pilesize;
private boolean playSmart; //true iff the computer plays smart
private boolean playersTurn; //true iff it is the human player’s turn to move
private String gameRecord; //Complete history of the game’s progression
public Nim(boolean playSmart, boolean playerFirst)
{
this.playSmart = playSmart;
this.playersTurn = playerFirst;
pilesize = (int)((Math.random() * 91) + 10);
this.gameRecord = " Marble Game";
}
@Override
public boolean isCompleted()
{
return pilesize == 0;
}
@Override
public boolean isValidMove(String move)
{
try
{ //Interpret move as an integer, check if in range
int number = Integer.parseInt(move);
return number >= 1 && number <= pilesize / 2 ;
}
catch (NumberFormatException nfex)
{ //The move could not be parsed as an integer
return false;
}
}
@Override
public boolean isPlayersTurn()
{
return this.playersTurn;
}
@Override
public void makePlayersMove(String move)
{
Scanner input = new Scanner(System.in);
int marbles_to_remove = input.nextInt();
this.gameRecord = "How many marbles do you want to remove:";
while ((marbles_to_remove != 1) && (marbles_to_remove <= 0 || marbles_to_remove > pilesize / 2))
playersTurn = false;
pilesize -= marbles_to_remove;
}
@Override
public void makeComputersMove() {
while (pilesize > 0)
{
System.out.println("Current number of marlbes in pile: " + pilesize);
int marbles_to_remove = 0;
if (!playersTurn) {
if (playSmart || (pilesize == 1 || pilesize == 3
|| pilesize== 7 || pilesize == 15 || pilesize == 31
|| pilesize == 63)) {
marbles_to_remove = (int) (Math.random() * (pilesize / 2 + 1)) + 1;
}
else {
if (pilesize > 63) {
marbles_to_remove = pilesize - 63;
}
else if (pilesize > 31) {
marbles_to_remove = pilesize - 31;
}
else if (pilesize > 15) {
marbles_to_remove = pilesize - 15;
}
else if (pilesize > 7) {
marbles_to_remove = pilesize - 7;
}
else if (pilesize > 3) {
marbles_to_remove = pilesize - 3;
}
else {
marbles_to_remove = pilesize - 1;
}
}
System.out.println("Computer removes " + marbles_to_remove + " marble" + ((marbles_to_remove > 1)? "s": ""));
playersTurn = true;
}
}
}
@Override
public boolean playerHasWon()
{
boolean win = false;
if(pilesize == 1 && !playersTurn)
win = true;
return win;
}
@Override
public String movePrompt()
{
return this.gameRecord + "\nGuess a number";
}
}
和另一个客户:
public class InteractiveGamePlayer
{
//Play a series of two-person Interactive Games
// between a HUMAN player and the COMPUTER Player
public static void main(String[] args)
{
InteractiveGame game;
do
{
game = promptForGame();
if (game != null)
play( game );
} while ( game != null );
}
//Prompt the HUMAN Player for the name of the game and its parameters:
// 1) COMPUTER plays smart 2) HUMAN plays first
//Returns a new instance of the selected game, null if the HUMAN quits
private static InteractiveGame promptForGame()
{
Object[] gameOptions = {"GUESS", "NIM"};
String gameName = (String)JOptionPane.showInputDialog(null,
"Choose a game, or CANCEL", "GAME MENU",
JOptionPane.INFORMATION_MESSAGE, null,
gameOptions, gameOptions[0] );
if ( gameName != null )
{ //Allow the Human Player to select the game options
boolean smartMode = gameOption("Computer plays SMART?") ;
boolean playFirst = gameOption("Will YOU play FIRST?") ;
switch ( gameName ) //Return the selected game
{
case "GUESS" : return new GuessingGame(smartMode, playFirst );
case "NIM" : return new Nim(smartMode, playFirst);
}
}
return null;
}
//The HUMAN Palyer selects a game option
private static boolean gameOption(String prompt)
{
return JOptionPane.showConfirmDialog(null, prompt) == JOptionPane.YES_OPTION;
}
//Play a selected 2-person game by alternating turns
// between the HUMAN Player and the COMPUTER Player
private static void play(InteractiveGame game)
{
while ( !game.isCompleted() )
if ( game.isPlayersTurn() )
game.makePlayersMove( promptForMove(game) );
else
game.makeComputersMove();
String message = game + "\n\n" +
(game.playerHasWon() ? "Well Done!" : "Hard Luck!") ;
JOptionPane.showMessageDialog(null, message);
}
//Prompt the HUMAN Player to enter their next move
// The prompt is repeated until a legal move is entered
private static String promptForMove(InteractiveGame game)
{
String prompt = game.movePrompt() + " ?";
do
{
String playersMove = JOptionPane.showInputDialog( null, prompt );
if ( game.isValidMove( playersMove ) )
return playersMove;
prompt += "\n" + playersMove + " is INVALID";
} while ( true );
}
}
但是当我运行我的程序时,无论输入什么输入,我都没有输出。该程序只是空白输出无限运行。我究竟做错了什么? movePrompt方法也有这些规范 玩家移动的提示必须包括游戏当前状态的清晰表示;提示必须显示足够的信息,以允许玩家决定他们的下一步行动。假设人类玩家不熟悉Nim。必须使用JOptionPane方法实现提示。
答案 0 :(得分:0)
至少makePlayersMove(...)
方法中的这个构造很容易创建一个无限循环:
while ((marbles_to_remove != 1) && (marbles_to_remove <= 0 || marbles_to_remove > pilesize / 2))
playersTurn = false;
由于marbles_to_remove
的值永远不会在循环内部发生变化,如果满足循环条件一次,它将被无限次地满足。
你应该扩展循环以不断询问用户新的输入(现在它只在循环外被询问一次),直到输入在定义的参数范围内。
同样,makeComputersMove(...)
中的while循环变为无限循环,因为循环条件为while (pilesize > 0)
且pilesize
在循环内不会发生变化。因此,如果它在进入循环时高于零,它将永远保持在零以上。如果您只希望计算机一次进行一次移动,请不要理解为什么需要循环。