public bool IsUnderAttack(Square sq, PlayerBoard opponentBoard) { ulong occupied = 1UL << (int)sq; ulong pawnAttacks = opponentBoard.GetPawnAttacks(); if ((occupied & pawnAttacks) != 0) { return(true); } ulong knights = opponentBoard.bitboards[(int)Figure.Knight].GetInnerValue(); ulong king = opponentBoard.bitboards[(int)Figure.King].GetInnerValue(); ulong otherFigures = opponentBoard.allFigures | this.allFigures; otherFigures &= (~occupied); var knightAttackGenerator = this.attacksGenerators[(int)Figure.Knight]; ulong occupiedKnightMoves = knightAttackGenerator.GetAttacks(sq, otherFigures); if ((occupiedKnightMoves & knights) != 0) { return(true); } var kingAttackGenerator = this.attacksGenerators[(int)Figure.King]; ulong occupiedKingMoves = kingAttackGenerator.GetAttacks(sq, otherFigures); if ((occupiedKingMoves & king) != 0) { return(true); } ulong rooksQueens = opponentBoard.GetRooksQueens(); ulong bishopsQueens = opponentBoard.GetBishopsQueens(); var rookAttackGenerator = this.attacksGenerators[(int)Figure.Rook]; ulong occupiedRookMoves = rookAttackGenerator.GetAttacks(sq, otherFigures); if ((occupiedRookMoves & rooksQueens) != 0) { return(true); } var bishopAttackGenerator = this.attacksGenerators[(int)Figure.Bishop]; ulong occupiedBishopMoves = bishopAttackGenerator.GetAttacks(sq, otherFigures); if ((occupiedBishopMoves & bishopsQueens) != 0) { return(true); } return(false); }
private bool AreNoMoves(PlayerBoard player, PlayerBoard opponent) { var moves = player.GetMoves(opponent, this.History.GetLastMove(), MovesMask.AllMoves); this.FilterMoves(moves, player.FigureColor); bool result = (moves.Size == 0); this.allocator.ReleaseLast(); return(result); }
private bool AreNoMoves(PlayerBoard player, PlayerBoard opponent) { var moves = player.GetMoves(opponent, this.History.GetLastMove(), MovesMask.AllMoves); this.FilterMoves(moves, player.FigureColor); bool result = (moves.Size == 0); this.allocator.ReleaseLast(); return result; }
public bool IsUnderCheck(PlayerBoard opponent) { return(IsUnderAttack(this.King.GetSquare(), opponent)); }
public List <Move[]> GetKingMoves(PlayerBoard opponent, ulong mask, MovesMask movesMask) { var otherFigures = opponent.allFigures | this.allFigures; var list = this.moveGenerators[(int)Figure.King].GetMoves(otherFigures, mask); // --------------------------------------------- // castlings stuff // check king can move if (this.King.AlreadyMoved != 0) { return(list); } var rooks = this.Rooks; // if rooks cannot move if (rooks.GetInnerProperty() == 0) { return(list); } if (movesMask == MovesMask.Attacks) { return(list); } var allMasks = KingBitBoardHelper.CastlingMasks; ulong[] castlingMasks = allMasks[(int)this.color][(int)this.position]; bool leftIsEmpty = (castlingMasks[0] & otherFigures) == 0; bool rightIsEmpty = (castlingMasks[1] & otherFigures) == 0; // check other figures if (!(leftIsEmpty || rightIsEmpty)) { return(list); } bool noCheck; var squares = KingBitBoardHelper.CastlingSquares[(int)this.color][(int)this.position]; int resultIndex = -1; // check checks if (leftIsEmpty && (rooks.LeftNotMoved != 0)) { noCheck = true; for (int i = 0; i < squares[0].Length; ++i) { if (this.IsUnderAttack(squares[0][i], opponent)) { noCheck = false; break; } } if (noCheck) { resultIndex = 0; } } if (rightIsEmpty && (rooks.RightNotMoved != 0)) { noCheck = true; for (int i = 0; i < squares[1].Length; ++i) { if (this.IsUnderAttack(squares[1][i], opponent)) { noCheck = false; break; } } if (noCheck) { resultIndex += 2; } } if (resultIndex != -1) { list.Add(KingBitBoardHelper.CastlingMoves[(int)this.color][(int)this.position][resultIndex]); } return(list); }
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); }
public bool IsUnderCheck(PlayerBoard opponent) { return IsUnderAttack(this.King.GetSquare(), opponent); }
public bool IsUnderAttack(Square sq, PlayerBoard opponentBoard) { ulong occupied = 1UL << (int)sq; ulong pawnAttacks = opponentBoard.GetPawnAttacks(); if ((occupied & pawnAttacks) != 0) return true; ulong knights = opponentBoard.bitboards[(int)Figure.Knight].GetInnerValue(); ulong king = opponentBoard.bitboards[(int)Figure.King].GetInnerValue(); ulong otherFigures = opponentBoard.allFigures | this.allFigures; otherFigures &= (~occupied); var knightAttackGenerator = this.attacksGenerators[(int)Figure.Knight]; ulong occupiedKnightMoves = knightAttackGenerator.GetAttacks(sq, otherFigures); if ((occupiedKnightMoves & knights) != 0) return true; var kingAttackGenerator = this.attacksGenerators[(int)Figure.King]; ulong occupiedKingMoves = kingAttackGenerator.GetAttacks(sq, otherFigures); if ((occupiedKingMoves & king) != 0) return true; ulong rooksQueens = opponentBoard.GetRooksQueens(); ulong bishopsQueens = opponentBoard.GetBishopsQueens(); var rookAttackGenerator = this.attacksGenerators[(int)Figure.Rook]; ulong occupiedRookMoves = rookAttackGenerator.GetAttacks(sq, otherFigures); if ((occupiedRookMoves & rooksQueens) != 0) return true; var bishopAttackGenerator = this.attacksGenerators[(int)Figure.Bishop]; ulong occupiedBishopMoves = bishopAttackGenerator.GetAttacks(sq, otherFigures); if ((occupiedBishopMoves & bishopsQueens) != 0) return true; return false; }
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; }
public List<Move[]> GetKingMoves(PlayerBoard opponent, ulong mask, MovesMask movesMask) { var otherFigures = opponent.allFigures | this.allFigures; var list = this.moveGenerators[(int)Figure.King].GetMoves(otherFigures, mask); // --------------------------------------------- // castlings stuff // check king can move if (this.King.AlreadyMoved != 0) return list; var rooks = this.Rooks; // if rooks cannot move if (rooks.GetInnerProperty() == 0) return list; if (movesMask == MovesMask.Attacks) return list; var allMasks = KingBitBoardHelper.CastlingMasks; ulong[] castlingMasks = allMasks[(int)this.color][(int)this.position]; bool leftIsEmpty = (castlingMasks[0] & otherFigures) == 0; bool rightIsEmpty = (castlingMasks[1] & otherFigures) == 0; // check other figures if (!(leftIsEmpty || rightIsEmpty)) return list; bool noCheck; var squares = KingBitBoardHelper.CastlingSquares[(int)this.color][(int)this.position]; int resultIndex = -1; // check checks if (leftIsEmpty && (rooks.LeftNotMoved != 0)) { noCheck = true; for (int i = 0; i < squares[0].Length; ++i) { if (this.IsUnderAttack(squares[0][i], opponent)) { noCheck = false; break; } } if (noCheck) resultIndex = 0; } if (rightIsEmpty && (rooks.RightNotMoved != 0)) { noCheck = true; for (int i = 0; i < squares[1].Length; ++i) { if (this.IsUnderAttack(squares[1][i], opponent)) { noCheck = false; break; } } if (noCheck) resultIndex += 2; } if (resultIndex != -1) list.Add(KingBitBoardHelper.CastlingMoves[(int)this.color][(int)this.position][resultIndex]); return list; }