[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[computer-go] A design pattern for implementing the GTP



Well I appreciate the feed back, and have posted the source to my website at [http://home.comcast.net/~logospathosethos/].  As for some more details on how it works, let me highlight three areas.  The code should be fairly self explanatory, the first queries every method in the ‘communicator’ class, the second matches a GTP command with a method name, and the third defines the communicator class.

 

Notes:

·         If you can't tell, my Go program is called Gozilla- which unfortunately has already been taken so I will probably rename it if I let it out into the wild.

·         The code uses the .NET Framework 2.0, to compile it I would recommending downloading a copy of C# Express from [http://lab.msdn.microsoft.com/express/vcsharp/]

 

 

public GozillaThroughGTP(bool excludeI)

{

       m_bRunning = true;

 

       /**

        * Use reflection to create an instance of GozillaCommunicator and

        * query all of its members so that we can define which GTP commands are

        * known at runtime without much of a mess.  This also makes enhancing the

        * Gozilla GTP command system MUCH easier.

        */

       Type gozillaCommunicator = typeof(GozillaCommunicator);

                    

       // Create an instance of it 'somewhere' in memory

       object[] arguments = { excludeI };

       m_gozillaCommunicator = (GozillaCommunicator) Activator.CreateInstance(gozillaCommunicator, arguments);

 

       // Add the commands to a list, neglecting ToString, GetHashCode and others.

       m_GTPCommands = new List<MethodInfo>();

       MethodInfo[] allMethods = gozillaCommunicator.GetMethods();

 

       StringCollection invalidMethods = new StringCollection();

       invalidMethods.Add("Equals");

       invalidMethods.Add("GetHashCode");

       invalidMethods.Add("GetType");

       invalidMethods.Add("ToString");

                    

       foreach (MethodInfo method in allMethods)

       {

              // If it isn't on our banned list it is OK by me

              if (invalidMethods.IndexOf(method.Name) == -1)

                     m_GTPCommands.Add(method);

       }

}

 

 

private String ExecuteCommand(String command, String arguments)

{

       m_bCommandHadError = false;

 

       // See if the command exists in our GozillaCommunicator

       foreach (MethodInfo method in m_GTPCommands)

       {

              if (method.Name == command)

              {

                     GTPCommandInput ip = new GTPCommandInput(arguments);

                     object[] methodargument = { ip };

                    

                     // Invoke the method

                     GTPCommandOutput op = (GTPCommandOutput)method.Invoke(m_gozillaCommunicator, methodargument);

                     // Yeah!

                     if (op.HasError) m_bCommandHadError = true;

                     return op.Output;

              }

       }

 

       // known_command checks if the argument is a supported command or not

       if (command == "known_command")

       {

              foreach (MethodInfo method in m_GTPCommands)

              {

                     if (method.Name == arguments)

                           return "true";

              }

                     return "false";

       }

 

       // list_commands lists all supported GTP commands

       if (command == "list_commands")

       {

              StringBuilder knownCommands = new StringBuilder();

              foreach (MethodInfo method in m_GTPCommands)

              {

                     knownCommands.Append(method.Name + "\n");

              }

 

              // Add the ones that are in this module

              knownCommands.Append("known_command\n");

              knownCommands.Append("list_commands\n");

              knownCommands.Append("quit");

 

              return knownCommands.ToString();

       }

 

       // Terminate

       if (command == "quit")

       {

              m_bRunning = false;

              return "";

       }

 

       // All else fails, error

       m_bCommandHadError = true;

       return "unknown command";

}

 

public class GozillaCommunicator

{

       public GozillaCommunicator(bool bIgnoreIs)

       {

              m_engine = new GozillaGoEngine();

              m_bIgnoreIs = bIgnoreIs;

       }

 

       /// <summary>

       /// The actual Go engine

       /// </summary>

       private GozillaGoEngine m_engine;

 

       /// <summary>

       /// Whether or not the Go program should ignore 'I' when issued board points, so

       /// I9 will return an error and J is the 9th coloumn on the board

       /// </summary>

       private bool m_bIgnoreIs;

 

       #region "Meta-Commands"

       /// <summary>

       /// Returns the name of the Go program

       /// </summary>

       /// <param name="input"></param>

       /// <returns></returns>

       public GTPCommandOutput name(GTPCommandInput input)

       {

              return new GTPCommandOutput("Gozilla", false);

       }

 

       /// <summary>

       /// Displays the version information of Gozilla

       /// </summary>

       /// <param name="input"></param>

       /// <returns></returns>

       public GTPCommandOutput version(GTPCommandInput input)

       {

              return new GTPCommandOutput(m_engine.EngineVersion, false);

       }

      

       (The class goes on…)

 

 

_______________________________________________
computer-go mailing list
computer-go@xxxxxxxxxxxxxxxxx
http://www.computer-go.org/mailman/listinfo/computer-go/