2015-04-19 14 views
5

Tôi đang tạo một chương trình kéo giấy bằng đá đơn giản nhưng không chắc chắn cách đảm bảo rằng người dùng chỉ nhập một lựa chọn hợp lệ. Tôi cần để có thể reprompt chúng nếu họ không gõ một số varriant của "đá", "giấy", hoặc "kéo" (viết hoa không quan trọng) và sau đó "có" hoặc "không". Gợi ý?Làm cách nào để đảm bảo người dùng nhập một lựa chọn hợp lệ?

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

Tạo vòng lặp liên tục thu thập dữ liệu người dùng cho đến khi người đó nhập nội dung nào đó hợp lệ. Khi người dùng đã nhập câu trả lời chính xác, hãy để lại vòng lặp –

+0

@VinceEmigh làm cách nào tôi có thể thực hiện công việc này bất kể viết hoa là gì? –

+0

Sử dụng 'equalsIgnoreCase (String)' khi so sánh đầu vào của người dùng với các lựa chọn hợp lệ –

Trả lời

3

Nếu tôi được chơi một phiên họp của Roshambo chống lại máy tính, tôi muốn để có thể làm cho lựa chọn của mình bằng cách chỉ cần bạn gõ trong chữ cái đầu tiên của "Rock", "Paper" hoặc "Scissors".

Sử dụng một giàu enum là một sự lựa chọn tự nhiên ở đây:

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

Có hầu hết các chức năng mã hóa khai báo trong enum, mã khách hàng của bạn sẽ trở nên đơn giản hơn nhiều. enum cũng xử lý lựa chọn ngẫu nhiên của máy tính (ý tưởng từ câu trả lời this).

while (true) { 

     Choice choice = null; 

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

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

Bạn cũng có thể gói gọn hầu hết (nếu không phải tất cả) của logic bạn có trong phương pháp getGameOutcome, vào Choice.

5

Giữ sự lựa chọn hợp lệ trong một danh sách, vòng lặp yêu cầu đầu vào từ người sử dụng cho đến khi ông nhập một cái gì đó có giá trị.

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)); 
+0

'toLowerCase()' tạo một đối tượng 'String' mới. Có lẽ tốt nhất là chỉ cần so sánh bằng cách sử dụng 'equalsIgnoreCase' –

+0

@VinceEmigh' equalsIgnoreCase' sử dụng 'regionMatches' gọi là' toUpperCase'. –

+0

@VinceEmigh Lưu ý rằng tôi vẫn thích 'equalsIgnoreCase' vì nó có một số tối ưu hóa như kiểm tra độ dài và so sánh bằng ref cho ký tự chữ. Tuy nhiên, trong ví dụ của tôi, tôi thậm chí không sử dụng 'equals' nhưng thay vào đó hãy kiểm tra xem danh sách có chứa chuỗi không. –

1

Somesing như

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

Hoặc bạn có thể lưu trữ choises hợp lệ trong danh sách như trình bày ở trên, và sử dụng vòng lặp foreach. Nhưng nó sẽ khó khăn hơn, bởi vì bạn cần phải kiểm tra tất cả các biến thể. Có thể một cái gì đó như thế.

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

Và gọi nó là cho cả hai trường hợp:

if (!checkValid(userChoise, "rock", "papper", "scissors")) continue; 
Các vấn đề liên quan