Esempio n. 1
0
        void PuzzleFinished(SubmittedMoveResponse response, bool correct)
        {
            CurrentPuzzleEndedUtc = DateTime.UtcNow;

            response.Correct         = correct ? 1 : -1;
            response.ExplanationSafe = Current.ExplanationSafe;

            PastPuzzleIds.Add(Current.ID);

            if (!correct)
            {
                Moves.RemoveAt(Moves.Count - 1);
                FENs.RemoveAt(FENs.Count - 1);
                Checks.RemoveAt(Checks.Count - 1);

                response.FEN = FENs[FENs.Count - 1];

                ChessGame correctGame = gameConstructor.Construct(Current.Variant, response.FEN);
                foreach (string move in PossibleVariations.First())
                {
                    string[] p = move.Split('-', '=');
                    correctGame.ApplyMove(new Move(p[0], p[1], correctGame.WhoseTurn, p.Length == 2 ? null : new char?(p[2][0])), true);
                    FENs.Add(correctGame.GetFen());
                    Checks.Add(correctGame.IsInCheck(correctGame.WhoseTurn) ? correctGame.WhoseTurn.ToString().ToLowerInvariant() : null);
                    Moves.Add(move);
                }
            }
            response.ReplayFENs   = FENs;
            response.ReplayChecks = Checks;
            response.ReplayMoves  = Moves;
        }
Esempio n. 2
0
 public void Setup(Puzzle puzzle)
 {
     Current = puzzle;
     CurrentPuzzleStartedUtc = DateTime.UtcNow;
     CurrentPuzzleEndedUtc   = null;
     PossibleVariations      = puzzle.Solutions.Select(x => x.Split(' '));
     FENs.Clear();
     FENs.Add(puzzle.InitialFen);
     Checks.Clear();
     Checks.Add(Current.Game.IsInCheck(Current.Game.WhoseTurn) ? Current.Game.WhoseTurn.ToString().ToLowerInvariant() : null);
     Moves.Clear();
     Moves.Add(null);
 }
        SubmittedMoveResponse MakeMoveAndDropCommon(SubmittedMoveResponse response, string moveStr)
        {
            response.Check = Current.Game.IsInCheck(Current.Game.WhoseTurn) ? Current.Game.WhoseTurn.ToString().ToLowerInvariant() : null;
            Checks.Add(response.Check);
            string fen = Current.Game.GetFen();

            response.FEN = fen;
            FENs.Add(fen);
            Dictionary <string, int> pocket = Current.Game.GenerateJsonPocket();

            response.Pocket = pocket;
            Pockets.Add(pocket);

            if (Current.Game.IsWinner(ChessUtilities.GetOpponentOf(Current.Game.WhoseTurn)))
            {
                PuzzleFinished(response, true);
                return(response);
            }

            if (!PossibleVariations.Any(x => CompareMoves(x.First(), moveStr) == 0))
            {
                PuzzleFinished(response, false);
                return(response);
            }

            PossibleVariations = PossibleVariations.Where(x => CompareMoves(x.First(), moveStr) == 0).Select(x => x.Skip(1));

            if (PossibleVariations.Any(x => x.Count() == 0))
            {
                PuzzleFinished(response, true);
                return(response);
            }

            string moveToPlay = PossibleVariations.First().First();

            if (!moveToPlay.Contains("@"))
            {
                string[] parts = moveToPlay.Split('-', '=');
                Current.Game.MakeMove(new Move(parts[0], parts[1], Current.Game.WhoseTurn, parts.Length == 2 ? null : new char?(parts[2][0])), true);
            }
            else
            {
                string[] parts = moveToPlay.Split('@');

                CrazyhouseChessGame zhCurrent = Current.Game as CrazyhouseChessGame;
                Piece toDrop = zhCurrent.MapPgnCharToPiece(parts[0] == "" ? 'P' : parts[0][0], zhCurrent.WhoseTurn);
                Drop  drop   = new Drop(toDrop, new Position(parts[1]), zhCurrent.WhoseTurn);
                zhCurrent.ApplyDrop(drop, true);
            }

            response.Play = moveToPlay;
            Moves.Add(moveToPlay);
            response.FenAfterPlay = Current.Game.GetFen();
            FENs.Add(response.FenAfterPlay);
            response.CheckAfterAutoMove = Current.Game.IsInCheck(Current.Game.WhoseTurn) ? Current.Game.WhoseTurn.ToString().ToLowerInvariant() : null;
            Checks.Add(response.CheckAfterAutoMove);
            response.Moves               = Current.Game.GetValidMoves(Current.Game.WhoseTurn);
            response.Correct             = 0;
            response.PocketAfterAutoMove = Current.Game.GenerateJsonPocket();
            Pockets.Add(response.PocketAfterAutoMove);
            PossibleVariations = PossibleVariations.Select(x => x.Skip(1));
            if (PossibleVariations.Any(x => !x.Any()))
            {
                PuzzleFinished(response, true);
            }
            return(response);
        }
        void PuzzleFinished(SubmittedMoveResponse response, bool correct)
        {
            CurrentPuzzleEndedUtc = DateTime.UtcNow;

            response.Correct         = correct ? 1 : -1;
            response.ExplanationSafe = Current.ExplanationSafe;

            if (!PastPuzzleIds.Contains(Current.ID))
            {
                PastPuzzleIds.Add(Current.ID);
            }

            string analysisUrl = "https://lichess.org/analysis/{0}/{1}";
            string analysisUrlVariant;

            switch (Current.Variant)
            {
            case "Atomic":
                analysisUrlVariant = "atomic";
                break;

            case "Antichess":
                analysisUrlVariant = "antichess";
                break;

            case "Crazyhouse":
                analysisUrlVariant = "crazyhouse";
                break;

            case "Horde":
                analysisUrlVariant = "horde";
                break;

            case "KingOfTheHill":
                analysisUrlVariant = "kingOfTheHill";
                break;

            case "ThreeCheck":
                analysisUrlVariant = "threeCheck";
                break;

            case "RacingKings":
                analysisUrlVariant = "racingKings";
                break;

            default:
                analysisUrlVariant = "unknown";
                break;
            }
            response.AnalysisUrl = string.Format(analysisUrl, analysisUrlVariant, Current.InitialFen.Replace(' ', '_'));

            List <string> replayFens   = new List <string>(FENs);
            List <string> replayChecks = new List <string>(Checks);
            List <string> replayMoves  = new List <string>(Moves);
            List <Dictionary <string, int> > replayPockets = new List <Dictionary <string, int> >(Pockets);

            if (!correct)
            {
                Moves.RemoveAt(Moves.Count - 1);
                FENs.RemoveAt(FENs.Count - 1);
                Checks.RemoveAt(Checks.Count - 1);
                Pockets.RemoveAt(Pockets.Count - 1);

                replayFens.RemoveAt(replayFens.Count - 1);
                replayMoves.RemoveAt(replayMoves.Count - 1);
                replayChecks.RemoveAt(replayChecks.Count - 1);
                replayPockets.RemoveAt(replayPockets.Count - 1);

                response.FEN    = FENs[FENs.Count - 1];
                response.Pocket = Pockets[Pockets.Count - 1];

                ChessGame correctGame = gameConstructor.Construct(Current.Variant, Current.InitialFen);
                int       i           = 0;
                var       full        = replayMoves.Concat(PossibleVariations.First());
                foreach (string move in full)
                {
                    if (move == null)
                    {
                        i++; continue;
                    }
                    if (!move.Contains("@"))
                    {
                        string[] p = move.Split('-', '=');
                        correctGame.MakeMove(new Move(p[0], p[1], correctGame.WhoseTurn, p.Length == 2 ? null : new char?(p[2][0])), true);
                    }
                    else
                    {
                        string[] p = move.Split('@');
                        if (string.IsNullOrEmpty(p[0]))
                        {
                            p[0] = "P";
                        }
                        Drop drop = new Drop(correctGame.MapPgnCharToPiece(p[0][0], correctGame.WhoseTurn), new Position(p[1]), correctGame.WhoseTurn);
                        (correctGame as CrazyhouseChessGame).ApplyDrop(drop, true);
                    }
                    if (i >= Moves.Count)
                    {
                        replayFens.Add(correctGame.GetFen());
                        replayChecks.Add(correctGame.IsInCheck(correctGame.WhoseTurn) ? correctGame.WhoseTurn.ToString().ToLowerInvariant() : null);
                        replayMoves.Add(move);
                        replayPockets.Add(correctGame.GenerateJsonPocket());
                    }
                    i++;
                }

                Current.Game   = gameConstructor.Construct(Current.Variant, response.FEN);
                response.Moves = Current.Game.GetValidMoves(Current.Game.WhoseTurn);
                response.Check = Current.Game.IsInCheck(Player.White) ? "white" : (Current.Game.IsInCheck(Player.Black) ? "black" : null);
            }
            response.ReplayFENs    = replayFens;
            response.ReplayChecks  = replayChecks;
            response.ReplayMoves   = replayMoves;
            response.ReplayPockets = replayPockets;
        }
Esempio n. 5
0
        public SubmittedMoveResponse ApplyMove(string origin, string destination, string promotion)
        {
            SubmittedMoveResponse response = new SubmittedMoveResponse()
            {
                Success = true,
                Error   = null
            };

            if (promotion != null && promotion.Length != 1)
            {
                response.Success = false;
                response.Error   = "Invalid promotion.";
                response.Correct = SubmittedMoveResponse.INVALID_MOVE;
                return(response);
            }

            MoveType type = Current.Game.ApplyMove(new Move(origin, destination, Current.Game.WhoseTurn, promotion?[0]), false);

            if (type == MoveType.Invalid)
            {
                response.Success = false;
                response.Error   = "Invalid move.";
                response.Correct = SubmittedMoveResponse.INVALID_MOVE;
            }

            response.Check = Current.Game.IsInCheck(Current.Game.WhoseTurn) ? Current.Game.WhoseTurn.ToString().ToLowerInvariant() : null;
            Checks.Add(response.Check);
            string fen = Current.Game.GetFen();

            response.FEN = fen;
            FENs.Add(fen);

            string promotionUpper = promotion?.ToUpperInvariant();

            Moves.Add(string.Format("{0}-{1}={2}", origin, destination, promotion == null ? "" : "=" + promotionUpper));

            if (Current.Game.IsWinner(ChessUtilities.GetOpponentOf(Current.Game.WhoseTurn)))
            {
                PuzzleFinished(response, true);
                return(response);
            }

            string moveStr = origin + "-" + destination + (promotion != null ? "=" + promotionUpper : "");

            if (!PossibleVariations.Any(x => string.Compare(x.First(), moveStr, true) == 0))
            {
                PuzzleFinished(response, false);
                return(response);
            }

            PossibleVariations = PossibleVariations.Where(x => string.Compare(x.First(), moveStr, true) == 0).Select(x => x.Skip(1));

            if (PossibleVariations.Any(x => x.Count() == 0))
            {
                PuzzleFinished(response, true);
                return(response);
            }

            response.FEN = fen;

            string moveToPlay = PossibleVariations.First().First();

            string[] parts = moveToPlay.Split('-', '=');
            Current.Game.ApplyMove(new Move(parts[0], parts[1], Current.Game.WhoseTurn, parts.Length == 2 ? null : new char?(parts[2][0])), true);
            response.Play = moveToPlay;
            Moves.Add(moveToPlay);
            response.FenAfterPlay = Current.Game.GetFen();
            FENs.Add(response.FenAfterPlay);
            response.CheckAfterAutoMove = Current.Game.IsInCheck(Current.Game.WhoseTurn) ? Current.Game.WhoseTurn.ToString().ToLowerInvariant() : null;
            Checks.Add(response.CheckAfterAutoMove);
            response.Moves     = Current.Game.GetValidMoves(Current.Game.WhoseTurn);
            response.Correct   = 0;
            PossibleVariations = PossibleVariations.Select(x => x.Skip(1));
            if (PossibleVariations.Any(x => !x.Any()))
            {
                PuzzleFinished(response, true);
            }
            return(response);
        }