Using a do-while to restart a game in java

2019-09-06 19:17发布

问题:

Please help with the swtich case need for a game

public static void main(String[] args) {

Scanner input = new Scanner(System.in);
System.out.print("Please Enter a number");
int day = input.nextInt();

switch(day)
{
case 1: System.out.println("1 Microphone");
break;
case 2: System.out.println("2 Loud Speakers 1 Microphone ");
break;
case 3: System.out.println("3 Keyboards  2 Loudspeakers 1 Microphone ");
break;
case 4: System.out.println("4 Java Books 3 Keyboards  2 Loudspeakers 1 Microphone");
break;
case 5: System.out.println("5 Iphones 4 Java Books 3 Keyboards  2 Loudspeakers 1 Microphone");
break;

default: System.out.println("Enter A Valid Prize Day");

}

}

回答1:

As @AlexandreSantos pointed out, you need to reinitialise the values of maxRolls and sum every time you restart the game. That is, these initialisations should be the first things executed in your do {} while () loop.

do {
    int maxRolls = 7;
    int sum = 0;

    // ... 

} while (option);

I'd also give you other recommendations:

  • in Java, the class names, by convention, start with an upper-case letter. Thus, I'd name your class Game instead of game.

The following code (and its equivalent with "no"):

(userInputTwo.equals("Yes") || userInputTwo.equals("yes") || userInputTwo.equals("YES"))

... can be replaced by:

userInputTwo.equalsIgnoreCase("yes")

... since, as you mentioned in your question, you're actually simply trying to ignore the case ;)

  • You're doing all that asking the user whether is wants to restart or not in two places. You could (should) actually simply do it once, after having printed either "You won" or "You lost".

I'd suggest to replace:

if (sum >= 43) {
    System.out.println("You Win");
    System.out.print("Would You Like To Play Again . Yes or No?");
    final String userInput = input.nextLine();
    if (userInput.equals("Yes") || userInput.equals("yes") || userInput.equals("YES")) {
        // MISSING CODE TO RESTART THE PROGRAM
        option = true;
    } else if (userInput.equals("No") || userInput.equals("no") || userInput.equals("NO")) {
        System.exit(0);
    }
}
if (sum < 43 || sum % 10 == 0) {
    System.out.println("You Lose");
    System.out.print("Would You Like To Play Again . Yes or No?");
    final String userInputTwo = input.nextLine();
    if (userInputTwo.equals("Yes") || userInputTwo.equals("yes") || userInputTwo.equals("YES")) {
        option = true;
        // MISSING CODE TO RESTART THE PROGRAM
    } else if (userInputTwo.equals("No") || userInputTwo.equals("no") || userInputTwo.equals("NO")) {
        System.exit(0);
    }
}

... by:

if (sum >= 43) {
    System.out.println("You Win");
}

if (sum < 43 || sum % 10 == 0) {
    System.out.println("You Lose");
}

System.out.print("Would You Like To Play Again . Yes or No?");
final String userInput = input.nextLine();
if ("yes".equalsIgnoreCase(userInput) {
    // MISSING CODE TO RESTART THE PROGRAM
    option = true;
} else if ("no".equalsIgnoreCase(userInput)) {
    System.exit(0);
}

... or, even better, extracting this into an other method.

Or, even better, not even checking for one of the possibilities and make it the default one, in case the user enters something that's neither "yes" nor "no":

private static boolean restart(final Scanner input) {
    // I choose to interpret any input that's different from "yes" as a "no".
    System.out.print("Would You Like To Play Again. Yes or No? (default: No)");
    final String userInput = input.nextLine();
    if ("yes".equalsIgnoreCase(userInput)) {
        return true;
    }

    return false;
}

... which can obviously then become:

private static boolean restart(final Scanner input) {
    // I choose to interpret any input that's different from "yes" as a "no".
    System.out.print("Would you like to play again? [Yes/No] (default: No)");
    return "yes".equalsIgnoreCase(input.nextLine());
}

... and the option variable could disappear:

do {
   ...
} while (Game.restart(input));
  • You could (should) use Random instead of Math.random(), it's just way more convenient.

For example:

final int dieOne = (int) (Math.random() * faces) + 1;
final int dieTwo = (int) (Math.random() * faces) + 1;
final int totalRollForRound = dieOne + dieTwo;

... could become:

// Outside of the do {} while ():
final Random r = new Random();

// Inside the do {} while ():
final int totalRollForRound = r.nextInt(faces) + r.nextInt(faces) + 2;
  • You should always close the Scanner before leaving the program.

Use the try-with-resources syntax:

private static boolean restart() {
    try (final Scanner input = new Scanner(System.in) {
        // I choose to interpret any input that's different from "yes" as a "no".
        System.out.print("Would you like to play again? [Yes/No] (default: No)");
        return "yes".equalsIgnoreCase(input.nextLine());
    }
}
  • One last thing: your sum % 10 == 0 is weird: you've already told the user that he won if he scored at least 43, and he's gonna lose if he scored less than 43... You should either:

Test that condition before checking whether the user has scored more than 43 (and therefore also rejecting scores like 50, 60, 70, 80...)

... or:

Forget about that rule that only aims to reject 10, 20, 30 and 40, which are already covered by the score < 43 rule.

Cheers ;)


Just 'cause I felt bored, I actually applied my own advices (and a few more) to your code:

import java.util.Random;
import java.util.Scanner;

public class Game {

    private static final int FACES = 6;
    private static final int MAX_ROLLS = 7;
    private static final Random R = new Random();

    public static void main(final String[] args) {
        try (final Scanner input = new Scanner(System.in)) {
            do {
                if (Game.roll() >= 43) {
                    System.out.println("You won!");
                } else {
                    System.out.println("You lost.");
                }
            } while (Game.restart(input));
        }
    }

    private static int roll() {
        int maxRolls = MAX_ROLLS;
        int sum = 0;

        for (int i = 1; i < maxRolls; i++) {
            final int dieOne = R.nextInt(FACES) + 1;
            final int dieTwo = R.nextInt(FACES) + 1;
            sum += dieOne + dieTwo;
            System.out.println("Roll #" + i + ": You rolled " + dieOne + " and " + dieTwo + ".\tYour new total is: " + sum);

            if (dieOne == dieTwo) {
                System.out.println("DOUBLES! You get an extra roll.");
                maxRolls++;
            }
        }

        return sum;
    }

    private static boolean restart(final Scanner input) {
        System.out.print("Play again? [Yes/No] (default: No): ");
        return "yes".equalsIgnoreCase(input.nextLine());
    }
}


回答2:

Sounds like you want an outer loop; each time through the loop the user plays one game. At the top of that loop, you initialize the values that you need to play one game:

boolean playingMoreGames = false;
do
{
  int sum = 0;
  int maxRolls = 6;
  int rollsMade = 0;
  boolean gameOver = false;
  do
  { 
    // roll dice
    // determine win or loss
    // and determine whether game is over
    // include testing rollsMade against maxRolls
  }
  while (!gameOver)
  // ask user whether he wants to play again and set playingMoreGames accordingly
}
while (playingMoreGames);

I have suggested a change to a while loop that executes as long as the maxRolls has not been reached. It is not a good idea to modify the target of a for loop within the loop; in some languages, at least, the behavior is undefined, and it confuses the reader. Since maxRolls can change, you need a different looping form there.

And you don't really need to call System.exit(); if you "fall out of" the bottom of your main routine, your program will just exit since it has no more instructions to execute.

I don't recommend do while(true) in this case; the (small) problem with it is that it makes it harder for the reader to determine when the loop exits. Not a big deal.

Good luck.