public static string Encode(IReadOnlyPosition position, EncodingOptions options = EncodingOptions.None) { Debug.Assert(position != null); var s = new StringBuilder(80); // Encode the chessboard var board = Factory.Instance.CreateChessboardArray(position); for (int row = Chessboard.ROW_MAX; row >= Chessboard.ROW_MIN; --row) { int empty_cells = 0; for (int column = Chessboard.COLUMN_MIN; column <= Chessboard.COLUMN_MAX; ++column) { var cur_cell = new ChessboardCell(row, column); Players player; Pieces piece; if (board.IsPieceAt(cur_cell, out player, out piece)) { if (empty_cells != 0) { s.Append(empty_cells); empty_cells = 0; } s.Append(PieceToChar(player, piece)); } else { ++empty_cells; } } if (empty_cells != 0) { s.Append(empty_cells); empty_cells = 0; } if (row != Chessboard.ROW_MIN) { s.Append(ROWS_SEPARATOR); } } // Encode player to move s.Append(' '); s.Append(position.IsWhiteToMove ? FEN_WHITE_TO_MOVE : FEN_BLACK_TO_MOVE); // Encode castling availability s.Append(' '); if (!position.IsCanCastleShort(Players.White) && !position.IsCanCastleLong(Players.White) && !position.IsCanCastleShort(Players.Black) && !position.IsCanCastleLong(Players.Black)) { s.Append(FEN_NO_ONE_CAN_CASTLE); } else { if (position.IsCanCastleShort(Players.White)) { s.Append(FEN_WHITE_CAN_CASTLE_SHORT); } if (position.IsCanCastleLong(Players.White)) { s.Append(FEN_WHITE_CAN_CASTLE_LONG); } if (position.IsCanCastleShort(Players.Black)) { s.Append(FEN_BLACK_CAN_CASTLE_SHORT); } if (position.IsCanCastleLong(Players.Black)) { s.Append(FEN_BLACK_CAN_CASTLE_LONG); } } // Encode en passant caputre possibility s.Append(' '); int? capture_en_passant_column = position.CaptureEnPassantColumn; if (capture_en_passant_column.HasValue) { var cell = new ChessboardCell(position.IsWhiteToMove ? 5 : 2, capture_en_passant_column.Value); s.Append(cell.ToString()); } else { s.Append(FEN_CANNOT_CAPTURE_EN_PASSANT); } s.Append(' ').Append(position.HalfmoveClock); s.Append(' ').Append(options.HasFlag(EncodingOptions.SetMovesCountToOne) ? 1 : position.FullmoveNumber); return s.ToString(); }