public void SetPosition(TrainingPosition position)
 {
     currentPosition          = position;
     AssociatedGame           = gameConstructor.Construct(Variant, position.FEN);
     CurrentFen               = position.FEN;
     CurrentLastMoveToDisplay = position.LastMove;
 }
예제 #2
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;
        }
예제 #3
0
 public Game Get(string id)
 {
     if (cache.ContainsKey(id))
     {
         return(cache[id]);
     }
     else
     {
         Game g = gameRepository.Get(id);
         if (g == null)
         {
             return(null);
         }
         g.ChessGame = gameConstructor.Construct(g.ShortVariantName, g.LatestFEN);
         cache[id]   = g;
         return(cache[id]);
     }
 }
예제 #4
0
        public async Task <IActionResult> RegisterPuzzleForEditing(string fen, string variant, int checksByWhite, int checksByBlack)
        {
            fen    += " - 0 1";
            variant = Utilities.NormalizeVariantNameCapitalization(variant);
            if (!Array.Exists(supportedVariants, x => x == variant))
            {
                return(Json(new { success = false, error = "Unsupported variant." }));
            }
            if (variant == "ThreeCheck")
            {
                if (checksByWhite > 2 || checksByWhite < 0 || checksByBlack > 2 || checksByBlack < 0)
                {
                    return(Json(new { success = false, error = "Invalid amount of checks." }));
                }

                fen += String.Format(" +{0}+{1}", checksByWhite, checksByBlack);
            }
            Puzzle possibleDuplicate = await puzzleRepository.FindByFenAndVariantAsync(fen, variant);

            if (possibleDuplicate != null && possibleDuplicate.Approved)
            {
                return(Json(new { success = false, error = "Duplicate; same FEN and variant: " + Url.Action("TrainId", "Puzzle", new { id = possibleDuplicate.ID }) }));
            }
            ChessGame game   = gameConstructor.Construct(variant, fen);
            Puzzle    puzzle = new Puzzle();

            Task <int?> aid = loginHandler.LoggedInUserIdAsync(HttpContext);

            puzzle.Game       = game;
            puzzle.InitialFen = fen;
            puzzle.Variant    = variant;
            puzzle.Solutions  = new List <string>();
            do
            {
                puzzle.ID = Guid.NewGuid().GetHashCode();
            } while (puzzlesBeingEdited.Contains(puzzle.ID));
            puzzle.Author = (await aid).Value;
            puzzlesBeingEdited.Add(puzzle);
            return(Json(new { success = true, id = puzzle.ID }));
        }
예제 #5
0
        public IActionResult RegisterPuzzleForEditing(string fen, string variant)
        {
            variant = Utilities.NormalizeVariantNameCapitalization(variant);
            if (!Array.Exists(supportedVariants, x => x == variant))
            {
                return(Json(new { success = false, error = "Unsupported variant." }));
            }
            ChessGame game   = gameConstructor.Construct(variant, fen);
            Puzzle    puzzle = new Puzzle();

            puzzle.Game       = game;
            puzzle.InitialFen = fen;
            puzzle.Variant    = variant;
            puzzle.Author     = loginHandler.LoggedInUserId(HttpContext).Value;
            puzzle.Solutions  = new List <string>();
            do
            {
                puzzle.ID = Guid.NewGuid().GetHashCode();
            } while (puzzlesBeingEdited.Contains(puzzle.ID));
            puzzlesBeingEdited.Add(puzzle);
            return(Json(new { success = true, id = puzzle.ID }));
        }
예제 #6
0
        public Game(string id, GamePlayer white, GamePlayer black, string shortVariant, string fullVariant, int nWhite, int nBlack, bool isSymmetrical, TimeControl tc, DateTime startedUtc, int rematchLevel, IGameConstructor gameConstructor)
        {
            ID               = id;
            White            = white;
            PositionWhite    = nWhite;
            Black            = black;
            PositionBlack    = nBlack;
            IsSymmetrical    = isSymmetrical;
            Result           = Results.ONGOING;
            Termination      = Terminations.UNTERMINATED;
            TimeControl      = tc;
            ShortVariantName = shortVariant;
            FullVariantName  = fullVariant;
            string fen;

            if (shortVariant == "Horde")
            {
                fen = ChessUtilities.FenForHorde960(nBlack);
            }
            else if (shortVariant == "RacingKings")
            {
                fen = ChessUtilities.FenForRacingKings1440Asymmetrical(nWhite, nBlack);
            }
            else
            {
                fen = ChessUtilities.FenForChess960Asymmetrical(nWhite, nBlack);
            }
            ChessGame         = gameConstructor.Construct(shortVariant, fen);
            InitialFEN        = LatestFEN = ChessGame.GetFen();
            PlayerChats       = new List <ChatMessage>();
            SpectatorChats    = new List <ChatMessage>();
            StartedUtc        = startedUtc;
            EndedUtc          = null;
            ClockWhite        = new Clock(tc);
            ClockBlack        = new Clock(tc);
            ClockTimes        = new List <double>();
            WhiteWantsRematch = false;
            BlackWantsRematch = false;
            WhiteWantsDraw    = false;
            BlackWantsDraw    = false;
            RematchLevel      = rematchLevel;
            UciMoves          = new List <string>();
        }
예제 #7
0
        public async Task <IActionResult> Game(string id)
        {
            id = id.ToLowerInvariant();
            Game game = await gameRepository.GetAsync(id);

            if (game == null)
            {
                return(ViewResultForHttpError(HttpContext, new NotFound("This game could not be found.")));
            }

            string whiteUsername;
            int?   whiteId;
            string blackUsername;
            int?   blackId;
            Player requester = Player.None;

            if (game.White is AnonymousPlayer)
            {
                whiteUsername = null;
                whiteId       = null;

                string anonIdentifier = HttpContext.Session.GetString("anonymousIdentifier");
                if (anonIdentifier == (game.White as AnonymousPlayer).AnonymousIdentifier)
                {
                    requester = Player.White;
                }
            }
            else
            {
                whiteId       = (game.White as RegisteredPlayer).UserId;
                whiteUsername = (await userRepository.FindByIdAsync(whiteId.Value)).Username;

                int?loggedOnUserId = await loginHandler.LoggedInUserIdAsync(HttpContext);

                if (loggedOnUserId.HasValue && loggedOnUserId.Value == whiteId)
                {
                    requester = Player.White;
                }
            }

            if (game.Black is AnonymousPlayer)
            {
                blackUsername = null;
                blackId       = null;

                string anonIdentifier = HttpContext.Session.GetString("anonymousIdentifier");
                if (anonIdentifier == (game.Black as AnonymousPlayer).AnonymousIdentifier)
                {
                    requester = Player.Black;
                }
            }
            else
            {
                blackId       = (game.Black as RegisteredPlayer).UserId;
                blackUsername = (await userRepository.FindByIdAsync(blackId.Value)).Username;

                int?loggedOnUserId = await loginHandler.LoggedInUserIdAsync(HttpContext);

                if (loggedOnUserId.HasValue && loggedOnUserId.Value == blackId)
                {
                    requester = Player.Black;
                }
            }

            bool      finished = game.Result != Models.Variant960.Game.Results.ONGOING;
            string    destsJson;
            ChessGame g = gameConstructor.Construct(game.ShortVariantName, game.LatestFEN);

            if (finished || requester == Player.None)
            {
                destsJson = "{}";
            }
            else
            {
                if (g.WhoseTurn != requester)
                {
                    destsJson = "{}";
                }
                destsJson = JsonConvert.SerializeObject(moveCollectionTransformer.GetChessgroundDestsForMoveCollection(g.GetValidMoves(g.WhoseTurn)));
            }
            string check = null;

            if (g.IsInCheck(Player.White))
            {
                check = "white";
            }
            else if (g.IsInCheck(Player.Black))
            {
                check = "black";
            }

            List <string> replay = new List <string>
            {
                game.InitialFEN
            };

            List <string> replayChecks = new List <string>
            {
                null
            };

            List <string> replayMoves = new List <string>();

            ChessGame replayGame = gameConstructor.Construct(game.ShortVariantName, game.InitialFEN);

            List <Dictionary <string, int> > replayPocket;

            if (replayGame is CrazyhouseChessGame)
            {
                replayPocket = new List <Dictionary <string, int> >
                {
                    replayGame.GenerateJsonPocket()
                };
            }
            else
            {
                replayPocket = null;
            }
            foreach (string uciMove in game.UciMoves)
            {
                if (!uciMove.Contains("@"))
                {
                    string from = uciMove.Substring(0, 2);
                    string to   = uciMove.Substring(2, 2);
                    replayMoves.Add(string.Concat(from, "-", to));
                    char?promotion = null;
                    if (uciMove.Length == 5)
                    {
                        promotion = uciMove[4];
                    }
                    replayGame.MakeMove(new Move(from, to, replayGame.WhoseTurn, promotion), true);
                }
                else
                {
                    string[] typeAndPos = uciMove.Split('@');
                    Position pos        = new Position(typeAndPos[1]);
                    Piece    piece      = replayGame.MapPgnCharToPiece(typeAndPos[0][0], replayGame.WhoseTurn);
                    Drop     drop       = new Drop(piece, pos, piece.Owner);
                    (replayGame as CrazyhouseChessGame).ApplyDrop(drop, true);
                    replayMoves.Add(pos.ToString().ToLowerInvariant() + "-" + pos.ToString().ToLowerInvariant());
                }
                replay.Add(replayGame.GetFen());
                if (replayGame.IsInCheck(Player.White))
                {
                    replayChecks.Add("white");
                }
                else if (replayGame.IsInCheck(Player.Black))
                {
                    replayChecks.Add("black");
                }
                else
                {
                    replayChecks.Add(null);
                }
                if (replayPocket != null)
                {
                    replayPocket.Add(replayGame.GenerateJsonPocket());
                }
            }
            if (game.PGN == null)
            {
                game.PGN = replayGame.GetPGN();
                await gameRepository.UpdateAsync(game);
            }

            string lastMove = game.UciMoves.LastOrDefault();

            if (lastMove != null && lastMove.Contains('@'))
            {
                string pos = lastMove.Split('@')[1].ToLowerInvariant();
                lastMove = pos + pos;
            }
            ViewModels.Game model = new ViewModels.Game(game.ID,
                                                        whiteUsername,
                                                        blackUsername,
                                                        whiteId,
                                                        blackId,
                                                        game.ShortVariantName,
                                                        game.FullVariantName,
                                                        game.TimeControl,
                                                        game.LatestFEN,
                                                        requester != Player.None,
                                                        requester == Player.None ? null : requester.ToString().ToLowerInvariant(),
                                                        game.LatestFEN.Split(' ')[1] == "w" ? "white" : "black",
                                                        game.Result != Models.Variant960.Game.Results.ONGOING,
                                                        destsJson,
                                                        game.Result,
                                                        game.Termination,
                                                        lastMove,
                                                        check,
                                                        game.UciMoves.Count,
                                                        game.WhiteWantsDraw,
                                                        game.BlackWantsDraw,
                                                        game.WhiteWantsRematch,
                                                        game.BlackWantsRematch,
                                                        replay,
                                                        replayMoves,
                                                        replayChecks,
                                                        g.GenerateJsonPocket(),
                                                        replayPocket,
                                                        game.PositionWhite,
                                                        game.PositionBlack,
                                                        game.PGN,
                                                        game.InitialFEN);

            return(View(model));
        }
        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;
        }