0

I am a beginner and I've finished the basic Nim game. Now I want to apply the try catch block to the program to make sure the flow control is perfect. However, the resources I've seen for now is to catch the exception in the main method that all the methods created must be called in the try block to catch the exception.

In my case, I create my class's constructor to call the processCommands panel. Then, this panel calls the other methods in the class.

I need to catch the user input commands in the panel to see whether the commands is valid.

I've tried: https://beginnersbook.com/2013/04/user-defined-exception-in-java/

But it seems that I have to reconstruct the methods I've built so far. Is there any way to fix this?

Any help is appreciated. Thank you for your kindness and patience.

Here is part of my Nimsys:

import java.util.ArrayList;
import java.util.Scanner;

class InvalidUserInput extends Exception {
public InvalidUserInput(String s) {
    super(s);
}
}

public class Nimsys{

private NimModel nimModel;

public static void main(String[] args) throws InvalidUserInput {
    Nimsys nimsys = new Nimsys();
    nimsys.processCommands();
}


public Scanner in = new Scanner(System.in);

private void processCommands() {
    this.nimModel = new NimModel();
    System.out.println("Welcome to Nim\n");
    while (true) {
        System.out.print('$');
        String [] commandin = in.nextLine().split(" ");

        if (commandin[0].equalsIgnoreCase("addplayer")) {
            addPlayer(commandin[1]);
        }
        if (commandin[0].equalsIgnoreCase("removeplayer")) {
            if (commandin.length > 1) {
                removePlayer(commandin[1]);
            } else {
                removePlayer("");
            }
        }
        if (commandin[0].equalsIgnoreCase("editplayer")) {
            editPlayer(commandin[1]);
        }
        if (commandin[0].equalsIgnoreCase("displayplayer")) {
            if (commandin.length > 1 ){
                displayPlayer(commandin[1]);
            } else {
                displayPlayer("");
            }

        }
        if (commandin[0].equalsIgnoreCase("startgame")) {
            startGame(commandin[1]);
        }
        if (commandin[0].equalsIgnoreCase("resetstats")) {
            if (commandin.length > 1 ){
                resetStats(commandin[1]);
            } else {
                resetStats("");
            }
        }

        if (commandin[0].equalsIgnoreCase("rankings")) {
            if (commandin.length > 1 && commandin[1].equals("asc")) {
                rankings(commandin[1]);
            }
            else if (commandin.length > 1 && commandin[1].equals("desc")) {
                rankings(commandin[1]);
            } else {
                rankings("");
            }  
        }

        if (commandin[0].equalsIgnoreCase("exit")) {
            if (commandin.length == 1) {
                System.out.println("");
                break;
            }
        }
    }
}

void userCommandCheck(String [] command) throws InvalidUserInput {
    if (command.length >2) {
        throw new InvalidUserInput("Incorrect number of arguments supplied to command.");
    }
    String [] commandSet = {"addplayer", "removeplayer", "editplayer", "displayplayer", "startgame", "resetstats", "rankings"};
    for(String commandCell: commandSet) {
        if (command[0] != commandCell) {
            throw new InvalidUserInput("`"+command[0]+"'" + " is not a valid command.");
        }
    }
}
}
Woden
  • 1,054
  • 2
  • 13
  • 26
  • 2
    Would you be better off with a method with signature: `static String userCommandCheck(String command) throws InvalidUserInput;`? This would appear to fit better with your `processCommands()` method. – codebod May 10 '20 at 11:50
  • 2
    Then `try { switch(userCommandCheck(commandin[0])) { } } catch(InvalidUserInput e) {}`. – codebod May 10 '20 at 11:59
  • The `Static` is valid, but it still not reads my input. I just don't want to put `try catch` in the `processCommands` since there are too many nests inside. @codebod – Woden May 10 '20 at 12:02
  • It seems not working... Sir, if you have an answer, could you please post it? Thank you. @codebod – Woden May 10 '20 at 12:09

2 Answers2

1
private void processCommands() {
    this.nimModel = new NimModel();
    System.out.println("Welcome to Nim\n");
    while (true) {
        System.out.print('$');
        String [] commandin = in.nextLine().split(" ");

        try {
            switch (userCommandCheck(commandin[0])) {
                case "addplayer":
                    addPlayer(commandin[1]);
                default:

            }
        } catch (InvalidUserInput e) {

        }
}

static String userCommandCheck(String command) throws InvalidUserInput {

    String [] commandSet = {"addplayer", "removeplayer", "editplayer", "displayplayer", "startgame", "resetstats", "rankings"};
    for(String commandCell: commandSet) {
        if (command.equalsIgnoreCase(commandCell)) {
            return command.toLowerCase();
        }
    }
    throw new InvalidUserInput("`"+command+"'" + " is not a valid command.");
}

}

codebod
  • 686
  • 6
  • 17
  • Which piece doesn't work exactly? Obviously, I've left some blanks within the `switch` statement that you will need to fill in to handle all cases. – codebod May 10 '20 at 13:06
  • my bad, I didn't see it clearly. Thank you very much, sir. – Woden May 10 '20 at 13:25
0

finally, I did it like this. I think is clearer because I want the command panel looks clean.

class InvalidUserInput extends Exception {}

Main class {

private void processCommands() {
// commands inside
// try catch block
try {
      String [] commandSet = {"addplayer", "addaiplayer", "removeplayer", "editplayer", "displayplayer", "startgame", "resetstats", "rankings"};
      boolean contains = Arrays.stream(commandSet).anyMatch(commandin[0]::equals); //check if commandin[0] in any of values in the commandSet

      if (!contains) {
           throw new InvalidUserInput();
       }

       } catch (Exception e) {
           System.out.println("`"+commandin[0]+"`" + " is not a valid command.");
}
}
Woden
  • 1,054
  • 2
  • 13
  • 26