public static object ListLegalMoves(int gameId, int playerId, string lastMove)
        {
            if (!Games.ContainsKey(gameId))
            {
                throw new Exception("Game not found.");
            }
            var game = Games[gameId];

            string statusMessage = "";

            bool isInCheck = false;

            if (lastMove != null)
            {
                game.RegisterMove(lastMove);

                var v = new MoveValidator(game);
                v.Turn = v.Turn == "w" ? "b" : "w";
                var moves = v.CalculateValidMoves().ToList();

                var kings = game.Pieces.Where(x => x.Value.EndsWith("k"));
                isInCheck = kings.Aggregate(false, (current, king) => current || moves.Any(x => x.EndsWith(king.Key)));
            }
            if (isInCheck)
            {
                statusMessage = "Check!";
            }

            var validator      = new MoveValidator(game);
            var tentativeMoves = validator.CalculateValidMoves().ToList();
            var verifiedMoves  = new List <string>();

            foreach (var move in tentativeMoves)
            {
                var v = new MoveValidator(game);

                var moveBackup = game.Pieces.ToDictionary(x => x.Key, x => x.Value);

                game.RegisterMove(move);
                v.Turn = v.Turn == "w" ? "b" : "w";

                var moves = v.CalculateValidMoves().ToList();
                var kings = game.Pieces.Where(x => x.Value.EndsWith("k"));
                isInCheck = kings.Aggregate(false, (current, king) => current || moves.Any(x => x.EndsWith(king.Key)));

                game.UnregisterPreviousMove();
                game.Pieces = moveBackup;
                if (!isInCheck)
                {
                    verifiedMoves.Add(move);
                }
            }

            if (verifiedMoves.Count == 0)
            {
                statusMessage = isInCheck ? "Checkmate!" : "Draw: No more moves possible.";
            }

            //king versus king
            //king and bishop versus king
            //king and knight versus king
            //king and bishop versus king and bishop with the bishops on the same colour. (Any number of additional bishops of either color on the same color of square due to underpromotion do not affect the situation.)
            else if
            (
                (game.Pieces.Count == 2) ||
                (game.Pieces.Count == 3 && (game.Pieces.ContainsValue("wb") || game.Pieces.ContainsValue("bb"))) ||
                (game.Pieces.Count == 3 && (game.Pieces.ContainsValue("wn") || game.Pieces.ContainsValue("bn"))) ||
                (game.Pieces.Count == 4 && (game.Pieces.ContainsValue("wb") && game.Pieces.ContainsValue("bb")))
            )
            {
                statusMessage = "Draw: Checkmate impossible (insufficent material.)";
                verifiedMoves.Clear();
            }
            return(new MoveWrapper {
                StatusMessage = statusMessage, Moves = verifiedMoves
            });
        }
Exemple #2
0
        public static object ListLegalMoves(int gameId, int playerId, string lastMove)
        {
            if (!Games.ContainsKey(gameId))
            {
                throw new Exception("Game not found.");
            }
            var game = Games[gameId];

            string statusMessage = "";

            bool isInCheck = false;

            if (lastMove != null)
            {
                game.RegisterMove(lastMove);

                var v = new MoveValidator(game);
                v.Turn = v.Turn == "w" ? "b" : "w";
                var moves = v.CalculateValidMoves().ToList();

                var kings = game.Pieces.Where(x => x.Value.EndsWith("k"));
                isInCheck = kings.Aggregate(false, (current, king) => current || moves.Any(x => x.EndsWith(king.Key)));
            }
            if (isInCheck)
            {
                statusMessage = "Check!";
            }

            var validator = new MoveValidator(game);
            var tentativeMoves = validator.CalculateValidMoves().ToList();
            var verifiedMoves = new List<string>();
            foreach (var move in tentativeMoves)
            {
                var v = new MoveValidator(game);

                var moveBackup = game.Pieces.ToDictionary(x => x.Key, x => x.Value);

                game.RegisterMove(move);
                v.Turn = v.Turn == "w" ? "b" : "w";

                var moves = v.CalculateValidMoves().ToList();
                var kings = game.Pieces.Where(x => x.Value.EndsWith("k"));
                isInCheck = kings.Aggregate(false, (current, king) => current || moves.Any(x => x.EndsWith(king.Key)));

                game.UnregisterPreviousMove();
                game.Pieces = moveBackup;
                if (!isInCheck)
                {
                    verifiedMoves.Add(move);
                }
            }

            if (verifiedMoves.Count == 0)
            {
                statusMessage = isInCheck ? "Checkmate!" : "Draw: No more moves possible.";
            }

            //king versus king
            //king and bishop versus king
            //king and knight versus king
            //king and bishop versus king and bishop with the bishops on the same colour. (Any number of additional bishops of either color on the same color of square due to underpromotion do not affect the situation.)
            else if
                (
                    (game.Pieces.Count == 2) ||
                    (game.Pieces.Count == 3 && (game.Pieces.ContainsValue("wb") || game.Pieces.ContainsValue("bb"))) ||
                    (game.Pieces.Count == 3 && (game.Pieces.ContainsValue("wn") || game.Pieces.ContainsValue("bn"))) ||
                    (game.Pieces.Count == 4 && (game.Pieces.ContainsValue("wb") && game.Pieces.ContainsValue("bb")))
                )
            {
                statusMessage = "Draw: Checkmate impossible (insufficent material.)";
                verifiedMoves.Clear();
            }
            return new MoveWrapper {StatusMessage = statusMessage, Moves = verifiedMoves};
        }