/// <summary>Constructor using fen string </summary> /// <see cref="Board"/> /// <param name="fen">FEN string that will be parsed to a corresponding board position</param> /// <exception cref="InvalidBoardException"> /// Invlalid strings /// The fen string is interpeted as an array of string, if the array isn't in the correct length (6) /// It can and will throw an exception if any of the arguments provided is not by the fen standart /// </exception> public Grid(string fen) { Board = new Tile[8, 8]; string[] arr = fen.Split(' '); if (arr.Length != 6) { throw new InvalidFENBoardException("FEN string must have six arguments"); } //Initalize pieces section string[] boardState = arr[0].Split('/'); for (int i = 0; i < boardState.Length; i++) { int xPos = 0; foreach (char ch in boardState[i]) { int number; bool success = int.TryParse(ch.ToString(), out number); if (success) { for (int j = 0; j < number; j++) { Board[7 - i, xPos] = new Tile(null, xPos, 7 - i); xPos++; } } else { Piece piece = Piece.PieceIdentifier(ch); if (piece == null) { throw new InvalidFENBoardException("Invalid board state"); } Board[7 - i, xPos] = new Tile(piece, xPos, 7 - i); xPos++; } } } InitPieces(); //initialize currentplayer section string teamFlag = arr[1]; if (teamFlag.Length != 1) { throw new InvalidFENBoardException("Invalid player turn argument"); } if (teamFlag[0] == 'w') { CurrentPlayer = new Player(true); } else if (teamFlag[0] == 'b') { CurrentPlayer = new Player(false); } else { throw new InvalidFENBoardException("Invalid player turn argument"); } //Initialize castling rights section string castlingRights = arr[2]; if (castlingRights.Length > 4 || castlingRights.Length < 0) { throw new InvalidFENBoardException("Invalid castling rights argument"); } string temp = castlingRights.ToUpper(); foreach (char c in temp) { if (c != 'K' && c != 'Q' && c != '-') { throw new InvalidFENBoardException("Invalid castling rights argument"); } } Piece wKing = WhitePieces.Find(piece => piece is King && piece.IsWhite); King whiteKing = wKing as King; if (whiteKing == null) { throw new InvalidFENBoardException("Board missing white king"); } Piece bKing = BlackPieces.Find(piece => piece is King && !piece.IsWhite); King blackKing = bKing as King; if (blackKing == null) { throw new InvalidFENBoardException("Board missing black king"); } if (castlingRights == "-") { whiteKing.HasMoved = true; blackKing.HasMoved = true; } if (!castlingRights.Contains('K')) { whiteKing.kingSideCatlingDone = true; } if (!castlingRights.Contains('Q')) { whiteKing.queenSideCasltingDone = true; } if (!castlingRights.Contains('k')) { blackKing.kingSideCatlingDone = true; } if (!castlingRights.Contains('q')) { blackKing.queenSideCasltingDone = true; } //Initialize enpassant section string enpassant = arr[3]; if (enpassant != "-") { if (enpassant.Length != 2) { throw new InvalidFENBoardException("En passant argument must be 2 characters long"); } int row = (int)enpassant[0] - (int)'a'; int col = int.Parse(enpassant[1].ToString()); Tile pawnTile; if (col == 6) { pawnTile = GetTile(row, col - 2); } else if (col == 3) { pawnTile = GetTile(row, col); } else { throw new InvalidFENBoardException("En passant argument is invalid"); } Pawn pawn = pawnTile.Piece as Pawn; if (pawn == null) { throw new InvalidFENBoardException("En passant is invalid"); } pawn.CanBeCapturedEnPassant = true; } //Initialize 50 move rule count string fiftyMoveRule = arr[4]; int fiftyMoveRuleCount; bool isInt = int.TryParse(fiftyMoveRule, out fiftyMoveRuleCount); if (isInt) { if (fiftyMoveRuleCount >= 0) { FiftyMoveRuleCount = fiftyMoveRuleCount; } else { throw new InvalidFENBoardException("Fifty move rule argument must be a positive integer"); } } else { throw new InvalidFENBoardException("Fifty move rule argument must be an integer"); } //Initialize move count string FENMoveCount = arr[5]; int moveCount; isInt = int.TryParse(FENMoveCount, out moveCount); if (isInt) { if (moveCount > 0) { MoveCount = moveCount; } else { throw new InvalidFENBoardException("Move count argument must be greater than 0"); } } else { throw new InvalidFENBoardException("Move count argument must be an integer"); } UpdateGameState(); UpdateKilledPieces(); AllBoards.Add(CreateCopyOfBoard()); }
/// <summary> /// Returns the fen representation of the current board position /// <see cref="Board"/> /// </summary> /// <returns>The corresponding FEN string of the current board position</returns> public string FEN() { //Init board state section string res = ""; int emptySpacesCount = 0; for (int i = 7; i >= 0; i--) { for (int j = 0; j < 8; j++) { Tile tile = GetTile(j, i); if (tile.Piece != null) { if (emptySpacesCount != 0) { res += emptySpacesCount; } res += tile.Piece.ToString(); emptySpacesCount = 0; } else { emptySpacesCount++; } } if (emptySpacesCount != 0) { res += emptySpacesCount; } emptySpacesCount = 0; res += "/"; } res = res.TrimEnd('/'); //Init current player section if (CurrentPlayer.IsWhite) { res += " w "; } else { res += " b "; } //Init caslting right position Piece wKing = WhitePieces.Find(piece => piece is King); King whiteKing = wKing as King; if (whiteKing == null) { throw new InvalidBoardException("White king is missing"); } Piece bKing = BlackPieces.Find(piece => piece is King); King blackKing = bKing as King; if (blackKing == null) { throw new InvalidBoardException("Black king is missing"); } string castlingRights = ""; if (!whiteKing.HasMoved) { if (!whiteKing.kingSideCatlingDone) { Rook rightRook = GetTile(7, 0).Piece as Rook; if (rightRook != null && !rightRook.HasMoved) { castlingRights += 'K'; } } if (!whiteKing.queenSideCasltingDone) { Rook leftRook = GetTile(0, 0).Piece as Rook; if (leftRook != null && !leftRook.HasMoved) { castlingRights += 'Q'; } } } if (!blackKing.HasMoved) { if (!blackKing.kingSideCatlingDone) { Rook rightRook = GetTile(7, 7).Piece as Rook; if (rightRook != null && !rightRook.HasMoved) { castlingRights += 'k'; } } if (!blackKing.queenSideCasltingDone) { Rook leftRook = GetTile(0, 7).Piece as Rook; if (leftRook != null && !leftRook.HasMoved) { castlingRights += 'q'; } } } if (whiteKing.HasMoved && blackKing.HasMoved) { castlingRights = "-"; } res += castlingRights + " ";