5
\$\begingroup\$

I'm working on a little text based console game for a bit of fun and am starting work on the user commands entered into the console.

Are there some good design patterns for deciding what to do with the commands the user enters into the console window?

My thoughts so far:

I've createed a basic query structure for obtaining the command and it's arguments. It works kinda as follows (the code is C#):

var userCommand = _getUserInputQuery.Invoke(new GetUserInputRequest
                                                {
                                                  FullCommandText = Console.ReadLine()
                                                });

I now have two items available to me in the userCommand. Firstly I have the name of the command as a string userCommand.UserCommand and secondly I have a string array of arguments userCommand.UserCommandArgs.

I figure there's a couple of ways I can now proceed with the information I have.

The most basic form could be a simple switch/if on the command name and invoke the relevant class/method required (seems a bit icky though).

I also figured given a generic interface for all commands IUserInputCommand I could create the class required using reflection and fire off a generic Invoke method from the interface. (Although I'm not sure how useful this will be given that some command invokations will require different data than others).

What are some design patterns already available for solving this kind of problem? What would you do personally?

\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

Old MUDs and Talkers (mostly the talker code bases) would use an array of arrays of structs for keeping lookups only to possible alphabetic matches. This would be done with

input[0].ToLowerInvarriant() - 'a'

== the index of all the commands starting with the same letter... In C# however I would say just use a Dictionary. Their hashing routines for strings is nice and zippy so just

Dictionary<string, Delegate> dCommandHash;

or so would work. Then just

if ( dCommandHash.ContainsKey(userCommand.UserCommand))
    Whatever.You.Call.Invoke.On.Invoke(dCommandHash[userCommand.UserCommand],userCommand.UserCommandArgs);

would likely be the most straight forward way to accomplish this.

\$\endgroup\$
4
\$\begingroup\$

If you'd like to see what one approach to this looks like far down the evolutionary path, take a look at the MudOS parser. This is a complex, powerful mechanism for defining pattern-based parsing, meant to be able to intelligently route command handling for targets with multiple nouns and adjectives, and handle cases like put ITEM in CONTAINER vs. put on CLOTHING (i.e. very different actions that happen to start with the same verb). It may help illuminate where you're going.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .