java - 石头剪刀布 Java 游戏

标签 java loops while-loop nested-loops

我的任务是编写一个程序,让用户与计算机玩石头、剪刀、布的游戏。

说明:

主方法应该有两个嵌套循环,其中外循环将允许用户根据需要经常玩游戏,而内循环将在出现平局时玩游戏。在 userChoice() 方法中的 while 循环中调用 isValidChoice() 方法来验证用户输入的选择必须是“石头”、“布”或“剪刀”。如果输入无效的字符串,isValidChoice()将返回 false,程序应要求新的输入,直到给出有效的输入。

情况:

当用户输入有效的输入时,程序运行正常。然而,一旦它不是有效的输入,就会出现一个小问题。

结果:

Enter rock, paper, or scissors: rocky
Invalid input, enter rock, paper, or scissors: roc
Invalid input, enter rock, paper, or scissors: rock
The computer's choice was paper
The user's choice was rocky

Play again? (y/n)

如您所见,程序识别出无效输入。用户最终输入了有效的 第三次输入。然而,它显示用户的第一选择“rocky”,这是无效的。 因此程序无法显示谁获胜。

问题

我需要你的帮助。
我希望我的程序像这样运行: 当用户输入多次无效输入,但一次 输入有效的输入,我的程序应该仍然能够显示用户的有效输入并显示获胜者。

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

public class RockPaperScissorsGame 
{
   public static void main (String[] args)
   {
      Scanner keyboard = new Scanner(System.in);

      String computer, user;
      char keepPlaying;

      do 
      {
         computer = computerChoice();
         user = userChoice();

         System.out.println("The computer's choice was " + computer);
         System.out.println("The user's choice was " + user);

         determineWinner(computer, user);

         while (computer.equals(user))
         {
            computer = computerChoice();
            user = userChoice();

            System.out.println("The computer's choice was " + computer);
            System.out.println("The user's choice was " + user);

            determineWinner(computer, user);
         }


         System.out.println("\n" + "Play again? (y/n)");
         keepPlaying = keyboard.nextLine().toLowerCase().charAt(0);

         while ( keepPlaying != 'y' && keepPlaying != 'n' )
         {
            System.out.println("Invalid input, please enter (y/n)");
            keepPlaying = keyboard.nextLine().toLowerCase().charAt(0);
         }

      } while (keepPlaying == 'y');

   }
   public static String computerChoice()
   {
      String[] choice = {"rock","paper","scissors"};
      Random rand = new Random();
      int computerChoice = rand.nextInt(3);
      return choice[computerChoice];
   }
   public static String userChoice()
   {
      Scanner keyboard = new Scanner(System.in);
      System.out.print("Enter rock, paper, or scissors: ");
      String choice = keyboard.nextLine();

      isValidChoice(choice);
      return choice;
   }
   public static boolean isValidChoice (String choice)
   {
      Scanner keyboard = new Scanner(System.in);

      while (!(choice.equalsIgnoreCase("rock")) && !(choice.equalsIgnoreCase("paper")) && !(choice.equalsIgnoreCase("scissors")))
    {
       System.out.print("Invalid input, enter rock, paper, or scissors: ");
       choice = keyboard.nextLine();
    }

       return true;
    }
    public static void determineWinner(String computer, String user)
    {
       if (computer.equalsIgnoreCase("rock") && user.equalsIgnoreCase("paper"))
          System.out.println("\n" + "Paper wraps rock.\nThe user wins!");
       else if (computer.equalsIgnoreCase("rock") && user.equalsIgnoreCase("scissors"))
          System.out.println("\n" + "Rock smashes scissors.\nThe computer wins!");
       else if (computer.equalsIgnoreCase("paper") && user.equalsIgnoreCase("rock"))
          System.out.println("\n" + "Paper wraps rock.\nThe computer wins!");
       else if (computer.equalsIgnoreCase("paper") && user.equalsIgnoreCase("scissors"))
          System.out.println("\n" + "Scissors cuts paper.\nThe user wins!");
       else if (computer.equalsIgnoreCase("scissors") && user.equalsIgnoreCase("rock"))
          System.out.println("\n" + "Rock smashes scissors.\nThe user wins!");
       else if (computer.equalsIgnoreCase("scissors") && user.equalsIgnoreCase("paper"))
          System.out.println("\n" + "Scissors cuts paper.\nThe computer wins!");
       else if (computer.equalsIgnoreCase(user))
          System.out.println("\n" + "The game is tied!\nGet ready to play again...");
    }   
}

最佳答案

这个问题是由于 Java 是按值传递,而不是按引用传递。

换句话讲,传递的不是参数的引用,而是参数的副本。您的方法更改了副本,但一旦方法结束,副本就会超出范围并被垃圾收集。

当您将 choice 传递到 isvalidChoice 时,不会传递对 choice 本身的引用。制作字符串的副本,然后传递。当您更新变量选择时,它不会更改原始字符串,而是更改系统创建的副本。 This answer explains how it works pretty well.

那么你应该做什么?

如果不是有效输入,则 isValidChoice 返回 false,而不是在 isValidChoice 中循环。

您的 isValidChoice 最终应如下所示:

public static boolean isValidChoice(String choice) {
    return (choice.equalsIgnoreCase("rock")) || (choice.equalsIgnoreCase("paper")) || (choice.equalsIgnoreCase("scissors"));
}

然后在userChoice中执行类似的操作

Scanner keyboard = new Scanner(System.in);
while(!isValidChoice(choice)) {
    System.out.print("Invalid input, enter rock, paper, or scissors: ");
    choice = keyboard.nextLine();
}

关于java - 石头剪刀布 Java 游戏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26984597/

相关文章:

Java GPA 计算器循环

Java 使用两个循环

c# - 并非所有代码路径在循环时都返回值

java - 如何将嵌套循环插入到2个while循环中

java - 玩!没有正确关闭 H2

java - JAXB 混合内容列表包含换行符

php和mysql foreach只显示第一条记录四次

loops - Haskell中的while循环有条件

java - 无法使用 FileWriter 和 Printwriter 在文本文件中写入文本

java - FlowLayout 包装在嵌套的 JPanel 中不起作用