/// <summary> /// Initializes new Piece by given color and type as:<br/> /// "wp" => White Pawn<br/> /// "br" => Black Rook<br/> /// See: piece.ToString()<br/> /// </summary> public Piece(string piece) { if (!Regexes.regexPiece.IsMatch(piece)) { throw new ChessArgumentException(null, "Piece should match pattern: " + Regexes.PiecePattern); } Color = PieceColor.FromChar(piece[0]); Type = PieceType.FromChar(piece[1]); }
internal static (bool succeeded, ChessException?exception) TryLoad(string fen, out FenBoardBuilder?builder) { builder = null; var matches = Regexes.regexFen.Matches(fen); if (matches.Count == 0) { return(false, new ChessArgumentException(null, "FEN board string should match pattern: " + Regexes.FenPattern)); } builder = new FenBoardBuilder(); foreach (var group in matches[0].Groups.Values) { switch (group.Name) { case "1": // Set pieces to given positions int x = 0, y = 7; for (int i = 0; i < group.Length; i++) { if (group.Value[i] == '/') { y--; x = 0; continue; } if (x < 8) { if (char.IsLetter(group.Value[i])) { builder.pieces[y, x] = new Piece(group.Value[i]); x++; } else if (char.IsDigit(group.Value[i])) { x += int.Parse(group.Value[i].ToString()); } } } break; case "3": builder.Turn = PieceColor.FromChar(group.Value[0]); break; case "4": if (group.Value != "-") { if (group.Value.Contains('K')) { builder.CastleWK = true; } if (group.Value.Contains('Q')) { builder.CastleWQ = true; } if (group.Value.Contains('k')) { builder.CastleBK = true; } if (group.Value.Contains('q')) { builder.CastleBQ = true; } } break; case "5": if (group.Value == "-") { builder.EnPassant = new(); } else { builder.EnPassant = new Position(group.Value); } break; case "6": (builder.HalfMoves, builder.FullMoves) = group.Value.Split(' ').Select(s => int.Parse(s)).ToArray(); break; } } var wcap = new List <Piece>(); var bcap = new List <Piece>(); var fpieces = builder.pieces.Cast <Piece>().Where(p => p is not null); // Calculating missing pieces on according begin pieces in fen // Math.Clamp() for get max/min taken figures (2 queens possible) wcap.AddRange(Enumerable.Range(0, Math.Clamp(8 - fpieces.Where(p => p.Type == PieceType.Pawn && p.Color == PieceColor.White).Count(), 0, 8)).Select(_ => new Piece(PieceColor.White, PieceType.Pawn))); wcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Rook && p.Color == PieceColor.White).Count(), 0, 2)).Select(_ => new Piece(PieceColor.White, PieceType.Rook))); wcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Bishop && p.Color == PieceColor.White).Count(), 0, 2)).Select(_ => new Piece(PieceColor.White, PieceType.Bishop))); wcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Knight && p.Color == PieceColor.White).Count(), 0, 2)).Select(_ => new Piece(PieceColor.White, PieceType.Knight))); wcap.AddRange(Enumerable.Range(0, Math.Clamp(1 - fpieces.Where(p => p.Type == PieceType.Queen && p.Color == PieceColor.White).Count(), 0, 1)).Select(_ => new Piece(PieceColor.White, PieceType.Queen))); bcap.AddRange(Enumerable.Range(0, Math.Clamp(8 - fpieces.Where(p => p.Type == PieceType.Pawn && p.Color == PieceColor.Black).Count(), 0, 8)).Select(_ => new Piece(PieceColor.Black, PieceType.Pawn))); bcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Rook && p.Color == PieceColor.Black).Count(), 0, 2)).Select(_ => new Piece(PieceColor.Black, PieceType.Rook))); bcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Bishop && p.Color == PieceColor.Black).Count(), 0, 2)).Select(_ => new Piece(PieceColor.Black, PieceType.Bishop))); bcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Knight && p.Color == PieceColor.Black).Count(), 0, 2)).Select(_ => new Piece(PieceColor.Black, PieceType.Knight))); bcap.AddRange(Enumerable.Range(0, Math.Clamp(1 - fpieces.Where(p => p.Type == PieceType.Queen && p.Color == PieceColor.Black).Count(), 0, 1)).Select(_ => new Piece(PieceColor.Black, PieceType.Queen))); builder.WhiteCaptured = wcap.ToArray(); builder.BlackCaptured = bcap.ToArray(); return(true, null); }