public override List <Move> FindMoves(Board board) { var moves = new List <Move>(); int[] indices = new int[] { -2, -1, 1, 2 }; foreach (int x in indices) { foreach (int y in indices) { if (Math.Abs(x) == Math.Abs(y)) { continue; } if (!Position.IsOnBoard((int)Position.Rank + y, (int)Position.File + x)) { continue; } var newPos = Position.MoveHoriz(x).MoveVert(y); bool enemyOccupied = (board[newPos]?.Color.Opposite() == this.Color); moves.Add(MoveBuilder.CreateNormalMove(this, newPos, enemyOccupied)); } } return(moves); }
private List <Move> GetMovesWithDirection(Board board, int vertIncrement, int horizIncrement) { var moves = new List <Move>(); int r = (int)Position.Rank; int f = (int)Position.File; while (true) { r = r + vertIncrement; f = f + horizIncrement; bool validPosition = (f <= 8 && f >= 1) && (r <= 8 && r >= 1); if (!validPosition) { break; } var newPos = new Position((File)f, (Rank)r); var currentPiece = board[newPos]; if (currentPiece != null) { if (currentPiece.Color != this.Color) { // We can't go any further, but we can take! moves.Add(MoveBuilder.CreateNormalMove(this, newPos, true)); } break; } moves.Add(MoveBuilder.CreateNormalMove(this, newPos, false)); } return(moves); }
private static Move DetermineMove(Board board, UCIChessMove uciMove) { string from = uciMove.From; string to = uciMove.To; var fromPos = Position.Parse(from); var toPos = Position.Parse(to); var fromPiece = board[fromPos]; int fileDiff = Math.Abs((int)fromPiece.Position.File - (int)toPos.File); if (fromPiece.Type == PieceType.King && (fileDiff == 3 || fileDiff == 4)) { King king = (King)fromPiece; Rook rook; if (fileDiff == 4) { rook = (Rook)board[File.A, fromPiece.Position.Rank]; } else { rook = (Rook)board[File.H, fromPiece.Position.Rank]; } return(MoveBuilder.CreateCastleMove(king, rook)); } if (uciMove.PromotionChar != null) { string promotionChar = uciMove.PromotionChar.ToUpper(); var promotionType = (from p in (PieceType[])Enum.GetValues(typeof(PieceType)) where p.ToNotationLetter().ToUpper() == promotionChar.ToUpper() select p).First(); var promotionMoves = MoveBuilder.CreatePromotionMoves((Pawn)fromPiece, toPos, board[toPos] != null); return((from m in promotionMoves where m.Promotion.NewPieceType.Type == promotionType select m).First()); } // Check for en passant var existingPieceRank = fromPiece.Position.Rank; var isCorrectRank = fromPiece.Color == PieceColor.Black ? existingPieceRank == Rank._4 : existingPieceRank == Rank._5; try { int vertDir = fromPiece.Color == PieceColor.White ? -1 : 1; var existingPieceTo = board[toPos]; var capturedPiecePos = toPos.MoveVert(vertDir); var capturedPiece = board[capturedPiecePos]; if (capturedPiece.Color == fromPiece.Color.Opposite() && capturedPiece.MoveHistory.Count == 1) { // This is an en passant return(MoveBuilder.CreateEnPassantMove((Pawn)fromPiece, toPos, capturedPiecePos)); } } catch { } // Only other option is that this is a normal move. return(MoveBuilder.CreateNormalMove(fromPiece, toPos, board[toPos] != null)); }
private List <Move> GetMovesInDirection(Board board, int vert, int horiz) { var moves = new List <Move>(); int currentRank = (int)Position.Rank; int currentFile = (int)Position.File; int magnitude = 1; while (true) { int newRank = currentRank + magnitude * vert; int newFile = currentFile + magnitude * horiz; var newPos = new Position((File)newFile, (Rank)newRank); if (!Position.IsOnBoard(newPos)) { break; } var currentPiece = board[newPos]; if (currentPiece != null) { if (currentPiece.Color != this.Color) { // We can take! moves.Add(MoveBuilder.CreateNormalMove(this, newPos, true)); } break; } moves.Add(MoveBuilder.CreateNormalMove(this, newPos, false)); magnitude++; } return(moves); }
private List <Move> GetCapturingMoves(Board board) { var capturingMoves = new List <Move>(); if (Position.File != File.A) { var leftDiagPosition = Position .MoveVert(IncrementDirection) .MoveHoriz(-1); if (IsPositionEnemyOccupied(board, leftDiagPosition)) { capturingMoves.Add(MoveBuilder.CreateNormalMove(this, leftDiagPosition, true)); } } if (Position.File != File.H) { var rightDiagPosition = Position .MoveVert(IncrementDirection) .MoveHoriz(1); if (IsPositionEnemyOccupied(board, rightDiagPosition)) { capturingMoves.Add(MoveBuilder.CreateNormalMove(this, rightDiagPosition, true)); } } return(capturingMoves); }
private List <Move> GetAdvancingMoves(Board board) { var moves = new List <Move>(); bool canMoveTwo = false; if ((Color == PieceColor.White && Position.Rank == Rank._2) || (Color == PieceColor.Black && Position.Rank == Rank._7)) { canMoveTwo = true; } var singleMovePos = Position.MoveVert(IncrementDirection); if (board[singleMovePos] == null) { moves.Add(MoveBuilder.CreateNormalMove(this, singleMovePos, false)); } else { // Can't move two if you can't move one canMoveTwo = false; } if (canMoveTwo) { var moveTwoPos = Position.MoveVert(IncrementDirection * 2); if (board[moveTwoPos] == null) { moves.Add(MoveBuilder.CreateNormalMove(this, moveTwoPos, false)); } } return(moves); }
public void KingCannotCastleIfRookAlreadyMoved() { var kingBoard = CreateBoardWithWhiteKingAt(new Position(File.E, Rank._1)); kingBoard.AddPiece(new PieceBuilder(PieceType.Rook) .As(PieceColor.White) .At(new Position(File.A, Rank._1)) .Create()); var rookStart = (from p in kingBoard.WhitePieces where p.Type == PieceType.Rook select p).First(); kingBoard = kingBoard.PerformMove(MoveBuilder.CreateNormalMove( rookStart, rookStart.Position.MoveVert(1), false)); var rookMoveBack = (from p in kingBoard.WhitePieces where p.Type == PieceType.Rook select p).First(); kingBoard = kingBoard.PerformMove(MoveBuilder.CreateNormalMove( rookMoveBack, rookMoveBack.Position.MoveVert(-1), false)); var rookBackWhereHeStarted = (from p in kingBoard.WhitePieces where p.Type == PieceType.Rook select p).First(); Assert.Equal(new Position(File.A, Rank._1), rookBackWhereHeStarted.Position); var moves = kingBoard.GetPossibleMoves(PieceColor.White); var castleMoves = (from m in moves where m.Type == MoveType.Castle select m).ToList(); Assert.Equal(castleMoves.Count, 0); }
private Move CheckCastleWithRookLocation(Board board, Position rookPos) { var pieceInPos = board[rookPos]; if (pieceInPos == null) { return(null); } if (pieceInPos.Type != PieceType.Rook) { return(null); } if (pieceInPos.Color != this.Color) { return(null); } if (pieceInPos.MoveHistory != null && pieceInPos.MoveHistory.Count > 0) { return(null); } int startFile = (int)rookPos.File; int myFile = (int)Position.File; int increment = (myFile > startFile) ? 1 : -1; // Rook is eligible. Check pieces in between. for (int f = startFile + increment; f != myFile; f += increment) { var pieceInFile = board[(File)f, Position.Rank]; if (pieceInFile != null) { return(null); } bool kingWillPassThroughThisSquare = Math.Abs(myFile - f) <= 2; if (kingWillPassThroughThisSquare) { var fakeMove = MoveBuilder.CreateNormalMove(this, new Position((File)f, Position.Rank), false); if (board.DoesMovePutKingInCheck(this.Color, fakeMove)) { return(null); } } } return(MoveBuilder.CreateCastleMove(this, (Rook)pieceInPos)); }
public void KingCannotMoveIntoCheck() { var board = Board.NewEmptyBoard(); var king = new PieceBuilder(PieceType.King) .As(PieceColor.White) .At(new Position(File.D, Rank._1)) .Create(); board.AddPiece(king); board.AddPiece(new PieceBuilder(PieceType.Rook) .As(PieceColor.Black) .At(new Position(File.E, Rank._8)) .Create()); var move = MoveBuilder.CreateNormalMove(king, new Position(File.E, Rank._1), false); bool putsMeInCheck = board.DoesMovePutKingInCheck(PieceColor.White, move); Assert.True(putsMeInCheck); }
private List <Move> FindKingNormalMoves(Board board) { var moves = new List <Move>(); for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { // Don't consider 'not moving' if (x == 0 && y == 0) { continue; } // Would this move take us 'out of bounds'? if (!Position.IsOnBoard((int)Position.Rank + y, (int)Position.File + x)) { continue; } var newPos = Position.MoveHoriz(x).MoveVert(y); var existingPiece = board[newPos]; if (existingPiece != null) { if (existingPiece.Color != this.Color) { // We can take! moves.Add(MoveBuilder.CreateNormalMove(this, newPos, true)); } } else { moves.Add(MoveBuilder.CreateNormalMove(this, newPos, false)); } } } return(moves); }
private List <Move> GetMovesInDirection <T>(Board board, bool positive) { var moves = new List <Move>(); bool isFile = typeof(T) == typeof(File); int currentValue = isFile ? (int)Position.File : (int)Position.Rank; int incrementValue = positive ? 1 : -1; for (int r = currentValue + incrementValue; r <= 8 && r >= 1; r += incrementValue) { Position newPos; if (isFile) { newPos = new Position((File)r, Position.Rank); } else { newPos = new Position(Position.File, (Rank)r); } var newPosPiece = board[newPos]; if (newPosPiece != null) { if (newPosPiece.Color != this.Color) { // Its not null, but its capturable moves.Add(MoveBuilder.CreateNormalMove(this, newPos, true)); } break; } moves.Add(MoveBuilder.CreateNormalMove(this, newPos, false)); } return(moves); }