public void FilterMoves(FixedArray moves, Color playerColor) { var oppositeColor = 1 - (int)playerColor; var player = this.playerBoards[(int)playerColor]; var opponent = this.playerBoards[oppositeColor]; int index = 0; int squeezed_index = 0; var innerArray = moves.InnerArray; int size = moves.Size; while (index < size) { var move = innerArray[index]; if (move.Type == MoveType.KingCastle) { innerArray[squeezed_index].From = move.From; innerArray[squeezed_index].To = move.To; innerArray[squeezed_index].Type = move.Type; innerArray[squeezed_index].Value = move.Value; ++squeezed_index; ++index; continue; } this.ProcessMove(move, playerColor); // TODO write "from direction" method if (!player.IsUnderAttack(player.King.GetSquare(), opponent)) { innerArray[squeezed_index].From = move.From; innerArray[squeezed_index].To = move.To; innerArray[squeezed_index].Type = move.Type; innerArray[squeezed_index].Value = move.Value; ++squeezed_index; } this.CancelLastMove(playerColor); ++index; } moves.Size = squeezed_index; }
public MovesArrayAllocator(int historySize, int maxMovesSize) { this.HistorySize = historySize; this.MaxMovesSize = maxMovesSize; AllocatedArrays = new FixedArray[HistorySize]; for (int i = 0; i < HistorySize; ++i) { AllocatedArrays[i] = new FixedArray(); var innerArray = new Move[MaxMovesSize]; for (int j = 0; j < MaxMovesSize; ++j) { innerArray[j] = new Move(Square.NoSquare, Square.NoSquare); } AllocatedArrays[i].InnerArray = innerArray; } CurrentIndex = -1; }
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); }