Check out Janggi (Korean Chess), our featured variant for December, 2024.


[ Help | Earliest Comments | Latest Comments ]
[ List All Subjects of Discussion | Create New Subject of Discussion ]
[ List Earliest Comments Only For Pages | Games | Rated Pages | Rated Games | Subjects of Discussion ]

Single Comment

GAME code table-driven move generator[Subject Thread] [Add Response]
H. G. Muller wrote on Sat, Jul 25, 2020 05:38 PM UTC:

Phase 0 seems to work now. I create a preset Sandbox to try it out. (due to a faulty d key on my laptop the settings are saved in the file sanbox.) I notice this completely bypasses any checking on the entered moves; one can also move pieces of the opponent. When parsing the input move this thus also has to be checked.

Next is phase 1: testing whether the entered move could in principle be a valid move for a chess variant of the type that can be handled by the Play-Test Applet. These are simple moves (possibly performing replacement capture at their destination), moves that alter the piece type (promotions), moves that as a side effect remove one or two pieces from other squares, or make a piece appear on another square.

In Game Courier this can require entering a sequence of moves for one turn. We will enforce the convention that the first of these will always be a normal displacement of a piece of the player whose turn it is, like "P e7-e8". This can then be followed by putting a piece on the destination square on the first move ("Q-e8") to indicate a promotion. Such a ' drop move' should also be used to make a captured piece appear elsewhere. If a piece is captured as a side efect ('locust capture'), this can be indicated by dropping an empty square on top of it ("@-d4"). All the additional actions can thus be indicated through extra moves with the drop syntax; they just differ in where or what they drop.

We will allow one exception to this: a locust capture can also be entered by first making the capture in the normal chess way, moving to the location of the victim, and moving from there to the destination in a second 'normal' move. So additional board moves will be allowed, provided that they start where a previous board move ended. The intermediate square must then have been occupied, and the combination of board moves will have exactly the same effect as when that intermediate square had been mentioned in the drop of an empty square, to effect locust capture.

A tentative routine for parsing the input move is given below. Its purpose is to set the variables origin, dest, moved, promo, suicide, freedrop and dropped, in accordance with the entered move in thismove. The first three of those describe the mandatory first move, and will always be set when the move is accepted. The next three describe the optional side efects of promoting, removing a piece, adding a piece. When the move will not have the corresponding side effect, they will be set to false. The value of dropped will only be defined when a piece was added, and in that case holds the mentioned piece type.

sub ParseMove player:
  my i j mvs parts sqrs;
  set many suicide false freedrop false promo false;
  set mvs explode chr 59 thismove;                   // split at semicolons
  set parts explode ws trim elem 0 #mvs;             // split first move at space
  set i count #parts;
  if > #i 2:                                         // too many parts
    die "move must be piece ID plus board step";
  endif;
  set sqrs explode chr 45 trim elem dec #i #parts;   // split last part at hyphen
  if != 2 count #sqrs:                               // must give 2 squares
    die "board step does not mention two squares";
  endif;
  set origin elem 0 #sqrs;                           // first is origin
  set dest elem 1 #sqrs;                             // second is dest
  if not onboard origin or not onboard dest:         // check if these are valid
    die "the board isn't that large";
  endif;
  set moved space origin;                            // look what we move
  if != moved elem 0 #parts and == 1 #i:             // input move mentioned another piece
    die "there is no " elem 0 parts " on " origin;
  endif;
  if not cond #player islower moved isupper moved:   // it is not our piece
    die "you have no piece on " origin;
  endif;
  set j 1;                                           // prepare to do side effects
  while < #j count #mvs:                             // for each of those
    set parts explode chr 45 trim elem #j #mvs;      // split them at hyphen
    if != 2 count #parts:                            // must give 2 parts
      die "malformed move " elem #j #mvs;
    elseif not onboard elem 1 #parts:                // second part must be valid square
      die "second leg goes off board";
    elseif onboard elem 0 #parts:                    // additional move for locust capture
      if != dest elem 0 #parts:                      // must start from destination of first move
        die "you can only continue with same piece";
      endif;
      if #suicide:                                   // for now only one side efect
        die "cannot have more than one locust victim";
      endif;
      set suicide dest;                              // old dest was actually locust square
      set dest elem 1 #parts;                        // and this is true destination
    elseif == dest elem 1 #parts:                    // drop on dest: promotion
      set promo elem 0 #parts;
    elseif == @ elem 0 #parts:                       // drop of empty: locust square
      if #suicide:
        die "cannot have more than one locust victim";
      endif;
      set suicide elem 1 #parts;
    else:                                            // drop of piece: unload
      if #freedrop:
        die "cannot kick more than one piece";
      endif;
      set dropped elem 0 #parts;
      set freedrop elem 1 #parts;
    endif;
    inc #j;                                          // go on with next side effect
  loop;
endsub;