In this section we discuss some additional useful techniques. This section is still a work in progress.
.jar FilesCopying a plug-in's .class files to the plugins/ directory is
inconvenient if you intend to distribute your plug-in to other users.
For more convenient distribution, it's possible to package a plug-in into a
single .jar file. If that .jar file is placed in the plugins/
directory, then Combinatorial Game Suite will automatically detect it and
display it in Plug-in Manager.
To try this for the Sample Plug-in, first go to Plug-in Manager and remove the
plug-in created during the first part of this tutorial, and
exit CGSuite. Then download the metafile
sample.mf and copy it to the directory that contains the compiled
.class files. (sample.mf contains a single entry,
Cgsuite-Plugin-Class, that tells Combinatorial Game Suite which subclass of
Plugin to use.) Switch to that directory and type:
jar cfm sample.jar sample.mf *.class
Then copy sample.jar to the plugins/ directory of your CGSuite
installation. Start Combinatorial Game Suite and click Tools/Plug-in
Manager. sample.jar should pop up automatically; it can now be
loaded just by clicking the "Load" button.
Depending on the game you're implementing, it might be useful to cache additional information beyond just the canonical form of each position. Or you might want to completely override AbstractShortGame's canonicalize method and perform the caching manually. Whatever the case, it's generally inadvisable to use a static member cache for this purpose. The reason is that the memory used by your plug-in's cache can never be reclaimed by the CGSuite kernel.
Combinatorial Game Suite provides a single global cache, the "primary cache", that all plug-ins can use. To obtain a reference to the primary cache, call the static method cgsuite.Context.getActiveContext().getPrimaryCache(). Note that the static Context contains a variety of other utility methods; see the
API for more information. Plug-ins should never call Context.setActiveContext.
TODO: More information on caching.
In many cases it is desirable to specify optional arguments for a Combinatorial Game Suite method. You might wish to provide additional, less frequently used parameters for your method, without forcing the user to specify default values for a bunch of extraneous arguments.
For example, consider a class that could represent both standard and
diagonal Clobber. Its method (in CGSuite) would need a Boolean-valued
parameter that is true if diagonal moves are permitted; false
otherwise. One solution would be to add an extra Boolean-valued
argument, but this would encumber the vast majority of calls to Clobber
with an extra false. A better solution is to use an
optional method argument; the syntax, borrowed from GAP, looks like this:
Clobber("lrlr","rl.l" : Diagonal := true)
Of course optional method arguments can take any type of value, not just
Booleans.
For details on declaring optional method arguments, see the API for PluginContext and MethodInfo.
Return to the Table of Contents