Code: Select all
d4
exd
NxR
N2xRe4
...
1) I've added to my move generator the functions to extract all the generated moves at ply 1 in full format, for sample:
Code: Select all
Ne4xPf6
Code: Select all
d4 -> P??-d4
dxc -> Pd??xPc?
NxR -> N??xR??
NexQ -> Ne?xQ??
O-O -> Ke?-g?
...and so on...
This system has the advantage that I don't have to duplicate the move generator just to find what piece can move (dxc) or where it is (Re4) or where it goes (QxR). The same system can maybe used for any legal move generator in chess variants.
Just to know the detail, here's my code:
Code: Select all
bool clsGame::SetGame(const clsString &PGN, clsEngine *pEngine)
{
bool bRet = true;
nMoves = 0;
#define ILLEGAL_MOVE { bRet = false; break; }
result = pgnUnknown;
firstmove = 0;
clsCStrings ss(PGN, '\n');
clsString sOriginal;
clsString s;
clsString sParameter;
clsString sValue;
enum enPGNStates { pgnHeader, pgnMoves } state = pgnHeader;
for (int i = 0; i < ss.Count(); i++)
{
s = ss.cGet(i);
switch (state)
{
case pgnHeader:
if (s[0] == '[')
{
int iFound = 1; // salta '['
sParameter = s.Token(' ', iFound);
sValue = s.TokenDelimited('\"', '\"', iFound);
ssHeader.AddString(sParameter, sValue);
if (sParameter == "RESULT")
{
SetResult(sValue);
}
break;
}
state = pgnMoves;
case pgnMoves:
sOriginal += s;
sOriginal += " ";
break;
}
}
sOriginal.ReplaceThis("\n", " ")
.ReplaceThis("\r", " ")
.ReplaceThis(" ", " ")
.ReplaceThis(" ", " ")
.ReplaceThis("+", "")
.ReplaceThis("#", "")
;
pEngine->Init(STANDARD_CHESS_FEN);
for (int iFound = nMoves = 0; iFound >= 0 && bRet;)
{
clsString s = sOriginal.Token(' ', iFound).Trim();
#if DEBUG_PGN
sfout.Push(s + " -> ", false);
#endif
if (lgsIsBetween(s[0], '0', '9')) // 1. 2. ... N.
{
if (!firstmove) firstmove = s.GetInt(1);
#if DEBUG_PGN
sfout.Push(" move.");
#endif
}
else
{
if (s[0] == '{')
{
clsString sComment = s.xMid(1, s.Length() - 2);
//ssComments.AddString(clsString(nMoves), sComment);
}
else
{
if (s[0] == '1' || s[0] == '0')
{
SetResult(s);
}
else
{
if (pEngine->Perft(1) == 0) ILLEGAL_MOVE;
clsString sLegalMoves = pEngine->GetMoves(true);
clsCStrings ssLegals(sLegalMoves, ' ');
int idx = 0; // 0) test pezzo sorgente
if (s[idx] == 'O')
{
if (s == "O-O") s = "Ke?-g?";
else if (s == "O-O-O") s = "Ke?-c?";
else ILLEGAL_MOVE;
}
else
{
if (s.Length() == 2) s.InsertChar(0, 'P'); // d4
else if (!lgsIsBetween(s[idx], 'A', 'Z')) s.InsertChar(0, '?');
if (s.Length() == 3 && s[1]!='x') // Pd4 (!dxc !CxT...) -> P??d4
{
s.Insert(1, "??");
idx += 2;
}
else
{
++idx; // 1) test colonna sorgente
if (s[idx] == 'x') // Cx...
{
s.Insert(idx, "??");
++idx;
}
else
{
if (!lgsIsBetween(s[idx], 'a', 'h')) s.InsertChar(idx, '?');
++idx; // 2) test riga sorgente
if (s[idx] == 'x') // Cdx...
{
s.Insert(idx, "?");
}
else
{
if (!lgsIsBetween(s[idx], '1', '8')) s.InsertChar(idx, '?'); // Tad8
}
}
}
++idx; // 3) test pezzo destinazione
if (s[idx] == 'x')
{
++idx; // presa
if (!lgsIsBetween(s[idx], 'A', 'Z')) // pezzo preso
{
s.InsertChar(idx, '?');
}
}
else
{
s.InsertChar(idx, '-');
}
++idx; // 4) test colonna destinazione
if (!lgsIsBetween(s[idx], 'a', 'h')) // ...xT
{
s.InsertChar(idx, '?');
}
++idx; // 5) test riga destinazione
if (!lgsIsBetween(s[idx], '1', '8'))
{
s.InsertChar(idx, '?');
}
}
// cerca la mossa
bool bFound = false;
for (int i = 0; i < ssLegals.Count(); i++)
{
clsString sLegal = ssLegals.cGet(i);
bFound = true;
for (int c = 0; c < s.Length() && bFound; c++)
{
if (s[c] == '?') continue;
bFound = bFound && s[c] == sLegal[c];
}
if (bFound)
{
++nMoves;
clsString sCleanMove(sLegal);
sCleanMove.Validate("abcdefgh12345678");
sCleanMove += sLegal.TokenRight('=');
sMoves += sCleanMove + " ";
int val = 0;
switch(result)
{
case pgnWhiteWin: ++val; break;
case pgnBlackWin: --val; break;
case pgnDraw:
case pgnUnknown:
break;
}
clsString sFEN = pEngine->GetFEN();
if (int *pVal = book.GetItemByKey(sFEN)) *pVal += val;
else book.Add(sFEN, new int(val));
#if DEBUG_PGN
sfout.Push(s + " -> " + sLegal + " -> " + sCleanMove);
#endif
pEngine->UserMove(sCleanMove);
break;
}
}
if (!bFound)
{
#if DEBUG_PGN
sfout.Push(" : LEGAL MOVES: " + sLegalMoves);
#endif
ILLEGAL_MOVE;
}
#if DEBUG_PGN
pEngine->DebugBoard();
#endif
}
}
}
}
return bRet;
}

