DIY: Do It Yourself: integrating chess selection strategies with the SAN Kit

Revised: 1994.02.19

The general rule: to integrate a new chess move selection strategy into the SAN
Kit, make a copy of an existing one and then modify the copy.

The SAN Kit allows for an indefinite number of "search selection strategies" to
be integrated as part of the toolkit.  By convention each strategy has a three
character alphanumeric name with the first character always being a letter and
with all letters being lower case.  The chosen name must not be "san" and it
also must not be one of the existing strategy names.

For the remainder of the discussion, let the example strategy name be "xyz".

The first step is to modify the strategy name count definition in the file
sandef.h.  There is a line of the form:

    #define ssL 5

which gives the number of strategies currently implemented.  The integer should
be increased by one.

The strategy name list is then modified.  The existing list looks something
like:

    #define ss_eat 0 /* best simple capture */
    #define ss_gtp 1 /* Gillogly TECH program */
    #define ss_ran 2 /* random move selection */
    #define ss_sc0 3 /* Stanback Chess Program (internal) */
    #define ss_sc1 4 /* Stanback Chess Program (external) */

Note that the strategy names appear in alphabetical order.  The new name is
then added to the list and, if needed, all of the integer ordinals are updated.

For the "xyz" name, the only change needed is an additional line at the end of
the list:

    #define ss_xyz 5 /* example strategy */

The next step is the modification of the file sansss.c to include
initialization and other references to the new strategy.  The first substep is
to add an include file reference along with the existing "x" family references
near the beginning of the file:

    #include "x_xyz.h"

The next substep is to add a line for the initialization of the strategy name
vector:

    ssstrv[ss_xyz] = "xyz";

The next substep is to add a set of eight statements to initialize the function
pointer vector entries for the hook routines in the new strategy implementation
file.  To do this, just copy one of the existing sets and change the names
accordingly:

    ssdv[ss_xyz][sep_init] = XYZInit;
    ssdv[ss_xyz][sep_term] = XYZTerm;
    ssdv[ss_xyz][sep_newgame] = XYZNewGame;
    ssdv[ss_xyz][sep_select] = XYZSelect;
    ssdv[ss_xyz][sep_play] = XYZPlay;
    ssdv[ss_xyz][sep_unplay] = XYZUnplay;
    ssdv[ss_xyz][sep_setpos] = XYZSetPos;
    ssdv[ss_xyz][sep_config] = XYZConfig;

This concludes the steps for modifying the file sansss.c.

The Makefile also needs modification.  There are three new files it needs to
know about: x_xyz.h (prototype header file), x_xyz.x (C source file), and
x_xyz.o (object file for x_xyz.c).  These are added to the macro definitions at
the beginning of the Makefile in the same manner as other selection strategy
files appear.  Additionally, a compilation rule will be needed to make x_xyz.o
from x_xyz.c; this is added in the same way that the other strategy compilation
rules appear.  Finally, the dependency rule for the compilation of the file
sansss.c needs to have the filename x_xyz.h added to the rest of the strategy
header file names.

The strategy header file needs to be created.  This is a simple file that
contains only the ANSI prototypes for the eight hook routines that will appear
in file x_xyz.c.  The easist way of creating this file is to copy and existing
strategy header file and then changing the names.

    /*>>> x_xyz.h: subprogram prototypes for x_xyz.c */

    /* Revised: 1993.04.25 */

    void XYZInit(void);
    void XYZTerm(void);
    void XYZNewGame(void);
    void XYZSelect(void);
    void XYZPlay(void);
    void XYZUnplay(void);
    void XYZSetPos(void);
    void XYZConfig(void);

    /*<<< x_xyz.h: EOF */

The final major step is the creation of the implementation module; the file
x_xyz.c.  Again, the best way to start this is to copy one of the simpler
existing strategy implementation files and then change the names accordingly.

Each of the eight hook routines must be coded to activate the appropriate
functions of the new strategy.  Note that none of these routines has any formal
arguments.  This is because these routines are themselves considered to be
"tightly integrated" into the SAN Kit and so are assumed to have access to the
SAN Kit global data structures.  Also, note that none of the eight routines
returns a value.

The hook routine XYZInit is called once during program initialization and
before any other hooks are called.

The hook routine XYZTerm is called once during program termination and after
all other hooks are called.

The hook routine XYZNewGame is called when a new game is to be started.  This
happens once during SAN Kit initialization and also when the command "newg"
(new game) is entered.

The hook routine XYZSelect is called when a move selection is requested from
the strategy.  Unlike all of the other hook routines, this routine is only
called when the given search strategy is selected from the SAN Kit command
processor.  This is done by use of the "svss" (set value: search strategy)
command.  The idea is that all of the integrated strategy modules get called
for all of the hook events other than the move selection.  This allows for two
items: first, all of the strategies are kept in synchronization so strategies
may be switched at any time; second, because move selection is likely a time
consuming process, only the selection that will affect the real search result
will be performed.  Note: this hook only selects a move, it does not play the
move.  The selected move is stored in the global variable "select_m".

The hook routine XYZPlay is called whenever a move is made.  The strategy
should use this opportunity to update its internal structures.  The move is a
legal move.

The hook routine XYZUnplay is called whenever a move is unmade.  The strategy
should use this opportunity to update its internal structures.  A legal
retraction is always possible.

The hook routine XYZSetPos is called whenever a set-up position is entered.
This is a position that does not have any history and so moves cannot be
retracted.  The strategy should use this opportunity to update its internal
structures.  Note: the position may be an illegal one!  This can be checked
with the apropriate SAN Kit routines.

The hook routine XYZConfig is called whenever there is some configuration
change in the SAN Kit operating parameters that may affect strategy operation.
Currently, the only two items that trigger this call are operations that set
the values for the playing level and the average response time.  More
configuration items will probably be added in the future.

DIY: EOF
