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 10:26 PM UTC:

Well, that did not work quite as planned. For one, the # does not seem to work in subroutines; I had to replace it by var everywhere. What caused me the worst headache was the afct that origin and dest seem to be protected variables; everything worked fine upto the point where sqrs became an array (f3 f5), but after set origin elem 0 var sqrs; the value of origen was not the expected f3, but @ ! After I change the names to ori, desti and mover the preset worked again. At least to the point where it did not die, and executed the entered moves. I don't manage to print the variables to see if they obtained the expected values; the page where I printed them flashed away too fast to read. I suppose I would have to intentionally let it die to see it.

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