如何为文本冒险游戏实现调度表?

Rya*_* S. 4 c# adventure dispatch-table

在C#中进行文本冒险,有人建议我使用调度表而不是switch语句.

这是switch语句代码:

        #region Public Methods
        public static void Do(string aString)
        {
                if(aString == "")
                        return;

                string verb = "";
                string noun = "";

                if (aString.IndexOf(" ") > 0)
                {
                        string[] temp = aString.Split(new char[] {' '}, 2);
                        verb = temp[0].ToLower();
                        noun = temp[1].ToLower();
                }
                else
                {
                        verb = aString.ToLower();
                }

                switch(Program.GameState)
                {
                        case Program.GameStates.Playing:
                                if (IsValidInput(Commands, verb, true))
                                {
                                        switch(verb) //this is the switch statement
                                        {
                                                case "help":
                                                case "?":
                                                        WriteCommands();
                                                        break;
                                                case "exit":
                                                case "quit":
                                                        Program.GameState = Program.GameStates.Quit;
                                                        break;
                                                case "move":
                                                case "go":
                                                        MoveTo(noun);
                                                        break;
                                                case "examine":
                                                        Examine(noun);
                                                        break;
                                                case "take":
                                                case "pickup":
                                                        Pickup(noun);
                                                        break;
                                                case "drop":
                                                case "place":
                                                        Place(noun);
                                                        break;
                                                case "use":
                                                        Use(noun);
                                                        break;
                                                case "items":
                                                case "inventory":
                                                case "inv":
                                                        DisplayInventory();
                                                        break;
                                                case "attack":
                                                        //attack command
                                                        break;
                                        }
                                }
                                break;

                        case Program.GameStates.Battle:
                                if(IsValidInput(BattleCommands, verb, true))
                                {
                                        switch(verb) //this is the other switch statement
                                        {
                                                case "attack":
                                                        //attack command
                                                        break;
                                                case "flee":
                                                case "escape":
                                                        //flee command
                                                        break;
                                                case "use":
                                                        //use command
                                                        break;
                                                case "items":
                                                case "inventory":
                                                case "inv":
                                                        //items command
                                                        break;
                                        }
                                }
                                break;
                }
        }
        #endregion
Run Code Online (Sandbox Code Playgroud)

我如何重构这个以使用调度表?

tyr*_*nid 12

最简单的方法是使用代表字典.

例如:

Dictionary<string, Action> dispatch = new Dictionary<string, Action>();

dispatch["help"] = new Action(() => Console.WriteLine("Hello"));
dispatch["dosomething"] = new Action(() =>
{
    // Do something else
    Console.WriteLine("Do Something");
});

// Call the 'help' command
dispatch["help"]();
Run Code Online (Sandbox Code Playgroud)

对于多个不同的参数,最简单的方法是使用基本委托并使用动态调用.

Dictionary<string, Delegate> dispatch = new Dictionary<string, Delegate>();

dispatch["help"] = new Action(() => Console.WriteLine("Hello"));
dispatch["dosomething"] = new Action<string>(s => Console.WriteLine(s));

dispatch["help"].DynamicInvoke();
dispatch["dosomething"].DynamicInvoke("World");
Run Code Online (Sandbox Code Playgroud)

如果使用.NET 4,您还可以使用动态类型在运行时解析,以减少动态调用的混乱.

Dictionary<string, dynamic> dispatch = new Dictionary<string, dynamic>();

dispatch["help"] = new Action(() => Console.WriteLine("Hello"));
dispatch["dosomething"] = new Action<string>(s => Console.WriteLine(s));

dispatch["help"]();
dispatch["dosomething"]("World");
Run Code Online (Sandbox Code Playgroud)