The routine is called EMP() for "Enumerate move paths".
This was written for the OpenCL environment which does not support recursive routines or pointers to routines.
Much can be added. It would be possible to implement a checkpoint/restart capability which would save/restore the routine's internal state. Also, instead of doing perft(), a non recursive Search() routine could be implemented in the same style.
Code: Select all
// Movepath enumeration
NodeCount EMP(Position *positionptr, const ui draft)
{
typedef enum
{
EsInit,
EsInitPly,
EsExecute,
EsTermPly,
EsTerm,
EsExit
} Es;
NodeCount total;
Es state = EsInit;
ui ply;
ui segbase[PlyLen];
ui seglength[PlyLen];
ui segindex[PlyLen];
Move movestack[PlyLen * MoveGenLen];
while (state != EsExit)
switch (state)
{
case EsInit:
total = 0;
ply = 0;
segbase[ply] = 0;
state = EsInitPly;
break;
case EsInitPly:
if (ply == draft)
{
total++;
state = EsTermPly;
}
else
{
if (ply > 0)
segbase[ply] = segbase[ply - 1] + seglength[ply - 1];
seglength[ply] = PositionGeneratePseudolegal(positionptr, &movestack[segbase[ply]]);
segindex[ply] = 0;
state = EsExecute;
};
break;
case EsExecute:
if (segindex[ply] == seglength[ply])
state = EsTermPly;
else
{
PositionExecute(positionptr, &movestack[segbase[ply] + segindex[ply]]);
segindex[ply]++;
if (PositionEvilInCheck(positionptr))
{
PositionRetract(positionptr);
state = EsExecute;
}
else
{
ply++;
state = EsInitPly;
};
};
break;
case EsTermPly:
if (ply == 0)
state = EsTerm;
else
{
ply--;
PositionRetract(positionptr);
state = EsExecute;
};
break;
case EsTerm:
state = EsExit;
break;
default:
break;
};
return total;
}
