private IEnumerable <ChessDraw> getForewardDraws(IChessBoard board, ChessPosition drawingPiecePosition) { var draws = new List <ChessDraw>(); var piece = board.GetPieceAt(drawingPiecePosition); var coordsPosOneForeward = new Tuple <int, int>(drawingPiecePosition.Row + (piece.Color == ChessColor.White ? 1 : -1), drawingPiecePosition.Column); var coordsPosTwoForeward = new Tuple <int, int>(drawingPiecePosition.Row + (piece.Color == ChessColor.White ? 2 : -2), drawingPiecePosition.Column); if (ChessPosition.AreCoordsValid(coordsPosOneForeward)) { var posOneForeward = new ChessPosition(coordsPosOneForeward); bool oneForeward = !board.IsCapturedAt(posOneForeward); if (oneForeward) { draws.Add(new ChessDraw(board, drawingPiecePosition, posOneForeward)); if (!piece.WasMoved && ChessPosition.AreCoordsValid(coordsPosTwoForeward)) { var posTwoForeward = new ChessPosition(coordsPosTwoForeward); if (!board.IsCapturedAt(posTwoForeward)) { draws.Add(new ChessDraw(board, drawingPiecePosition, posTwoForeward)); } } } } return(draws); }
private IEnumerable <ChessPosition> getStandardDrawPositions(ChessPosition position) { // get positions next to the current position of the king (all permutations of { -1, 0, +1 }^2 except (0, 0)) var coords = new Tuple <int, int>[] { new Tuple <int, int>(position.Row - 1, position.Column - 1), new Tuple <int, int>(position.Row - 1, position.Column), new Tuple <int, int>(position.Row - 1, position.Column + 1), new Tuple <int, int>(position.Row, position.Column - 1), new Tuple <int, int>(position.Row, position.Column + 1), new Tuple <int, int>(position.Row + 1, position.Column - 1), new Tuple <int, int>(position.Row + 1, position.Column), new Tuple <int, int>(position.Row + 1, position.Column + 1), }; // only retrieve positions that are actually onto the chess board (and not off scale) var positions = coords.Where(x => ChessPosition.AreCoordsValid(x)).Select(x => new ChessPosition(x.Item1, x.Item2)); return(positions); }
/// <summary> /// Compute the field positions that can be captured by the given chess piece. /// </summary> /// <param name="board">The chess board representing the game situation</param> /// <param name="drawingPiecePosition">The chess position of the chess piece to be drawn</param> /// <param name="precedingEnemyDraw">The last draw made by the opponent</param> /// <param name="analyzeDrawIntoCheck">Indicates whether drawing into a check situation should be analyzed</param> /// <returns>a list of all possible chess draws</returns> public IEnumerable <ChessDraw> GetDraws(IChessBoard board, ChessPosition drawingPiecePosition, ChessDraw?precedingEnemyDraw = null, bool analyzeDrawIntoCheck = false) { var piece = board.GetPieceAt(drawingPiecePosition); // make sure the chess piece is a knight if (piece.Type != ChessPieceType.Knight) { throw new InvalidOperationException("The chess piece is not a knight."); } // get positions next to the current position of the king (all permutations of { -1, 0, +1 }^2 except (0, 0)) var coords = new Tuple <int, int>[] { new Tuple <int, int>(drawingPiecePosition.Row - 2, drawingPiecePosition.Column - 1), new Tuple <int, int>(drawingPiecePosition.Row - 2, drawingPiecePosition.Column + 1), new Tuple <int, int>(drawingPiecePosition.Row - 1, drawingPiecePosition.Column - 2), new Tuple <int, int>(drawingPiecePosition.Row - 1, drawingPiecePosition.Column + 2), new Tuple <int, int>(drawingPiecePosition.Row + 1, drawingPiecePosition.Column - 2), new Tuple <int, int>(drawingPiecePosition.Row + 1, drawingPiecePosition.Column + 2), new Tuple <int, int>(drawingPiecePosition.Row + 2, drawingPiecePosition.Column - 1), new Tuple <int, int>(drawingPiecePosition.Row + 2, drawingPiecePosition.Column + 1), }; // only retrieve positions that are actually onto the chess board (and not off scale) var positions = coords.Where(x => ChessPosition.AreCoordsValid(x)).Select(x => new ChessPosition(x)); // do not draw into positions captured by allied chess pieces positions = positions.Where(x => !board.IsCapturedAt(x) || board.GetPieceAt(x).Color != piece.Color); // transform positions to chess draws var draws = positions.Select(newPos => new ChessDraw(board, drawingPiecePosition, newPos)); if (analyzeDrawIntoCheck && draws?.Count() > 0) { // remove draws that would draw into a check situation draws = draws.Where(x => !ChessDrawSimulator.Instance.IsDrawIntoCheck(board, x)); } return(draws); }
private IEnumerable <ChessDraw> getCatchDraws(IChessBoard board, ChessPosition drawingPiecePosition, ChessDraw?precedingEnemyDraw = null) { var draws = new List <ChessDraw>(); var piece = board.GetPieceAt(drawingPiecePosition); // get the possible chess field positions (info: right / left from the point of view of the white side player) var coordsPosCatchLeft = new Tuple <int, int>(drawingPiecePosition.Row + (piece.Color == ChessColor.White ? 1 : -1), drawingPiecePosition.Column + 1); var coordsPosCatchRight = new Tuple <int, int>(drawingPiecePosition.Row + (piece.Color == ChessColor.White ? 1 : -1), drawingPiecePosition.Column - 1); // check for en-passant precondition bool wasLastDrawPeasantDoubleForeward = precedingEnemyDraw != null && precedingEnemyDraw.Value.DrawingPieceType == ChessPieceType.Peasant && Math.Abs(precedingEnemyDraw.Value.OldPosition.Row - precedingEnemyDraw.Value.NewPosition.Row) == 2; // check if left catch / en-passant is possible if (ChessPosition.AreCoordsValid(coordsPosCatchLeft)) { var posCatchLeft = new ChessPosition(coordsPosCatchLeft); bool catchLeft = board.IsCapturedAt(posCatchLeft) && board.GetPieceAt(posCatchLeft).Color != piece.Color; if (catchLeft) { draws.Add(new ChessDraw(board, drawingPiecePosition, posCatchLeft)); } if (wasLastDrawPeasantDoubleForeward) { // get the positions of an enemy chess piece taken by a possible en-passant var posEnPassantEnemyLeft = new ChessPosition(drawingPiecePosition.Row, drawingPiecePosition.Column + 1); bool isLeftFieldCapturedByEnemy = precedingEnemyDraw.Value.NewPosition == posEnPassantEnemyLeft && board.IsCapturedAt(posEnPassantEnemyLeft) && board.GetPieceAt(posEnPassantEnemyLeft).Color != piece.Color; bool enPassantLeft = isLeftFieldCapturedByEnemy && Math.Abs(posEnPassantEnemyLeft.Column - drawingPiecePosition.Column) == 1; if (enPassantLeft) { draws.Add(new ChessDraw(board, drawingPiecePosition, posCatchLeft)); } } } // check if right catch / en-passant is possible if (ChessPosition.AreCoordsValid(coordsPosCatchRight)) { var posCatchRight = new ChessPosition(coordsPosCatchRight); bool catchRight = board.IsCapturedAt(posCatchRight) && board.GetPieceAt(posCatchRight).Color != piece.Color; if (catchRight) { draws.Add(new ChessDraw(board, drawingPiecePosition, posCatchRight)); } if (wasLastDrawPeasantDoubleForeward) { // get the positions of an enemy chess piece taken by a possible en-passant var posEnPassantEnemyRight = new ChessPosition(drawingPiecePosition.Row, drawingPiecePosition.Column - 1); bool isRightFieldCapturedByEnemy = precedingEnemyDraw.Value.NewPosition == posEnPassantEnemyRight && board.IsCapturedAt(posEnPassantEnemyRight) && board.GetPieceAt(posEnPassantEnemyRight).Color != piece.Color; bool enPassantRight = isRightFieldCapturedByEnemy && Math.Abs(posEnPassantEnemyRight.Column - drawingPiecePosition.Column) == 1; if (enPassantRight) { draws.Add(new ChessDraw(board, drawingPiecePosition, posCatchRight)); } } } return(draws); }
/// <summary> /// Compute the field positions that can be captured by the given chess piece. /// </summary> /// <param name="board">The chess board representing the game situation</param> /// <param name="drawingPiecePosition">The chess position of the chess piece to be drawn</param> /// <param name="precedingEnemyDraw">The last draw made by the opponent</param> /// <param name="analyzeDrawIntoCheck">Indicates whether drawing into a check situation should be analyzed</param> /// <returns>a list of all possible chess draws</returns> public IEnumerable <ChessDraw> GetDraws(IChessBoard board, ChessPosition drawingPiecePosition, ChessDraw?precedingEnemyDraw = null, bool analyzeDrawIntoCheck = false) { var piece = board.GetPieceAt(drawingPiecePosition); // make sure the chess piece is bishop-like if (piece.Type != ChessPieceType.Bishop && piece.Type != ChessPieceType.Queen) { throw new InvalidOperationException("The chess piece is not a bishop."); } var draws = new List <ChessDraw>(); // get upper left-side draws for (int i = 1; i < 8; i++) { // get position and make sure it is valid (otherwise exit loop) var coords = new Tuple <int, int>(drawingPiecePosition.Row + i, drawingPiecePosition.Column - i); if (!ChessPosition.AreCoordsValid(coords)) { break; } var newPos = new ChessPosition(coords); if (!board.IsCapturedAt(newPos) || board.GetPieceAt(newPos).Color != piece.Color) { draws.Add(new ChessDraw(board, drawingPiecePosition, newPos)); } if (board.IsCapturedAt(newPos)) { break; } } // get lower left-side draws for (int i = 1; i < 8; i++) { // get position and make sure it is valid (otherwise exit loop) var coords = new Tuple <int, int>(drawingPiecePosition.Row - i, drawingPiecePosition.Column - i); if (!ChessPosition.AreCoordsValid(coords)) { break; } var newPos = new ChessPosition(coords); if (!board.IsCapturedAt(newPos) || board.GetPieceAt(newPos).Color != piece.Color) { draws.Add(new ChessDraw(board, drawingPiecePosition, newPos)); } if (board.IsCapturedAt(newPos)) { break; } } // get upper right-side draws for (int i = 1; i < 8; i++) { // get position and make sure it is valid (otherwise exit loop) var coords = new Tuple <int, int>(drawingPiecePosition.Row + i, drawingPiecePosition.Column + i); if (!ChessPosition.AreCoordsValid(coords)) { break; } var newPos = new ChessPosition(coords); if (!board.IsCapturedAt(newPos) || board.GetPieceAt(newPos).Color != piece.Color) { draws.Add(new ChessDraw(board, drawingPiecePosition, newPos)); } if (board.IsCapturedAt(newPos)) { break; } } // get lower right-side draws for (int i = 1; i < 8; i++) { // get position and make sure it is valid (otherwise exit loop) var coords = new Tuple <int, int>(drawingPiecePosition.Row - i, drawingPiecePosition.Column + i); if (!ChessPosition.AreCoordsValid(coords)) { break; } var newPos = new ChessPosition(coords); if (!board.IsCapturedAt(newPos) || board.GetPieceAt(newPos).Color != piece.Color) { draws.Add(new ChessDraw(board, drawingPiecePosition, newPos)); } if (board.IsCapturedAt(newPos)) { break; } } // analyze draw into a check situation if (analyzeDrawIntoCheck && draws?.Count() > 0) { draws = draws.Where(draw => !ChessDrawSimulator.Instance.IsDrawIntoCheck(board, draw)).ToList(); } return(draws); }