/// <summary> /// Attempts to parse a move string in coordinate or long algebraic format. /// </summary> /// <param name="pos"></param> /// <param name="moveStr"></param> /// <param name="move"></param> /// <returns></returns> private static bool TryParseMoveCoordinateOrAlgebraic(MGPosition pos, string moveStr, out MGMove move) { moveStr = moveStr.ToLower(); // Sometimes promotions to Knight use the "k" instead of expected "n" if (moveStr.EndsWith("k")) { moveStr = moveStr.Substring(0, moveStr.Length - 1) + "n"; } MGMoveList moves = new MGMoveList(); MGMoveGen.GenerateMoves(in pos, moves); foreach (MGMove moveTry in moves.MovesArray) { // Accept moves in any of multiple formats, including Chess 960 (for castling variation) if (String.Equals(moveTry.MoveStr(MGMoveNotationStyle.LC0Coordinate), moveStr, StringComparison.OrdinalIgnoreCase) || String.Equals(moveTry.MoveStr(MGMoveNotationStyle.LC0Coordinate960Format), moveStr, StringComparison.OrdinalIgnoreCase) || String.Equals(moveTry.MoveStr(MGMoveNotationStyle.LongAlgebraic), moveStr, StringComparison.OrdinalIgnoreCase)) { move = moveTry; return(true); } } move = default; return(false); }
/// <summary> /// Attempts to parse a move string in coordinate or long algebraic format. /// </summary> /// <param name="pos"></param> /// <param name="moveStr"></param> /// <param name="move"></param> /// <returns></returns> private static bool TryParseMoveCoordinateOrAlgebraic(MGPosition pos, string moveStr, out MGMove move) { moveStr = moveStr.ToLower(); // Sometimes promotions to Knight use the "k" instead of expected "n" if (moveStr.EndsWith("k")) { moveStr = moveStr.Substring(0, moveStr.Length - 1) + "n"; } MGMoveList moves = new MGMoveList(); MGMoveGen.GenerateMoves(in pos, moves); foreach (MGMove moveTry in moves.MovesArray) { if (moveTry.MoveStr(MGMoveNotationStyle.LC0Coordinate).ToLower() == moveStr || (moveTry.MoveStr(MGMoveNotationStyle.LongAlgebraic).ToLower() == moveStr)) { move = moveTry; return(true); } } move = default; return(false); }
/// <summary> /// Copy constructor. /// </summary> /// <param name="other"></param> public MGMoveList(MGMoveList other) { NumMovesUsed = other.NumMovesUsed; // Allocate and initialize move array of exactly correct size MovesArray = GC.AllocateUninitializedArray <MGMove>(other.NumMovesUsed); Array.Copy(other.MovesArray, MovesArray, NumMovesUsed); }
static void TestZZ(string fen) { MGPosition curPosition = MGChessPositionConverter.MGChessPositionFromFEN(fen); // Generate moves MGMoveList moves = new MGMoveList(); MGMoveGen.GenerateMoves(in curPosition, moves); foreach (var move in moves) { Console.WriteLine(move + " " + MoveStr(curPosition.AsPosition, move)); } }
public static string AlgebraicMoveString(MGMove mgMove, Position pos) { string ret = null; bool white = pos.MiscInfo.SideToMove == SideType.White; MGPosition curPosition = MGChessPositionConverter.MGChessPositionFromFEN(pos.FEN); // Generate moves MGMoveList moves = new MGMoveList(); MGMoveGen.GenerateMoves(in curPosition, moves); //if (white) mgMove = new MGMove(mgMove, true); MGPosition newPosition = MGChessPositionConverter.MGChessPositionFromFEN(pos.FEN); newPosition.MakeMove(mgMove); bool isCheck = MGMoveGen.IsInCheck(newPosition, white); if (mgMove.CastleShort) { ret = "O-O"; } else if (mgMove.CastleLong) { ret = "O-O-O"; } else { Square fromSquare = mgMove.FromSquare; Square toSquare = mgMove.ToSquare; Piece fromType = pos.PieceOnSquare(fromSquare); Piece toPiece = pos.PieceOnSquare(toSquare); if (fromType.Type == PieceType.Pawn) { string promoteChar = ""; if (mgMove.PromoteQueen) { promoteChar = "Q"; } if (mgMove.PromoteBishop) { promoteChar = "B"; } if (mgMove.PromoteRook) { promoteChar = "R"; } if (mgMove.PromoteKnight) { promoteChar = "N"; } if (mgMove.EnPassantCapture) { int newRank = white ? 6 : 3; char newFile = char.ToLower(toSquare.FileChar); ret = fromSquare.ToString().Substring(0, 1).ToLower() + "x" + newFile + newRank; } else if (toPiece.Type == PieceType.None) { ret = toSquare.ToString().ToLower() + promoteChar; } else { ret = fromSquare.ToString().Substring(0, 1).ToLower() + "x" + toSquare.ToString().ToLower() + promoteChar; } } else { string captureChar = toPiece.Type == PieceType.None ? "" : "x"; List <MGMove> matchingCaptures = MovesByPieceTypeThatTakeOnSquare(mgMove.Piece, mgMove.ToSquareIndex, moves); if (matchingCaptures.Count == 1) { ret = char.ToUpper(fromType.Char) + captureChar + toSquare.ToString().ToLower(); } else { // Disambiguate DifferBy differBy = MoveDifferFromAllOthersBy(matchingCaptures, mgMove); string fileChar = fromSquare.FileChar.ToString().ToLower(); string rankChar = fromSquare.RankChar.ToString().ToLower(); if (differBy == DifferBy.File) { ret = char.ToUpper(fromType.Char) + fileChar + captureChar + toSquare.ToString().ToLower(); } else if (differBy == DifferBy.Rank) { ret = char.ToUpper(fromType.Char) + rankChar + captureChar + toSquare.ToString().ToLower(); } else { ret = char.ToUpper(fromType.Char) + fileChar + rankChar + captureChar + toSquare.ToString().ToLower(); } } } } if (isCheck) { return(ret + "+"); } else { return(ret); } }
static List <MGMove> MovesByPieceTypeThatTakeOnSquare(MGPositionConstants.MCChessPositionPieceEnum piece, byte toSquare, MGMoveList moves) { List <MGMove> matchingMoves = new List <MGMove>(0); foreach (MGMove move in moves.MovesArray) { if (move.Piece == piece && move.ToSquareIndex == toSquare) { matchingMoves.Add(move); } } return(matchingMoves); }