如何确保用户输入有效选项?

时间:2015-04-19 23:51:25

标签: java

我正在制作一个简单的石头剪刀程序,但我不确定如何确保用户只输入有效的选择。如果他们没有输入一些" rock",#34; paper"或者"剪刀"我需要能够重新嘲笑他们。 (大写并不重要)以及之后"是"或"不"。建议?

import java.util.*;

public class RockPaperScissors {

private int wins = 0;
private int losses = 0;
private int ties = 0;

public static void main(String[] args) {
    // TODO Auto-generated method stub

    RockPaperScissors model = new RockPaperScissors();
    Scanner scan = new Scanner(System.in);

    while (true) {
        System.out.println("Rock, Paper, Scissors... Pick one! (Type Rock, Paper, or Scissors)");
        String playerChoice = scan.next();

        String computerChoice = model.getRandomChoice();

        System.out.println("You chose " + playerChoice + ".");
        System.out.println("The computer chose " + computerChoice + ".");

        RockPaperScissors.GameOutcome outcome = model.getGameOutcome(
                playerChoice, computerChoice);

        if (outcome == RockPaperScissors.GameOutcome.WIN) {
            System.out.println("You won! Congratulations");
        } else if (outcome == RockPaperScissors.GameOutcome.LOSE) {
            System.out.println("You lose! Better luck next time!");
        } else {
            System.out.println("Tie!");
        }

        System.out.print("Do you want to play again? (Yes/No):");

        String answer = scan.next();
        if (answer.equalsIgnoreCase("no")) {
            break;
        }
    }

    System.out.println("Thanks for playing!");
    System.out.println("Wins: " + model.getWins());
    System.out.println("Losses: " + model.getLosses());
    System.out.println("Ties: " + model.getTies());
    scan.close();
}

public static enum GameOutcome {
    WIN, LOSE, TIE;
}

public GameOutcome getGameOutcome(String userChoice, String computerChoice) {

    if (userChoice.equalsIgnoreCase("Rock")) {

        if (computerChoice.equalsIgnoreCase("Paper")) {
            losses++;
            return GameOutcome.LOSE;
        } else if (computerChoice.equalsIgnoreCase("Scissors")) {
            wins++;
            return GameOutcome.WIN;
        }
    } else if (userChoice.equalsIgnoreCase("Paper")) {

        if (computerChoice.equalsIgnoreCase("Scissors")) {
            losses++;
            return GameOutcome.LOSE;
        } else if (computerChoice.equalsIgnoreCase("Rock")) {
            wins++;
            return GameOutcome.WIN;
        }
    } else if (userChoice.equalsIgnoreCase("Scissors")) {
        if (computerChoice.equalsIgnoreCase("Rock")) {
            losses++;
            return GameOutcome.LOSE;
        } else if (computerChoice.equalsIgnoreCase("Paper")) {
            wins++;
            return GameOutcome.WIN;
        }
    }
    ties++;
    return GameOutcome.TIE;
}

public String getRandomChoice() {
    double d = Math.random();

    if (d < .33) {
        return "Rock";
    } else if (d < .66) {
        return "Paper";
    } else {
        return "Scissors";

    }
}

public int getWins() {
    return wins;
}

public int getLosses() {
    return losses;
}

public int getTies() {
    return ties;
}

}

3 个答案:

答案 0 :(得分:5)

将有效选项保留在列表中,循环询问用户的输入,直到他输入有效的内容。

List<String> validChoices = Arrays.asList("rock", "paper", "scissors");
Scanner sc = new Scanner(System.in);
String choice = null;
do
{
    System.out.println("Enter a choice (rock|paper|scissors)");
    choice = sc.next().toLowerCase();//Retrieve as lower case
}
while(!validChoices.contains(choice));

答案 1 :(得分:3)

如果我要对电脑玩 roshambo 会话,我希望能够只输入“Rock”,“Paper”的第一个字母或“剪刀”。

使用丰富的enum是一个很自然的选择:

private enum Choice {

    ROCK ("Rock"),
    PAPER ("Paper"),
    SCISSORS ("Scissors");

    private String displayName;

    private static final List<Choice> VALUES =
            Collections.unmodifiableList(Arrays.asList(values()));
          private static final int SIZE = VALUES.size();
    private static final Random RANDOM = new Random();        

    private Choice(String dn) {
        displayName = dn;
    }

    /**
     * Returns a random Choice.
     */
    public static Choice getRandomChoice() {
        return VALUES.get(RANDOM.nextInt(SIZE));
    }

    /**
     * Returns a Choice that matches the input string. The input is considered a match if it starts with the same character 
     * as the displayname of a Choice. If no match is found, returns null.
     */
    public static Choice fromInput(String input) {

        if (input == null || input.length() == 0) {
            return null;
        }

        for (Choice c : VALUES) {
            if (Character.toLowerCase(c.displayName.charAt(0))
                    == Character.toLowerCase(input.charAt(0))) {
                return c;
            }
        }
        return null;
    }

    /**
     * Returns the text to display to the user, asking for input to #fromInput().
     */
    public static String promptText() {
        StringBuilder sb = new StringBuilder();
        for (Choice c : VALUES) {
            if (sb.length() > 0) {
                sb.append(", ");
            }
            sb.append(c.displayName).append(" (")
                    .append(c.displayName.charAt(0)).append(")");
        }
        sb.append(". Pick one!");
        return sb.toString();
    }
}

enum中以声明方式编码大部分功能,您的客户端代码将变得更加简单。 enum还处理计算机的随机选择(来自this回答的想法)。

 while (true) {

        Choice choice = null;

        while (choice == null) {
            System.out.println(Choice.promptText());
            choice = Choice.fromInput(scan.next());
        }

        String computerChoice = Choice.getRandomChoice().displayName;
 // ...

您还可以将getGameOutcome方法中的大多数(如果不是全部)逻辑封装到Choice

答案 2 :(得分:1)

喜欢

if (!playerChoise.equalsIgnoreCase("paper") && ...) continue;

或者您可以在列表中存储有效的选择,如上所示,并使用foreach循环。但这将更加困难,因为您需要检查所有变体。也许是类似的东西。

private boolean checkValid(String userChoise, String... variants) {
    for (String s : variants) {
        if (playerChoise.equalsIgnoreCase(s)) return true;
    }
    return false;
}

并在两种情况下调用它:

if (!checkValid(userChoise, "rock", "papper", "scissors")) continue;