Java代码打印异常中给出的消息,即使条件为';这不是真的

Java代码打印异常中给出的消息,即使条件为';这不是真的,java,illegalargumentexception,Java,Illegalargumentexception,我正在测试我的用户输入,以查看它是否有效。如果无效,则应抛出一个IllegalArgumentException。但是,无论我的输入是什么,都会抛出gameLogic函数前几行中的IllegalArgumentException。结果是程序打印出“在这个游戏中,你只能输入石头、布、剪刀或-1。”无论我输入什么 import java.util.Scanner; import java.util.Random; class RockPaperScissors { private stati

我正在测试我的用户输入,以查看它是否有效。如果无效,则应抛出一个
IllegalArgumentException
。但是,无论我的输入是什么,都会抛出
gameLogic
函数前几行中的
IllegalArgumentException
。结果是程序打印出
“在这个游戏中,你只能输入石头、布、剪刀或-1。”
无论我输入什么

import java.util.Scanner;
import java.util.Random;
class RockPaperScissors
{
    private static double mUserWinCount = 0;
    private static double mCpuWinCount = 0;
    private static double mUserLossCount = 0;
    private static double mCpuLossCount = 0; 
    private static double mDrawCount = 0;
    private static double mGameCount = 0;
    private static String mCpuInput;
    private static String mUserInput;


    public static void main(String [] args)
    {

         try
         {
             gameLogic(cpuInput(),userInput());
         }
         catch(IllegalArgumentException iae)
         {
             System.out.println(iae.getMessage());
         }


    }

    static String cpuInput()
    {
        Random random = new Random (System.currentTimeMillis());
        int RandomNumber=random.nextInt(3);
        if (RandomNumber == 0)
        mCpuInput = "Rock";
        else if (RandomNumber == 1)
        mCpuInput = "Paper";
        else
        mCpuInput = "Scissors";

        return mCpuInput;
    }

    static String userInput()
    {
        System.out.println("Enter Rock, Paper or Scissors, enter -1 in order to exit:- ");
        mUserInput = new Scanner(System.in).next();

        return mUserInput;

    }

    static void gameLogic(String cpuInput, String userInput)
    {
      if(!userInput.equalsIgnoreCase("Rock") || !userInput.equalsIgnoreCase("Paper") || !userInput.equalsIgnoreCase("Scissors") || !userInput.equals("-1"))
      {
         throw new IllegalArgumentException("You're only permitted to enter Rock, Paper, Scissors or -1 in this game.\n");
      }    

      if(userInput.equals("-1"))
      {
          score();
          System.exit(0);
      }
      System.out.println("CPU entered "+cpuInput+", User entered "+userInput);  
      String [] args = new String[0];

      if(userInput.equalsIgnoreCase(cpuInput))
      {
          System.out.println("It's a draw!");
          mDrawCount++;
          mGameCount++;
      }
      if(userInput.equalsIgnoreCase("Rock") && cpuInput.equalsIgnoreCase("Scissors") || userInput.equalsIgnoreCase("Paper") && cpuInput.equalsIgnoreCase("Rock") || userInput.equalsIgnoreCase("Scissors") && cpuInput.equalsIgnoreCase("Paper"))
      {
         System.out.println("User wins!"); 
         mUserWinCount++; 
         mCpuLossCount++;
         mGameCount++;
      }  
      if(cpuInput.equalsIgnoreCase("Rock") && userInput.equalsIgnoreCase("Scissors") || cpuInput.equalsIgnoreCase("Paper") && userInput.equalsIgnoreCase("Rock") || cpuInput.equalsIgnoreCase("Scissors") && userInput.equalsIgnoreCase("Paper"))
      {
         System.out.println("CPU wins!"); 
         mCpuWinCount++; 
         mUserLossCount++;
         mGameCount++;
      }

      main(args);
    }



    static void score()
    { 
       if (mGameCount==0)
       {
          System.out.println("No games have been played..");
       }    
       else 
       {
           double userWinPercentage = (mUserWinCount / mGameCount) * 100;
           double userLossPercentage = (mUserLossCount / mGameCount) * 100;
           double cpuWinPercentage = (mCpuWinCount / mGameCount) * 100; 
           double cpuLossPercentage = (mCpuLossCount / mGameCount) * 100; 
           double drawPercentage = (mDrawCount/mGameCount) * 100;

           System.out.println("Number of Games Played- " + mGameCount);

           System.out.println("Number of Draws- "+ mDrawCount);
           System.out.println("Percentage of Draws "+ drawPercentage + "%");

           System.out.println("Number of Wins by User- " + mUserWinCount);
           System.out.println("User's Win Percentage- " + userWinPercentage + "%");
           System.out.println("Number of Losses by User- " + mCpuLossCount);
           System.out.println("User's Loss Percentage- " + userLossPercentage + "%");

           System.out.println("Number of Wins by CPU- " + mCpuWinCount);
           System.out.println("CPU's Win Percentage- " + cpuWinPercentage + "%");
           System.out.println("Number of Losses by CPU- " + mCpuLossCount);
           System.out.println("CPU's Loss Percentage- " + cpuLossPercentage + "%");
       } 
    }    
在这一行

if(!userInput.equalsIgnoreCase("Rock") || !userInput.equalsIgnoreCase("Paper") || !userInput.equalsIgnoreCase("Scissors") || !userInput.equals("-1"))
使用
&&
,而不是
|

您可以使用一种形式的真值表来了解原因:

|输入| A | B | C | D | |结果|&结果|
|------------+---+---+---+---+-----------|-----------|
|“岩石”| F | T | T | T | T | F |
|“纸”T | F | T | T | T | F|
|“剪刀”T | T | F | T | T | F|
|“-1”| T | T | F | T | F|
|“foo”T | T | T | T | T | T|
†但是,从设计的角度来看,您可能希望重新构造代码,要求用户在输入不正确时重复输入,而不仅仅是以异常终止游戏。

在这一行中

if(!userInput.equalsIgnoreCase("Rock") || !userInput.equalsIgnoreCase("Paper") || !userInput.equalsIgnoreCase("Scissors") || !userInput.equals("-1"))
使用
&&
,而不是
|

您可以使用一种形式的真值表来了解原因:

|输入| A | B | C | D | |结果|&结果|
|------------+---+---+---+---+-----------|-----------|
|“岩石”| F | T | T | T | T | F |
|“纸”T | F | T | T | T | F|
|“剪刀”T | T | F | T | T | F|
|“-1”| T | T | F | T | F|
|“foo”T | T | T | T | T | T|
†但是,从设计角度来看,您可能希望重新构造代码,要求用户在输入不正确时重复输入,而不仅仅是在出现异常时终止游戏

这句话总是对的。我们有三种可能性:

  • 这个词既不是“石头”也不是“纸”(忽略案例)
  • 这个词是“岩石”
  • 这个词是“纸”
  • 如果a),两个等式都将返回false,那么您将使用“NOT”它们!而你得到的是真的

    如果b)你得到假| |真(=真)

    如果c)你得到了真| |假(=真)

    这句话总是对的。我们有三种可能性:

  • 这个词既不是“石头”也不是“纸”(忽略案例)
  • 这个词是“岩石”
  • 这个词是“纸”
  • 如果a),两个等式都将返回false,那么您将使用“NOT”它们!而你得到的是真的

    如果b)你得到假| |真(=真)


    如果c)得到TRUE | | FALSE(=TRUE)

    我将展示一段重构代码,向您展示处理输入和主循环的替代方法

    此代码对输入使用显式检查,在确保输入为小写后,在输入上使用
    开关
    。请注意,检查正确的用户输入应该放在游戏逻辑之外。你的游戏逻辑应该是:执行游戏的代码。如果你有两个CPU播放器呢

    除此之外,它还包含许多编码提示,首先是注释:

    import java.util.Scanner;
    import java.util.Random;
    
    class RockPaperScissors {
        // NOTE: prefer integers instead of doubles for counts
        private static int mUserWinCount = 0;
        private static int mCpuWinCount = 0;
        // NOTE: avoid double state
        // isn't user loss always identical to cpu win count?
        private static int mUserLossCount = 0;
        private static int mCpuLossCount = 0;
        private static int mDrawCount = 0;
        private static int mGameCount = 0;
    
        public static void main(String[] args) {
    
            // NOTE: always manage your resources
            try (Scanner scanner = new Scanner(System.in)) {
    
                // NOTE: never use recursion unless you cannot avoid it
                // prefer while loop over calling main)
                while (true) {
                    String userInput = userInput(scanner);
                    if (userInput.equals("-1")) {
                        score();
                        // NOTE: prefer running out of main over calling exit
                        break;
                    }
    
                    // NOTE: bring back the amount of state ASAP!
                    // just lowercase has less state, enums have even less
                    if (!validChoice(userInput)) {
                        System.out.println("Not a valid choice!");
                        continue;
                    }
    
                    try {
                        String cpuInput = cpuInput();
                        gameLogic(cpuInput, userInput);
                    } catch (IllegalArgumentException iae) {
                        System.out.println(iae.getMessage());
                    }
                }
            }
        }
    
        // NOTE: use explicit checks for user input
        static boolean validChoice(String userChoice) {
            switch (userChoice.toLowerCase()) {
            case "paper":
            case "scissors":
            case "rock":
                return true;
            default:
                return false;
            }
        }
    
        static String cpuInput() {
            // NOTE: only define your variables in the scope where they are needed
            // this doesn't need to be a field
            String mCpuInput;
    
            // NOTE: prefer new SecureRandom() over Random if performance is not
            // essential
            Random random = new Random(System.currentTimeMillis());
            int RandomNumber = random.nextInt(3);
            if (RandomNumber == 0)
                mCpuInput = "Rock";
            else if (RandomNumber == 1)
                mCpuInput = "Paper";
            else
                mCpuInput = "Scissors";
    
            return mCpuInput;
        }
    
        static String userInput(Scanner scanner) {
            String mUserInput;
            System.out
                    .println("Enter Rock, Paper or Scissors, enter -1 in order to exit:- ");
            mUserInput = scanner.next();
            return mUserInput;
    
        }
    
        static void gameLogic(String cpuInput, String userInput) {
            // NOTE: use logging instead for debug statements
            System.out.println("CPU entered " + cpuInput + ", User entered "
                    + userInput);
    
            // NOTE: learn to detect code smell...
            // if you don't really need args you should not have to define it
            // String [] args = new String[0];
    
            if (userInput.equalsIgnoreCase(cpuInput)) {
                // NOTE: don't mix input/output with the actual game rules
                // return the outcome and then print instead (not fixed)
                System.out.println("It's a draw!");
                mDrawCount++;
                mGameCount++;
            }
    
            if (userInput.equalsIgnoreCase("Rock")
                    && cpuInput.equalsIgnoreCase("Scissors")
                    || userInput.equalsIgnoreCase("Paper")
                    && cpuInput.equalsIgnoreCase("Rock")
                    || userInput.equalsIgnoreCase("Scissors")
                    && cpuInput.equalsIgnoreCase("Paper")) {
                System.out.println("User wins!");
                mUserWinCount++;
                mCpuLossCount++;
                mGameCount++;
            }
            if (cpuInput.equalsIgnoreCase("Rock")
                    && userInput.equalsIgnoreCase("Scissors")
                    || cpuInput.equalsIgnoreCase("Paper")
                    && userInput.equalsIgnoreCase("Rock")
                    || cpuInput.equalsIgnoreCase("Scissors")
                    && userInput.equalsIgnoreCase("Paper")) {
                System.out.println("CPU wins!");
                mCpuWinCount++;
                mUserLossCount++;
                mGameCount++;
            }
    
            // NOTE: avoid recursion
            // don't do this, if you do *document*
            // main(args);
        }
    
        static void score() {
            if (mGameCount == 0) {
                System.out.println("No games have been played..");
            } else {
                double userWinPercentage = (mUserWinCount / mGameCount) * 100;
                double userLossPercentage = (mUserLossCount / mGameCount) * 100;
                double cpuWinPercentage = (mCpuWinCount / mGameCount) * 100;
                double cpuLossPercentage = (mCpuLossCount / mGameCount) * 100;
                double drawPercentage = (mDrawCount / mGameCount) * 100;
    
                // NOTE: learn about printf when the time comes
                System.out.println("Number of Games Played- " + mGameCount);
    
                System.out.println("Number of Draws- " + mDrawCount);
                System.out.println("Percentage of Draws " + drawPercentage + "%");
    
                System.out.println("Number of Wins by User- " + mUserWinCount);
                System.out.println("User's Win Percentage- " + userWinPercentage
                        + "%");
                System.out.println("Number of Losses by User- " + mCpuLossCount);
                System.out.println("User's Loss Percentage- " + userLossPercentage
                        + "%");
    
                System.out.println("Number of Wins by CPU- " + mCpuWinCount);
                System.out.println("CPU's Win Percentage- " + cpuWinPercentage
                        + "%");
                System.out.println("Number of Losses by CPU- " + mCpuLossCount);
                System.out.println("CPU's Loss Percentage- " + cpuLossPercentage
                        + "%");
            }
        }
    }
    

    愉快的编码。

    我将展示一段经过重构的代码,向您展示处理输入和主循环的另一种方法

    此代码对输入使用显式检查,在确保输入为小写后,在输入上使用
    开关
    。请注意,检查正确的用户输入应该放在游戏逻辑之外。你的游戏逻辑应该是:执行游戏的代码。如果你有两个CPU播放器呢

    除此之外,它还包含许多编码提示,首先是注释:

    import java.util.Scanner;
    import java.util.Random;
    
    class RockPaperScissors {
        // NOTE: prefer integers instead of doubles for counts
        private static int mUserWinCount = 0;
        private static int mCpuWinCount = 0;
        // NOTE: avoid double state
        // isn't user loss always identical to cpu win count?
        private static int mUserLossCount = 0;
        private static int mCpuLossCount = 0;
        private static int mDrawCount = 0;
        private static int mGameCount = 0;
    
        public static void main(String[] args) {
    
            // NOTE: always manage your resources
            try (Scanner scanner = new Scanner(System.in)) {
    
                // NOTE: never use recursion unless you cannot avoid it
                // prefer while loop over calling main)
                while (true) {
                    String userInput = userInput(scanner);
                    if (userInput.equals("-1")) {
                        score();
                        // NOTE: prefer running out of main over calling exit
                        break;
                    }
    
                    // NOTE: bring back the amount of state ASAP!
                    // just lowercase has less state, enums have even less
                    if (!validChoice(userInput)) {
                        System.out.println("Not a valid choice!");
                        continue;
                    }
    
                    try {
                        String cpuInput = cpuInput();
                        gameLogic(cpuInput, userInput);
                    } catch (IllegalArgumentException iae) {
                        System.out.println(iae.getMessage());
                    }
                }
            }
        }
    
        // NOTE: use explicit checks for user input
        static boolean validChoice(String userChoice) {
            switch (userChoice.toLowerCase()) {
            case "paper":
            case "scissors":
            case "rock":
                return true;
            default:
                return false;
            }
        }
    
        static String cpuInput() {
            // NOTE: only define your variables in the scope where they are needed
            // this doesn't need to be a field
            String mCpuInput;
    
            // NOTE: prefer new SecureRandom() over Random if performance is not
            // essential
            Random random = new Random(System.currentTimeMillis());
            int RandomNumber = random.nextInt(3);
            if (RandomNumber == 0)
                mCpuInput = "Rock";
            else if (RandomNumber == 1)
                mCpuInput = "Paper";
            else
                mCpuInput = "Scissors";
    
            return mCpuInput;
        }
    
        static String userInput(Scanner scanner) {
            String mUserInput;
            System.out
                    .println("Enter Rock, Paper or Scissors, enter -1 in order to exit:- ");
            mUserInput = scanner.next();
            return mUserInput;
    
        }
    
        static void gameLogic(String cpuInput, String userInput) {
            // NOTE: use logging instead for debug statements
            System.out.println("CPU entered " + cpuInput + ", User entered "
                    + userInput);
    
            // NOTE: learn to detect code smell...
            // if you don't really need args you should not have to define it
            // String [] args = new String[0];
    
            if (userInput.equalsIgnoreCase(cpuInput)) {
                // NOTE: don't mix input/output with the actual game rules
                // return the outcome and then print instead (not fixed)
                System.out.println("It's a draw!");
                mDrawCount++;
                mGameCount++;
            }
    
            if (userInput.equalsIgnoreCase("Rock")
                    && cpuInput.equalsIgnoreCase("Scissors")
                    || userInput.equalsIgnoreCase("Paper")
                    && cpuInput.equalsIgnoreCase("Rock")
                    || userInput.equalsIgnoreCase("Scissors")
                    && cpuInput.equalsIgnoreCase("Paper")) {
                System.out.println("User wins!");
                mUserWinCount++;
                mCpuLossCount++;
                mGameCount++;
            }
            if (cpuInput.equalsIgnoreCase("Rock")
                    && userInput.equalsIgnoreCase("Scissors")
                    || cpuInput.equalsIgnoreCase("Paper")
                    && userInput.equalsIgnoreCase("Rock")
                    || cpuInput.equalsIgnoreCase("Scissors")
                    && userInput.equalsIgnoreCase("Paper")) {
                System.out.println("CPU wins!");
                mCpuWinCount++;
                mUserLossCount++;
                mGameCount++;
            }
    
            // NOTE: avoid recursion
            // don't do this, if you do *document*
            // main(args);
        }
    
        static void score() {
            if (mGameCount == 0) {
                System.out.println("No games have been played..");
            } else {
                double userWinPercentage = (mUserWinCount / mGameCount) * 100;
                double userLossPercentage = (mUserLossCount / mGameCount) * 100;
                double cpuWinPercentage = (mCpuWinCount / mGameCount) * 100;
                double cpuLossPercentage = (mCpuLossCount / mGameCount) * 100;
                double drawPercentage = (mDrawCount / mGameCount) * 100;
    
                // NOTE: learn about printf when the time comes
                System.out.println("Number of Games Played- " + mGameCount);
    
                System.out.println("Number of Draws- " + mDrawCount);
                System.out.println("Percentage of Draws " + drawPercentage + "%");
    
                System.out.println("Number of Wins by User- " + mUserWinCount);
                System.out.println("User's Win Percentage- " + userWinPercentage
                        + "%");
                System.out.println("Number of Losses by User- " + mCpuLossCount);
                System.out.println("User's Loss Percentage- " + userLossPercentage
                        + "%");
    
                System.out.println("Number of Wins by CPU- " + mCpuWinCount);
                System.out.println("CPU's Win Percentage- " + cpuWinPercentage
                        + "%");
                System.out.println("Number of Losses by CPU- " + mCpuLossCount);
                System.out.println("CPU's Loss Percentage- " + cpuLossPercentage
                        + "%");
            }
        }
    }
    

    快乐编码。

    如果输入部分不正确,我如何重复输入部分?非常感谢您的帮助。@ShumsBadwal-这是一个完全不同的问题。每个帖子设计一个特定的问题。一旦你成功了,我建议你发布它,并寻求帮助改进代码结构。@ShumsBadwal我在回答中创建了一些类似于评论的东西;它重复输入(提示:您应该重新使用扫描仪)。如果输入部分不正确,我如何重复输入部分?非常感谢您的帮助。@ShumsBadwal-这是一个完全不同的问题。每个帖子设计一个特定的问题。一旦你成功了,我建议你发布它,并寻求帮助改进代码结构。@ShumsBadwal我在回答中创建了一些类似于评论的东西;它会重复输入(提示:您应该重用扫描仪)。我还没有修复所有问题,我明确没有涉及到类、公共/私有等问题。因为您可能还没有读到这一章。好吧,我只需要一个CPU和一个用户,我在编写此代码时处于半睡眠状态,所以我对这一部分非常轻率,但无论如何,还是要感谢@Maarten Bodewsno,这不是问题,但要注意,你在半睡半醒时产生的代码可能会再次困扰你。一个星期五一次花了我一个星期一和一个星期二的时间来修复,重新开始会更容易更好。我还没有修复所有问题,我明确没有涉及到类、公共/私有等方面的问题,因为你可能还不在那一章。嗯,我只需要一个CPU和一个用户,我写这段代码时半睡半醒,所以我对这段代码很轻率,但无论如何感谢@Maarten Bodewsno没有问题,但请注意,你在半睡半醒时生成的代码可能会再次困扰你。一个星期五曾经花了我一个星期一和一个星期二的时间来修复,重新开始会更容易更好。下面的答案有帮助吗?如果是,请考虑使用复选标记。这向更广泛的社区表明,这是一个有帮助的答案,并给回答者和你自己带来了一些声誉。下面的答案有帮助吗?如果是,请考虑使用支票损坏。