即使条件不正确,Java代码也会打印Exception中给出的消息

时间:2015-08-02 11:47:08

标签: java illegalargumentexception

我正在测试我的用户输入,以查看它是否有效。如果它无效,则应抛出IllegalArgumentException。但是,无论我的输入是什么,IllegalArgumentException函数的前几行中的gameLogic都会被抛出。结果是,无论输入是什么,程序都会打印"You're only permitted to enter Rock, Paper, Scissors or -1 in this game."

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 + "%");
       } 
    }    

3 个答案:

答案 0 :(得分:4)

在这一行

if(!userInput.equalsIgnoreCase("Rock") || !userInput.equalsIgnoreCase("Paper") || !userInput.equalsIgnoreCase("Scissors") || !userInput.equals("-1"))

使用&&,而非||

if(!userInput.equalsIgnoreCase("Rock") && !userInput.equalsIgnoreCase("Paper") && !userInput.equalsIgnoreCase("Scissors") && !userInput.equals("-1"))

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

| Input      | A | B | C | D | || Result | && Result |
|------------+---+---+---+---+-----------|-----------|
| "Rock"     | F | T | T | T | T         | F         | 
| "Paper"    | T | F | T | T | T         | F         |
| "Scissors" | T | T | F | T | T         | F         |
| "-1"       | T | T | T | F | T         | F         |
| "foo"      | T | T | T | T | T         | T         |

但是,从设计的角度来看,您可能希望重构代码以要求用户重复输入(如果不正确),而不是仅仅使用例外。

答案 1 :(得分:0)

 if(!userInput.equalsIgnoreCase("Rock") || !userInput.equalsIgnoreCase("Paper") 

此行始终为真。我们有三种可能性:

  1. 这个词既不是" Rock"也不是"论文" (无视案例)
  2. 这个词是" Rock"
  3. 这个词是" Paper"
  4. 如果a),equalIgnoreCases都将返回false,那么你" NOT"他们一起!你得到TRUE || TRUE(== TRUE,很明显)

    如果b)你得到FALSE || TRUE(== TRUE)

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

答案 2 :(得分:0)

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

此代码使用输入的显式检查,在确保输入为小写后使用输入switch。请注意,检查正确的用户输入应该放在外面游戏逻辑中。你的游戏逻辑应该只是:执行游戏的代码。如果你有两个CPU播放器怎么办?

除了它包含许多编码提示,从NOTE:。开始。

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
                    + "%");
        }
    }
}

快乐的编码。