public FixedArray GetMoves(PlayerBoard opponent, Move lastMove, MovesMask movesMask)
{
FixedArray moves = this.allocator.CreateNewArray();
var innerArray = moves.InnerArray;
int index = 0;
ulong mask = 0;
if (movesMask == MovesMask.AllMoves)
mask = ~this.allFigures;
else
mask = opponent.allFigures;
var opponentFigures = opponent.allFigures;
var otherFigures = opponentFigures | this.allFigures;
// add knight, bishop, rook, queen moves
for (int i = 0; i < PlayerBoard.KnightBishopRookQueen.Length; ++i)
{
var figure = PlayerBoard.KnightBishopRookQueen[i];
var newMovesList = this.moveGenerators[(int)figure].GetMoves(otherFigures, mask);
for (int j = 0; j < newMovesList.Count; ++j)
{
var newMovesArray = newMovesList[j];
for (int k = 0; k < newMovesArray.Length; ++k)
{
var item = newMovesArray[k];
innerArray[index].From = item.From;
innerArray[index].To = item.To;
int destinationFigure = (int)opponent.figures[(int)item.To];
innerArray[index].Type =
BitBoardHelper.MoveTypes[(int)figure][destinationFigure][(int)item.From][(int)item.To];
innerArray[index].Value = (int)innerArray[index].Type * MoveTypeWeight +
(int)opponent.figures[(int)item.To];
index++;
}
}
}
// add king moves
var kingMoves = this.GetKingMoves(opponent, mask, movesMask);
for (int j = 0; j < kingMoves.Count; ++j)
{
var newMovesArray = kingMoves[j];
for (int k = 0; k < newMovesArray.Length; ++k)
{
var item = newMovesArray[k];
innerArray[index].From = item.From;
innerArray[index].To = item.To;
int destinationFigure = (int)opponent.figures[(int)item.To];
if (Math.Abs((int)item.From - (int)item.To) == 2)
innerArray[index].Type = MoveType.KingCastle;
else
innerArray[index].Type =
BitBoardHelper.MoveTypes[(int)Figure.King][destinationFigure][(int)item.From][(int)item.To];
innerArray[index].Value = (int)innerArray[index].Type * MoveTypeWeight +
(int)opponent.figures[(int)item.To];
index++;
}
}
// add to mask value
mask = opponent.allFigures;
// pawn in passing state bit
int lastFrom = (int)lastMove.From;
int lastTo = (int)lastMove.To;
int middle = (lastFrom + lastTo) >> 1;
bool wasLastMovePassing = false;
if (Math.Abs(lastFrom - lastTo) == 16)
if (opponent.Pawns.IsBitSet(lastMove.To))
{
mask |= 1UL << middle;
otherFigures |= mask;
wasLastMovePassing = true;
}
if (movesMask == MovesMask.Attacks)
{
ulong pawns = this.bitboards[(int)Figure.Pawn].GetInnerValue();
otherFigures |= pawns >> 8;
otherFigures |= pawns << 8;
}
// add pawns moves
var pawnMoves = this.moveGenerators[(int)Figure.Pawn].GetMoves(otherFigures, mask);
int moveTo;
for (int j = 0; j < pawnMoves.Count; ++j)
{
var newMovesArray = pawnMoves[j];
for (int k = 0; k < newMovesArray.Length; ++k)
{
var item = innerArray[index];
item.From = newMovesArray[k].From;
item.To = newMovesArray[k].To;
moveTo = (int)item.To;
int destinationFigure = (int)opponent.figures[(int)item.To];
item.Value = (int)opponent.figures[(int)item.To];
item.Type = BitBoardHelper.MoveTypes[(int)Figure.Pawn][destinationFigure][(int)item.From][moveTo];
if (wasLastMovePassing)
if (item.To == (Square)middle)
item.Type = MoveType.EpCapture;
if ((moveTo < 8) ||
(moveTo >= 56))
{
// add 4 moves
for (int m = 1; m < 4; ++m)
{
innerArray[index + m].From = item.From;
innerArray[index + m].To = item.To;
innerArray[index + m].Value = (int)opponent.figures[(int)item.To];
}
this.AddPromotionMoves(innerArray, index, (Figure)j);
index += 3;
}
else
item.Value += (int)item.Type;
index++;
}
}
moves.Size = index;
return moves;
}