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

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



Chris, you may have to provide a bit more detailed information on what you're trying to do.
 
The way you describe it it's not clear to me why you use reflection instead of an interface defining all the GTP commands.
 
If it's the switch-statement you're trying to avoid, then the 'Command' pattern is generally the answer. Have your GoEngine maintain a list of commands which can be expanded compile-time very easily. Provided of course all commands have the same signature.
 
I've found (the hard way) that there are not many cases where there isn't a better, safer and more efficient alternative to something that uses reflection.
-----Original Message-----
From: computer-go-bounces@xxxxxxxxxxxxxxxxx [mailto:computer-go-bounces@xxxxxxxxxxxxxxxxx]On Behalf Of Chris Smith
Sent: Friday, November 12, 2004 4:19
To: computer-go@xxxxxxxxxxxxxxxxx
Subject: [computer-go] A design pattern for implementing the GTP

I have recently completed a GTP communication layer of my Go program and found it to be surprisingly simple and easy to do.  I figured I would share the design used with you in case you were thinking about implanting the GTP in the near future, though this only applies to managed languages (C#, VB.NET, Java, etc.)  PLEASE DO NOT RESPOND TO THIS EMAIL TALKING ABOUT PROGRAMMING LANGUAGES.

 

The Problem and Requirements

When designing my GTP layer I wanted it to be as simple as possible so that adding and removing commands wouldn’t be troublesome.  This ruled out using inheritance or a massive switch statements.  The main thing I kept running into was how do you keep the list of known commands up to date at compile time without headache.  If you needed to know the function names at compile time the best I could come up with was a hash table of command name / delegate (function pointer) pairs.

 

However, in a moment of clarity I looked to reflection and found the answer.

 

Here is the Idea:

 

public class Communicator

{

            private GoEngine m_goEngine;

 

            public GTPOutput protocol_version (GTPInput input){ }

            public GTPOutput name (GTPInput input){ }

            public GTPOutput clear_board (GTPInput input){ }

            …

}

 

The communicator class has an instance of the computer-Go engine which it instantiates in its constructor and every function in the class is the implementation of a GTP command.  So the ‘clear_board’ method is the implementation for the ‘clear_board’ GTP command.

 

public class Driver

{

            GTPOutput ExecuteCommand(string command, string arguments, string id = “”);

}

 

When a driver class is created it uses reflection to query all public methods in the Communicator class and then simply matches a command string with a method name and calls the function.  By doing this you 1.) know every GTP function your Go program supports without having to update a list, database, hashtable, etc 2.) adding new or GTP commands is as simple as adding new functions and 3.) the implementation is very clean.

 

In one day I was able to support every GTP command in the version 2 draft, which surprised me enough to tell all of you J

 

The only caveat is that you must manually exclude all functions that are off of System.Object, so you must remove .ToString(), . GetHashCode(), etc… unless you want list_commands to say that that is a valid command to your Go engine.  Also worth nothing is that the performance hit is minimal, since you only need to query the object for its methods once and after that are just calling super-function-pointers of sorts.

 

Anyways, if there are any .NET or Java programmers out there who haven’t added GTP support to your Go-bots yet, this might be the solution you were waiting for.

 

Thanks,

-Chris Smith

 

 

 

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