So, here's Execute():
Code: Select all
static void PositionExecute(Position * const positionptr, const Move move)
{
// This routine executes the given move for the given position.
// Save the move
if (positionptr->freemovelist.count == 0)
MoveListAppendNode(&positionptr->freemovelist, MoveNodeNew());
MoveNode * const movenodeptr = MoveListDetachTail(&positionptr->freemovelist);
movenodeptr->move = move;
MoveListAppendNode(&positionptr->usedmovelist, movenodeptr);
// Save the preserved position data
if (positionptr->freeppdlist.count == 0)
PpdListAppendNode(&positionptr->freeppdlist, PpdNodeNew());
PpdNode * const ppdnodeptr = PpdListDetachTail(&positionptr->freeppdlist);
ppdnodeptr->ppd.fss = positionptr->fss;
ppdnodeptr->ppd.apd = positionptr->apd;
ppdnodeptr->ppd.msig = positionptr->msig;
PpdListAppendNode(&positionptr->usedppdlist, ppdnodeptr);
// Set up locals: pointer abbreviations
Tracker * const trackerptr = &positionptr->tracker;
Man * const manvec = positionptr->board.manvec;
Hash * const msigptr = &positionptr->msig;
// Set up locals: move components
const Sq frsq = GetFrSq(move);
const Sq tosq = GetToSq(move);
const Man frman = GetFrMan(move);
const Man toman = GetToMan(move);
const Mc mc = GetMc(move);
// Set up locals: FEN scalars
const Color good = positionptr->fss.good;
const Color evil = positionptr->fss.evil;
const Cabs cabs = positionptr->fss.cabs;
const Sq epsq = positionptr->fss.epsq;
// Process motion according to move special case
switch (mc)
{
case McReg: // Regular
if (IsManNotVacant(toman))
{
TrackerCapture(trackerptr, tosq);
HashFoldManSq(msigptr, toman, tosq);
};
TrackerMovement(trackerptr, frsq, tosq);
manvec[frsq] = ManVacant;
manvec[tosq] = frman;
HashFoldManSqSq(msigptr, frman, frsq, tosq);
break;
case McEPC: // En passant
{
const Sq vpsq = NextSq[CvColorToAdvDir[evil]][epsq];
TrackerCapture(trackerptr, vpsq);
HashFoldManSq(msigptr, MapColorPieceToMan(evil, PiecePawn), vpsq);
TrackerMovement(trackerptr, frsq, tosq);
manvec[vpsq] = ManVacant;
manvec[frsq] = ManVacant;
manvec[tosq] = frman;
HashFoldManSqSq(msigptr, frman, frsq, tosq);
};
break;
case McCQS: // Castle queenside
case McCKS: // Castle kingside
{
const Castling castling = CvColorMcToCastling[good][mc];
const Sq r0sq = CvCastlingToRookHomeSq[castling];
const Sq r1sq = CvCastlingToRookAwaySq[castling];
const Man rookman = MapColorPieceToMan(good, PieceRook);
TrackerMovement(trackerptr, frsq, tosq);
TrackerMovement(trackerptr, r0sq, r1sq);
manvec[frsq] = ManVacant;
manvec[tosq] = frman;
HashFoldManSqSq(msigptr, frman, frsq, tosq);
manvec[r0sq] = ManVacant;
manvec[r1sq] = rookman;
HashFoldManSqSq(msigptr, rookman, r0sq, r1sq);
};
break;
case McPPN: // Pawn promotes to knight
case McPPB: // Pawn promotes to bishop
case McPPR: // Pawn promotes to rook
case McPPQ: // Pawn promotes to queen
{
const Man newman = MapColorPieceToMan(good, CvMcToPiece[mc]);
if (IsManNotVacant(toman))
{
TrackerCapture(trackerptr, tosq);
HashFoldManSq(msigptr, toman, tosq);
};
TrackerMovement(trackerptr, frsq, tosq);
TrackerPromote(trackerptr, tosq, newman);
manvec[frsq] = ManVacant;
manvec[tosq] = newman;
HashFoldManSq(msigptr, frman, frsq);
HashFoldManSq(msigptr, newman, tosq);
};
break;
default:
break;
};
// Update: Colors
positionptr->fss.good = evil;
positionptr->fss.evil = good;
// Update: Castling availability bits
if (cabs != CabsNone)
{
positionptr->fss.cabs = (cabs & CabsPreservation[frsq] & CabsPreservation[tosq]);
if (cabs != positionptr->fss.cabs)
{
HashFoldCabs(msigptr, cabs);
HashFoldCabs(msigptr, positionptr->fss.cabs);
};
};
// Update: En passant target square
if (IsSqNotNil(epsq))
HashFoldEpFile(msigptr, MapSqToFile(epsq));
positionptr->fss.epsq = SqNil;
if (IsManPawn(frman) && ((frsq ^ tosq) == (FileLen * 2)))
{
const Sq candepsq = NextSq[CvColorToAdvDir[good]][frsq];
if (PositionTestEpSqCandPhase1(positionptr, candepsq))
{
positionptr->fss.epsq = candepsq;
HashFoldEpFile(msigptr, MapSqToFile(positionptr->fss.epsq));
};
};
// Update: Half move counter
if (IsManPawn(frman) || IsManNotVacant(toman))
positionptr->fss.hmvc = 0;
else
positionptr->fss.hmvc++;
// Update: Full move number
if (IsColorWhite(positionptr->fss.good))
positionptr->fss.fmvn++;
// Regenerate auxiliary position data
PositionRegenerateApd(positionptr);
}