예제 #1
0
        public static Command Parse(string input)
        {
            string[] values = input.Split(' ');

            if (!values.Any())
            {
                throw new ArgumentException("No command specified.");
            }

            // command should be first
            if (!Enum.TryParse(values[0].ToPascalCase(), out CommandType type))
            {
                throw new ArgumentException($"Invalid command {values[0]}");
            }
            if (type == CommandType.Undefined)
            {
                throw new ArgumentException($"Invalid command {type}");
            }

            string[] args = values.Skip(1).ToArray();

            Command command = null;

            switch (type)
            {
            case CommandType.End:
            {
                command = new EndCommand();
                break;
            }

            case CommandType.Flag:
            {
                command = new FlagCommand();
                Dictionary <string, object> requiredArgs = command.GetRequiredArguments();

                if (args.Length != requiredArgs.Count)
                {
                    throw new ArgumentException($"Command type {type} requires {requiredArgs.Count} arguments.");
                }

                if (!int.TryParse(args[0], out int x))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.XPosition} must be an integer.");
                }
                if (!int.TryParse(args[1], out int y))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.YPosition} must be an integer.");
                }

                requiredArgs[CommandKeys.XPosition] = x;
                requiredArgs[CommandKeys.YPosition] = y;

                command.Build(requiredArgs);

                break;
            }

            case CommandType.Help:
            {
                command = new HelpCommand();
                Dictionary <string, object> requiredArgs = command.GetRequiredArguments();

                if (args.Length > 0)
                {
                    if (args.Length > 1)
                    {
                        throw new ArgumentException($"Command type {type} requires 1 or 0 arguments.");
                    }

                    if (!Enum.TryParse(args[0].ToPascalCase(), out CommandType commandType))
                    {
                        throw new ArgumentException($"Invalid command type {args[0]}");
                    }

                    requiredArgs[CommandKeys.CommandName] = commandType;

                    command.Build(requiredArgs);
                }

                break;
            }

            case CommandType.New:
            {
                command = new NewCommand();
                Dictionary <string, object> requiredArgs = command.GetRequiredArguments();

                if (args.Length != requiredArgs.Count)
                {
                    throw new ArgumentException($"Command type {type} requires {requiredArgs.Count} arguments.");
                }

                if (!int.TryParse(args[0], out int x))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.XLength} must be an integer.");
                }
                if (!int.TryParse(args[1], out int y))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.YLength} must be an integer.");
                }
                if (!int.TryParse(args[2], out int b))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.Bombs} must be an integer.");
                }

                requiredArgs[CommandKeys.XLength] = x;
                requiredArgs[CommandKeys.YLength] = y;
                requiredArgs[CommandKeys.Bombs]   = b;

                command.Build(requiredArgs);

                break;
            }

            case CommandType.Open:
            {
                command = new OpenCommand();
                Dictionary <string, object> requiredArgs = command.GetRequiredArguments();

                if (args.Length != requiredArgs.Count)
                {
                    throw new ArgumentException($"Command type {type} requires {requiredArgs.Count} arguments.");
                }

                if (!int.TryParse(args[0], out int x))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.XPosition} must be an integer.");
                }
                if (!int.TryParse(args[1], out int y))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.YPosition} must be an integer.");
                }

                requiredArgs[CommandKeys.XPosition] = x;
                requiredArgs[CommandKeys.YPosition] = y;

                command.Build(requiredArgs);

                break;
            }

            case CommandType.Quit:
            {
                command = new QuitCommand();
                Dictionary <string, object> requiredArgs = command.GetRequiredArguments();
                break;
            }

            case CommandType.Unflag:
            {
                command = new UnflagCommand();
                Dictionary <string, object> requiredArgs = command.GetRequiredArguments();

                if (args.Length != requiredArgs.Count)
                {
                    throw new ArgumentException($"Command type {type} requires {requiredArgs.Count} arguments.");
                }

                if (!int.TryParse(args[0], out int x))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.XPosition} must be an integer.");
                }
                if (!int.TryParse(args[1], out int y))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.YPosition} must be an integer.");
                }

                requiredArgs[CommandKeys.XPosition] = x;
                requiredArgs[CommandKeys.YPosition] = y;

                command.Build(requiredArgs);

                break;
            }

            case CommandType.Status:
            {
                command = new StatusCommand();
                Dictionary <string, object> requiredArgs = command.GetRequiredArguments();

                if (args.Length != requiredArgs.Count)
                {
                    throw new ArgumentException($"Command type {type} requires {requiredArgs.Count} arguments.");
                }

                if (!int.TryParse(args[0], out int x))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.XPosition} must be an integer.");
                }
                if (!int.TryParse(args[1], out int y))
                {
                    throw new ArgumentException($"Parameter {CommandKeys.YPosition} must be an integer.");
                }

                requiredArgs[CommandKeys.XPosition] = x;
                requiredArgs[CommandKeys.YPosition] = y;

                command.Build(requiredArgs);

                break;
            }
            }

            return(command);
        }