public void Set(PGNChessGame g)
            {
                idx = -1;
                move = null;
                total_moves = 0;

                player = g.HasTag ("FEN") ? ChessGamePlayer.
                    CreateFromFEN (g.
                               GetTagValue ("FEN",
                                    null)) :
                    ChessGamePlayer.CreatePlayer ();

                game = g;

                int n = game.Moves.Count;
                if (n > 0)
                  {
                      total_moves = (n - 1) * 2;
                      // now see the last move
                      ChessMove lastmove =
                          (ChessMove) game.Moves[n -
                                     1];
                      if (lastmove.blackmove == null)
                          total_moves += 1;
                      else
                            total_moves += 2;
                  }

                if (total_moves == 0)
                    hasNext = false;
                else
                      hasNext = true;
            }
Example #2
0
        /// <summary>
        /// Checks if the white knight move is valid
        /// </summary>
        /// <param name="board"></param>
        /// <param name="move"></param>
        /// <returns></returns>
        public static bool BlackKnight(ChessBoard board, ChessMove move)
        {
            //if not killing or empty space throw error
            if (!KillOrEmpty(move.To.X, move.To.Y, board, ChessColor.Black))
                return false;

            //if not in a style of knight movement throw error
            if (Math.Abs(move.To.X - move.From.X) == 2)
            {
                if (Math.Abs(move.To.Y - move.From.Y) != 1)
                    return false;
            }
            else if (Math.Abs(move.To.X - move.From.X) == 1)
            {
                if (Math.Abs(move.To.Y - move.From.Y) != 2)
                    return false;
            }
            else
            {
                return false;
            }

            //all good
            return true;
        }
Example #3
0
 public bool CanMove(ChessGameField.Cell[,] field, Point posFrom, Point posTo, ChessMove lastMove)
 {
     Figure targetFig = field[posTo.X, posTo.Y].figure;
     if (targetFig == null || targetFig.GetOwner() != GetOwner())
     {
         return Rook.IsPathFree(field, posFrom, posTo) || Bishop.IsPathFree(field, posFrom, posTo);
     }
     return false;
 }
Example #4
0
 private DecisionTree(DecisionTree parent, ChessBoard board, ChessMove move)
 {
     UvsChess.Framework.Profiler.AddToMainProfile((int)ProfilerMethodKey.DecisionTree_ctor_DecisionTree_ChessBoard_ChessMove);
     Children = new List<DecisionTree>();
     Parent = parent;
     Board = board;
     Move = move;
     BestChildMove = null;
 }
Example #5
0
 /// <summary>
 /// this will define BoardAfterMove, TheMove, and HValue based on move
 /// </summary>
 /// <param name="board"></param>
 /// <param name="move"></param>
 /// <param name="colorofEnemy"></param>
 public Hueristic(ChessBoard board, ChessMove move, ChessColor colorofEnemy)
 {
     BoardBeforeMove = board.Clone();
     BoardAfterMove = board.Clone();
     BoardAfterMove.MakeMove(move);
     TheMove = move;
     //HValue = CalculateHueristicBasic(board, colorofEnemy);
     HValue = CalculateHueristicAdvanced(colorofEnemy);
 }
Example #6
0
        /// <summary>
        /// Returns the state after making the specified move
        /// </summary>
        /// <param name="state">The state before making the move</param>
        /// <param name="move">The move to make</param>
        /// <returns>The state after the move</returns>
        public int[,] GetStateAfterMove(int[,] state, ChessMove move)
        {
            int[,] newState = (int[,])state.Clone();

            newState[move.To.X, move.To.Y] = newState[move.From.X, move.From.Y];
            newState[move.From.X, move.From.Y] = SimpleState.Empty;

            if (newState[move.To.X, move.To.Y] == SimpleState.Pawn && move.To.Y == state.GetLength(1) - 1)
                newState[move.To.X, move.To.Y] = SimpleState.Queen;

            return newState;
        }
Example #7
0
        /// <summary>
        /// Checks if the move the black king wants to make is valid
        /// </summary>
        /// <param name="board">board state before move</param>
        /// <param name="move">move the piece wants to make</param>
        /// <returns>true if valid move, false is invalid</returns>
        public static bool BlackKing(ChessBoard board, ChessMove move)
        {
            //  ensure new move is onto an enemy piece or empty space
            if (!KillOrEmpty(move.To.X, move.To.Y, board, ChessColor.Black))
                return false;

            //validate the move is only one space away for a king
            if (Math.Abs(move.To.X - move.From.X) > 1 || Math.Abs(move.To.Y - move.From.Y) > 1)
                return false;

            //if all checks pass then
            return true;
        }
        /// <summary>
        /// Checks if the move the white king wants to make is valid
        /// </summary>
        /// <param name="board">board state before move</param>
        /// <param name="move">move the piece wants to make</param>
        /// <returns>true if valid move, false is invalid</returns>
        public static bool WhiteKing(ChessBoard board, ChessMove move)
        {
            //TODO NOT DONE, still need to finish this
            //validate the move is still on the board as well as
            //  ensure new move is onto an enemy piece or empty space
            if (!OnBoardAndKillOrEmpty(move.To.X, move.To.Y,board,ChessColor.White))
                return false;

            //validate it doesn't put self into check

            //if all checks pass then
            return true;
        }
Example #9
0
 public Node(ChessColor c, ChessMove m, Node p)
 {
     color = c;
     move = m;
     parent = p;
     if (parent == null)
     {
         depth = 0;
     }
     else
     {
         depth = parent.depth + 1;
     }
 }
Example #10
0
        public bool CanMove(ChessGameField.Cell[,] field, Point posFrom, Point posTo, ChessMove lastMove)
        {
            Figure targetFig = field[posTo.X, posTo.Y].figure;
            if (targetFig == null || targetFig.GetOwner() != GetOwner())
            {
                int difX = Math.Abs(posTo.X - posFrom.X);
                int difY = Math.Abs(posTo.Y - posFrom.Y);

                if (difX <= 1 && difY <= 1)
                {
                    return true;
                }
            }
            return false;
        }
Example #11
0
        /// <summary>
        /// Checks if black bishop move is valid
        /// </summary>
        /// <param name="board"></param>
        /// <param name="move"></param>
        /// <returns></returns>
        public static bool BlackBishop(ChessBoard board, ChessMove move)
        {
            //if he tries to move diagonal throw an error
            if (Math.Abs(move.From.X - move.To.X) != Math.Abs(move.From.Y - move.To.Y))
            {
                return false;
            }

            //if the path is not clear or they are not moving to kill then no good
            if (!PathClear(move.From.X, move.From.Y, move.To.X, move.To.Y, board) || !KillOrEmpty(move.To.X, move.To.Y, board, ChessColor.Black))
                return false;

            //all good
            return true;
        }
Example #12
0
        public ChessMove Move(ref ChessGameField.Cell[,] field, Point posFrom, Point posTo, ChessMove lastMove)
        {
            if (CanMove(field, posFrom, posTo, lastMove))
            {
                ChessMove move = new ChessMove();
                if (field[posTo.X, posTo.Y].figure != null)
                {
                    move.AddAction(new ChessMove.RemoveAction(posTo));
                }
                move.AddAction(new ChessMove.MoveAction(posFrom, posTo));
                return move;
            }

            return null;
        }
Example #13
0
        /// <summary>
        /// Converts a state based move to a ChessBoard move
        /// </summary>
        /// <param name="stateMove">The move the convert</param>
        /// <param name="playerColor">The color of hte player</param>
        /// <returns>The move corrected to work with ChessBoard</returns>
        public static ChessMove GetGameMove(ChessMove stateMove, ChessColor playerColor)
        {
            if (stateMove == null)
                return null;

            ChessMove gameMove = stateMove.Clone();

            if (playerColor == ChessColor.White)
            {
                gameMove.From.X = Columns - gameMove.From.X - 1;
                gameMove.From.Y = Rows - gameMove.From.Y - 1;
                gameMove.To.X = Columns - gameMove.To.X - 1;
                gameMove.To.Y = Rows - gameMove.To.Y - 1;
            }

            return gameMove;
        }
Example #14
0
        public ChessMove Parse(String anRecord)
        {
            var mv = RxMove.Match(anRecord);

            if (mv.Success)
            {
                var m = new ChessMove(mv.Groups["Move"].Value);

                ParsePromotion(m, mv);

                if (mv.Groups["Kingside"].Success || mv.Groups["Queenside"].Success)
                    ParseCastling(m, mv);
                else
                    ParseRegular(m, mv);

                return m;
            }

            throw new ArgumentException(String.Format("\"{0}\" is not a valid AN string.", anRecord));
        }
Example #15
0
        private void RunAiInThread()
        {
            // This is the only place that IsRunning should be set to true.
            this._isTurnOver = false;
            _hasAIEndedTurn = false;

            if (_isGetNextMoveCall)
            {
                _moveToReturn = this.AI.GetNextMove(_currentBoard, this.Color);
            }
            else
            {
                _isValidMove = this.AI.IsValidMove(_currentBoard, _moveToCheck,
                    (this.Color == ChessColor.White ? ChessColor.Black : ChessColor.White));
            }

            _hasAIEndedTurn = true;
        }
Example #16
0
            private bool loadMoves(string
						initialtoken,
						ArrayList tagList,
						ref bool tagFound)
            {
                string token;
                StringBuilder commentBuffer =
                    new StringBuilder ();
                int moveidx = -1;
                ArrayList moves = new ArrayList ();
                ChessMove move = null;
                string initialComment = null;

                if (initialtoken == null)
                    token = tokenizer.nextToken ();
                else
                    token = initialtoken;

                for (; token != null;
                     token = tokenizer.nextToken ())
                  {
                      //      if(token.Equals("{") || token.Equals("(") || token.Equals("<")) {
                      if (token.Equals ("%"))
                        {
                            ignoreLine (token,
                                tokenizer);
                            continue;
                        }
                      else if (token.Equals (";"))
                        {
                            string comment =
                                readLineComment
                                (token,
                                 tokenizer);
                            commentBuffer.
                                Append (comment);
                            continue;
                        }
                      else if (token.Equals ("{")
                           || token.Equals ("("))
                        {
                            string comment =
                                readComment
                                (token,
                                 tokenizer);
                            commentBuffer.
                                Append (comment);
                            continue;
                        }
                      else if (isNAG (token))
                        {
                            /* TODO: convert comment into a nag */
                            commentBuffer.
                                Append (" " +
                                    token +
                                    " ");
                            continue;
                        }
                      else if (tokenIsATermination
                           (token))
                        {
                            /* end of game */
                            break;
                        }
                      else if (token.Equals ("["))
                        {
                            Console.WriteLine
                                ("Abrupt end of the game. Didnt find the termination");
                            tagFound = true;
                            break;
                        }

                      if (moveidx > 0
                          && token.Equals ("."))
                          continue;

                      /* process moves */
                      bool token_is_a_number =
                          isNumber (token);
                      if (!token_is_a_number
                          && moveidx < 0)
                          throw new
                              PGNParserException
                              ("Line " +
                               tokenizer.
                               currentLine () +
                               ": Expecting a number. Got this token: ["
                               + token + "]");

                      if (token_is_a_number)
                        {
                            int val =
                                Int32.
                                Parse (token);
                            if (moveidx < 0)
                              {	// first time
                                  moveidx = val;
                                  move = new
                                      ChessMove
                                      (moveidx);
                                  /* if there is a comment here.. add it to the previous move
                                   * If there is no previous move.. then the comment is at the
                                   * beginning of the game. So, create a dummy chess move.
                                   */
                                  if (commentBuffer.Length > 0)
                                {
                                    if (moves.Count == 0)
                                      {
                                          initialComment
                                              =
                                              commentBuffer.
                                              ToString
                                              ();
                                          commentBuffer.
                                              Remove
                                              (0,
                                               commentBuffer.
                                               Length);
                                      }
                                    else
                                      {
                                          ChessMove
                                              previousmove
                                              =
                                              (ChessMove)
                                              moves
                                              [moves.
                                               Count
                                               -
                                               1];
                                          previousmove.
                                              blackComment
                                              =
                                              commentBuffer.
                                              ToString
                                              ();
                                          commentBuffer.
                                              Remove
                                              (0,
                                               commentBuffer.
                                               Length);
                                      }
                                }
                              }
                            else if (moveidx != val)
                                throw new
                                    PGNParserException
                                    ("Line: "
                                     +
                                     tokenizer.
                                     currentLine
                                     ());
                        }
                      else if (move.whitemove == null)
                        {
                            /* first token after move number */
                            move.whitemove = token;
                        }
                      else if (move.blackmove == null)
                        {
                            move.blackmove = token;
                            if (commentBuffer.Length >
                            0)
                              {
                                  move.whiteComment = commentBuffer.ToString ();
                                  commentBuffer.
                                      Remove
                                      (0,
                                       commentBuffer.
                                       Length);
                              }
                            /* at this point we have the moveidx, whitemove and blackmove
                             * Now create a chessmove. If there is any comment after this
                             * it will be added later.
                             */
                            moves.Add (move);
                            moveidx = -1;
                            move = null;
                        }
                  }

                if (commentBuffer.Length > 0)
                  {
                      if (move == null)
                        {
                            ChessMove previousmove =
                                (ChessMove)
                                moves[moves.
                                  Count - 1];
                            previousmove.
                                blackComment =
                                commentBuffer.
                                ToString ();
                            commentBuffer.Remove (0,
                                      commentBuffer.
                                      Length);
                        }
                      else
                        {
                            if (move.blackmove ==
                            null)
                                move.whiteComment
                                    =
                                    commentBuffer.
                                    ToString
                                    ();
                            else
                                move.blackComment
                                    =
                                    commentBuffer.
                                    ToString
                                    ();
                        }
                  }

                if (move != null)
                    moves.Add (move);

                PGNChessGame game =
                    new PGNChessGame (initialComment,
                              tagList, moves);
                if (GameLoaded != null)
                  {
                      GameLoaded (this,
                              new
                              GameLoadedEventArgs
                              (game));
                  }
                return true;
            }
 public void Next()
 {
     idx++;
     move = (ChessMove) game.Moves[idx / 2];
     if (idx == total_moves - 1)	// we have reached the last move. no more moves
         hasNext = false;
 }
Example #18
0
        private int MaxValue(int[,] state, ChessMove move, int depth, int alpha, int beta)
        {
            // If we return here, the move passed in represents the enemy's move, so we need to negate the value to obtain an evaluation of the board as it relates to us
            if (depth < 0 || move.Flag == ChessFlag.Checkmate)
                return -move.ValueOfMove;

            state = moveGenerator.GetEnemyState(state);

            int value = int.MinValue;

            List<ChessMove> allPossibleMoves = moveGenerator.GetAllMoves(state, true, boardEvaluator);

            // Sort the moves to get the most out of Alpha Beta Pruning
            allPossibleMoves.Sort((x, y) => y.ValueOfMove.CompareTo(x.ValueOfMove));

            for (int i = 0; i < allPossibleMoves.Count && !timesUp(); i++)
            {
                ChessMove currentMove = allPossibleMoves[i];

                value = Math.Max(value, MinValue(moveGenerator.GetStateAfterMove(state, currentMove), currentMove, depth - 1, alpha, beta));

                if (value >= beta)
                    return value;

                alpha = Math.Max(alpha, value);
            }

            return value;
        }
Example #19
0
 protected bool Equals(ChessMove other)
 {
     return(From.Equals(other.From) && To.Equals(other.To));
 }
Example #20
0
 /// <summary>
 /// Adds a child decision to the decision tree.
 /// </summary>
 /// <param name="board">The board the decision was made from</param>
 /// <param name="move">The move decided.</param>
 public void AddChild(ChessBoard board, ChessMove move)
 {
     UvsChess.Framework.Profiler.AddToMainProfile((int)ProfilerMethodKey.DecisionTree_AddChild_ChessBoard_ChessMove);
     this.Children.Add(new DecisionTree(this, board, move));
 }
Example #21
0
    public void undo()
    {
        if (history.Count == 0)
        {
            return;
        }

        ChessMove move = (ChessMove)history[history.Count - 1];

        history.RemoveAt(history.Count - 1);

        if (move.castling)
        {
            board[Mathf.RoundToInt(move.initialPos.x), Mathf.RoundToInt(move.initialPos.y)].moved       = false;
            board[Mathf.RoundToInt(move.initialPos.x), Mathf.RoundToInt(move.initialPos.y)].pieceSquare = board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].pieceSquare;
            board[Mathf.RoundToInt(move.initialPos.x), Mathf.RoundToInt(move.initialPos.y)].sideSquare  = board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].sideSquare;

            board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].moved       = false;
            board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].pieceSquare = piece.None;
            board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].sideSquare  = side.None;

            paintPiece(Mathf.RoundToInt(move.initialPos.x), Mathf.RoundToInt(move.initialPos.y));
            showPiece(Mathf.RoundToInt(move.initialPos.x), Mathf.RoundToInt(move.initialPos.y));
            hidePiece(Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y));

            board[Mathf.RoundToInt(move.initialPosRook.x), Mathf.RoundToInt(move.initialPosRook.y)].moved       = false;
            board[Mathf.RoundToInt(move.initialPosRook.x), Mathf.RoundToInt(move.initialPosRook.y)].pieceSquare = board[Mathf.RoundToInt(move.finalPosRook.x), Mathf.RoundToInt(move.finalPosRook.y)].pieceSquare;
            board[Mathf.RoundToInt(move.initialPosRook.x), Mathf.RoundToInt(move.initialPosRook.y)].sideSquare  = board[Mathf.RoundToInt(move.finalPosRook.x), Mathf.RoundToInt(move.finalPosRook.y)].sideSquare;

            board[Mathf.RoundToInt(move.finalPosRook.x), Mathf.RoundToInt(move.finalPosRook.y)].moved       = false;
            board[Mathf.RoundToInt(move.finalPosRook.x), Mathf.RoundToInt(move.finalPosRook.y)].pieceSquare = piece.None;
            board[Mathf.RoundToInt(move.finalPosRook.x), Mathf.RoundToInt(move.finalPosRook.y)].sideSquare  = side.None;


            paintPiece(Mathf.RoundToInt(move.initialPosRook.x), Mathf.RoundToInt(move.initialPosRook.y));
            showPiece(Mathf.RoundToInt(move.initialPosRook.x), Mathf.RoundToInt(move.initialPosRook.y));
            hidePiece(Mathf.RoundToInt(move.finalPosRook.x), Mathf.RoundToInt(move.finalPosRook.y));
        }
        else
        {
            board[Mathf.RoundToInt(move.initialPos.x), Mathf.RoundToInt(move.initialPos.y)].moved       = move.moved;
            board[Mathf.RoundToInt(move.initialPos.x), Mathf.RoundToInt(move.initialPos.y)].pieceSquare = board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].pieceSquare;
            board[Mathf.RoundToInt(move.initialPos.x), Mathf.RoundToInt(move.initialPos.y)].sideSquare  = board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].sideSquare;

            paintPiece(Mathf.RoundToInt(move.initialPos.x), Mathf.RoundToInt(move.initialPos.y));
            showPiece(Mathf.RoundToInt(move.initialPos.x), Mathf.RoundToInt(move.initialPos.y));

            if (move.eatenPiece != piece.None)
            {
                board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].moved       = move.eatenMoved;
                board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].pieceSquare = move.eatenPiece;
                board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].sideSquare  = move.eatenSide;

                paintPiece(Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y));
                showPiece(Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y));
            }
            else
            {
                board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].moved       = false;
                board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].pieceSquare = piece.None;
                board[Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y)].sideSquare  = side.None;

                hidePiece(Mathf.RoundToInt(move.finalPos.x), Mathf.RoundToInt(move.finalPos.y));
            }
        }

        changeTurn();
    }
 public BoardState TryApplyMove(ChessMove newMove, out bool putsUserInCheck)
 {
     var newBoardState = new BoardState(this, newMove);
     if (newBoardState.KingIsCapturable())
     {
         putsUserInCheck = true;
         return this;
     }
     else
     {
         putsUserInCheck = false;
         return newBoardState;
     }
 }
Example #23
0
        public async Task <ChessMatchStatus> Move(Stream stream, ulong channel, ulong player, string rawMove)
        {
            return(await Task.Run(async() =>
            {
                var moveInput = rawMove.Replace(" ", "").ToUpper();

                if (!Regex.IsMatch(moveInput, "^[A-H][1-8][A-H][1-8][Q|N|B|R]?$"))
                {
                    throw new ChessException("Error parsing move. Example move: a2a4");
                }

                var match = _chessMatches.SingleOrDefault(x => x.Channel == channel && x.Players.Contains(player));

                if (match == null)
                {
                    throw new ChessException("You are not currently in a game");
                }

                var whoseTurn = match.Game.WhoseTurn;
                var otherPlayer = whoseTurn == Player.White ? Player.Black : Player.White;

                if ((whoseTurn == Player.White && player != match.Challenger) || (whoseTurn == Player.Black && player != match.Challenged))
                {
                    throw new ChessException("It's not your turn.");
                }

                var sourceX = moveInput[0].ToString();
                var sourceY = moveInput[1].ToString();
                var destX = moveInput[2].ToString();
                var destY = moveInput[3].ToString();

                char?promotionChar = moveInput.Length > 4 ? moveInput[4].ToString().ToLower()[0] : 'q';

                var positionEnumValues = (IEnumerable <ChessDotNet.File>)Enum.GetValues(typeof(ChessDotNet.File));

                var sourcePositionX = positionEnumValues.Single(x => x.ToString("g") == sourceX);
                var destPositionX = positionEnumValues.Single(x => x.ToString("g") == destX);

                var originalPosition = new ChessDotNet.Position(sourcePositionX, int.Parse(sourceY));
                var destPosition = new ChessDotNet.Position(destPositionX, int.Parse(destY));

                var piece = match.Game.GetPieceAt(originalPosition);

                if (piece != null && !(piece is Pawn))
                {
                    promotionChar = null;
                }

                var move = new Move(originalPosition, destPosition, whoseTurn, promotionChar);

                if (!match.Game.IsValidMove(move))
                {
                    throw new ChessException("Invalid move.");
                }

                var chessMove = new ChessMove
                {
                    NewRank = move.NewPosition.Rank,
                    NewFile = move.NewPosition.File,
                    OriginalFile = move.OriginalPosition.File,
                    OriginalRank = move.OriginalPosition.Rank,
                    MoveDate = DateTime.Now,
                    PreviousWhoseTurn = match.Game.WhoseTurn
                };

                var board = match.Game.GetBoard();
                for (var column = 0; column < board.Length; column++)
                {
                    for (var row = 0; row < board[column].Length; row++)
                    {
                        chessMove.PreviousBoardState[column][row] = board[column][row];
                    }
                }

                match.Game.ApplyMove(move, true);
                match.History.Add(chessMove);
                match.UndoRequest = null;

                var checkMated = match.Game.IsCheckmated(otherPlayer);
                var isOver = checkMated || match.Game.IsStalemated(otherPlayer);
                var winner = isOver && checkMated ? player : (ulong?)null;

                var status = new ChessMatchStatus
                {
                    IsOver = isOver,
                    Winner = winner,
                    IsCheck = match.Game.IsInCheck(otherPlayer)
                };

                await WriteBoard(channel, player, stream);

                if (isOver)
                {
                    #pragma warning disable 4014
                    Task.Run(async() =>
                    {
                        using (Db db = _services.GetService <Db>())
                        {
                            await db.EndMatch(match, (long?)winner);
                            db.SaveChanges();
                        }
                    });
                    #pragma warning restore 4014
                    _chessMatches.Remove(match);
                }
                else
                {
                    #pragma warning disable 4014
                    Task.Run(async() =>
                    {
                        using (Db db = _services.GetService <Db>())
                        {
                            await db.SaveOrUpdateMatch(match);
                            db.SaveChanges();
                        }
                    });
                    #pragma warning restore 4014
                }


                return await Task.FromResult(status);
            }));
        }
Example #24
0
    public bool move(int i, int j)
    {
        ChessMove move = new ChessMove();

        move.castling = false;

        move.initialPos = new Vector2(selectedI, selectedJ);
        move.finalPos   = new Vector2(i, j);

        move.eatenPiece  = board[i, j].pieceSquare;
        move.moved       = board[selectedI, selectedJ].moved;
        move.eatenSide   = board[i, j].sideSquare;
        move.eatenMoved  = board[i, j].moved;
        move.movingPiece = board[selectedI, selectedJ].pieceSquare;

        //把数据赋值
        ChessSquare oldInitial = board[selectedI, selectedJ].Clone();
        ChessSquare oldNext    = board[i, j].Clone();

        //复制的数据记录
        board[i, j].sideSquare  = board[selectedI, selectedJ].sideSquare;
        board[i, j].pieceSquare = board[selectedI, selectedJ].pieceSquare;
        board[i, j].moved       = true;

        //旧的棋子位置需要更新状态,也就是格式化
        board[selectedI, selectedJ].sideSquare  = side.None;
        board[selectedI, selectedJ].pieceSquare = piece.None;
        board[selectedI, selectedJ].moved       = true;

        //检查是否可以移动
        AttacksTable t = new AttacksTable(board, !white);

        if (checkCheck(board, oldInitial.sideSquare, t))
        {
            board[i, j].sideSquare  = oldNext.sideSquare;
            board[i, j].pieceSquare = oldNext.pieceSquare;
            board[i, j].moved       = oldNext.moved;

            board[selectedI, selectedJ].sideSquare  = oldInitial.sideSquare;
            board[selectedI, selectedJ].pieceSquare = oldInitial.pieceSquare;
            board[selectedI, selectedJ].moved       = oldInitial.moved;

            checkedCooldown = Time.time;
            return(false);
        }


        //棋子移动以及棋子移动后的状态调整
        board[i, j].obj.GetComponent <Bouncy>().stopBounce(); //棋子动画停止
        paintPiece(i, j);                                     //棋子移动,具体操作将棋子的贴图赋给选择的棋盘位置上的棋子
        showPiece(i, j);                                      //让选择的棋盘为指导上的棋子显示出来
        hidePiece(selectedI, selectedJ);                      //棋子移动后,原位置上的棋子隐藏

        if (board[i, j].pieceSquare == piece.Pawn && (i == 9 || i == 2))
        {
            selectedI = i;
            selectedJ = j;

            promotion = true;
            playing   = false;
            Deselect();
            board[i, j].square.GetComponent <Square>().range();
        }
        else
        {
            changeTurn();
            if (oldNext.pieceSquare == piece.King)
            {
                theEnd();
            }
        }

        history.Add(move);
        return(true);
    }
Example #25
0
        private void UpdateGame()
        {
            // If the user presses a button, unhide the screen
            if (events.Any(e => e.type == SDL.SDL_EventType.SDL_KEYUP ||
                           e.type == SDL.SDL_EventType.SDL_MOUSEBUTTONUP) &&
                screenHidden &&
                !pressedSomething)
            {
                screenHidden     = false;
                pressedSomething = true;
            }

            // Check if the user is done preparing in skaktego
            if (gameState.gameType == GameTypes.SkaktegoPrep &&
                events.Any(e => e.type == SDL.SDL_EventType.SDL_KEYUP &&
                           e.key.keysym.sym == SDL.SDL_Keycode.SDLK_RETURN) &&
                !pressedSomething)
            {
                if (storedMove.HasValue)
                {
                    storedMove.TakeMVar(x => x);
                }
                storedMove.Var = Game.DONE_PREPARING_MOVE;

                pressedSomething = true;
            }

            int mouseX, mouseY;

            SDL.SDL_GetMouseState(out mouseX, out mouseY);

            if (events.Any(e => e.type == SDL.SDL_EventType.SDL_KEYUP &&
                           e.key.keysym.sym == SDL.SDL_Keycode.SDLK_ESCAPE) &&
                !pressedSomething)
            {
                isMenuActive     = !isMenuActive;
                pressedSomething = true;
            }

            Rect boardRect = new Rect(0, 0, 0, 0);

            {
                // Board size
                int bs = gameState.board.Size;
                boardRect.W = Math.Min(screenRect.H / bs * bs, screenRect.W / bs * bs);
                boardRect.H = Math.Min(screenRect.H / bs * bs, screenRect.W / bs * bs);
            }

            boardRect.X = (int)Math.Round((screenRect.W - boardRect.W) * 0.5);
            boardRect.Y = (int)Math.Round((screenRect.H - boardRect.H) * 0.5);

            int boardMouseX = (int)Math.Floor((mouseX - boardRect.X) / (double)boardRect.W * gameState.board.Size);
            int boardMouseY = -1 + gameState.board.Size - ((int)Math.Floor((mouseY - boardRect.Y) / (double)boardRect.H * gameState.board.Size));

            if (isMenuActive)
            {
                foreach (Button button in buttons)
                {
                    if (pressedSomething)
                    {
                        break;
                    }
                    pressedSomething |= button.Update(mouseX, mouseY, boardRect, events);
                }
            }
            else if (!screenHidden)
            {
                Rect xButtonRect = new Rect(0, 0, 0, 0);
                xButtonRect.W = (Math.Min(screenRect.H, screenRect.W) / 16);
                xButtonRect.H = (Math.Min(screenRect.H, screenRect.W) / 16);

                xButtonRect.X = screenRect.W - (Math.Min(screenRect.H, screenRect.W) / 12);
                xButtonRect.Y = (Math.Min(screenRect.H, screenRect.W) / 50);
                foreach (Button button in gameButtons)
                {
                    if (pressedSomething)
                    {
                        break;
                    }
                    pressedSomething |= button.Update(mouseX, mouseY, xButtonRect, events);
                }

                if (!doneGaming)
                {
                    if (0 <= boardMouseX && boardMouseX < gameState.board.Size)
                    {
                        if (0 <= boardMouseY && boardMouseY < gameState.board.Size)
                        {
                            highlightedTile = new BoardPosition(boardMouseX, boardMouseY);
                        }
                        else
                        {
                            highlightedTile = null;
                        }
                    }
                    else
                    {
                        highlightedTile = null;
                    }
                    if (events.Any(e => e.type == SDL.SDL_EventType.SDL_MOUSEBUTTONUP &&
                                   e.button.button == SDL.SDL_BUTTON_LEFT) &&
                        !pressedSomething
                        )
                    {
                        pressedSomething = true;
                        // If a tile is already selected, attempt to apply the move
                        if (selectedTile.HasValue &&
                            highlightedTile.HasValue
                            )
                        {
                            ChessMove move        = new ChessMove(selectedTile.Value, highlightedTile.Value);
                            bool      isMoveLegal = false;
                            foreach (BoardPosition legalPos in legalMoves)
                            {
                                if (move.to == legalPos)
                                {
                                    isMoveLegal = true;
                                }
                            }
                            if (isMoveLegal)
                            {
                                if (storedMove.HasValue)
                                {
                                    storedMove.TakeMVar(x => x);
                                }
                                storedMove.Var = move;
                                legalMoves.Clear();
                                selectedTile    = null;
                                highlightedTile = null;
                            }
                        }
                        SelectTile(gameState, highlightedTile);
                    }
                    else if (events.Any(e => e.type == SDL.SDL_EventType.SDL_MOUSEBUTTONUP &&
                                        e.button.button == SDL.SDL_BUTTON_RIGHT) &&
                             !pressedSomething
                             )
                    {
                        selectedTile = null;
                        legalMoves.Clear();
                        pressedSomething = true;
                    }
                }
                if (doneGaming)
                {
                    foreach (Button button in endButtons)
                    {
                        if (pressedSomething)
                        {
                            break;
                        }
                        pressedSomething |= button.Update(mouseX, mouseY, screenRect, events);
                    }
                }
            }
            DrawGame(gameState);
        }
Example #26
0
        public void WhenThereIsCapture_MovingPieceAndReversingTheMoveWillReaddRemovedPieceToAvailablePieces()
        {
            var whiteKingMock     = new Mock <IChessPiece>(MockBehavior.Strict);
            var blackKingMock     = new Mock <IChessPiece>(MockBehavior.Strict);
            var pawnMock          = new Mock <IChessPiece>(MockBehavior.Strict);
            var pieceMoverMock    = new Mock <IPieceMover>(MockBehavior.Strict);
            var piecesFactoryMock = new Mock <IPiecesFactory>(MockBehavior.Strict);

            var whiteKingPosition = new Position(4, 0);
            var blackKingPosition = new Position(4, 7);
            var pawnPosition      = new Position(4, 1);

            var chessMove = new ChessMove(whiteKingPosition, new Position(4, 1), true);

            whiteKingMock
            .SetupGet(k => k.Color)
            .Returns(ChessColor.White);
            whiteKingMock
            .SetupGet(k => k.PieceType)
            .Returns(ChessPieceType.King);
            whiteKingMock
            .SetupGet(k => k.Position)
            .Returns(whiteKingPosition);

            blackKingMock
            .SetupGet(k => k.Color)
            .Returns(ChessColor.Black);
            blackKingMock
            .SetupGet(k => k.PieceType)
            .Returns(ChessPieceType.King);
            blackKingMock
            .SetupGet(k => k.Position)
            .Returns(blackKingPosition);

            pawnMock
            .SetupGet(k => k.Color)
            .Returns(ChessColor.Black);
            pawnMock
            .SetupGet(k => k.PieceType)
            .Returns(ChessPieceType.Pawn);
            pawnMock
            .SetupGet(k => k.Position)
            .Returns(pawnPosition);

            pieceMoverMock
            .Setup(p => p.Move(chessMove, It.IsAny <IEnumerable <IChessPiece> >()))
            .Returns(pawnMock.Object);
            pieceMoverMock
            .Setup(p => p.ReverseLastMove(It.IsAny <IEnumerable <IChessPiece> >()))
            .Returns(chessMove.IsCapture);

            var pieces = new HashSet <IChessPiece>();

            pieces.Add(whiteKingMock.Object);
            pieces.Add(blackKingMock.Object);
            pieces.Add(pawnMock.Object);

            piecesFactoryMock
            .Setup(f => f.Create())
            .Returns(pieces);

            var chessBoard = new ChessBoard(piecesFactoryMock.Object, pieceMoverMock.Object);

            chessBoard.Move(chessMove);
            chessBoard.ReverseLastMove();

            Assert.AreEqual(3, chessBoard.Pieces.Count());
            Assert.Contains(whiteKingMock.Object, chessBoard.Pieces.ToList());
            Assert.Contains(blackKingMock.Object, chessBoard.Pieces.ToList());
            Assert.Contains(pawnMock.Object, chessBoard.Pieces.ToList());
        }
Example #27
0
        public ChessMove Get(string id)
        {
            string connstr = Environment.GetEnvironmentVariable("DWKDBConnectionString");

            using (DWKDBDataContext DB = new DWKDBDataContext(connstr))
            {
                id = id.Replace("x", ".");
                var    parms  = id.Split('|');
                Player player = null;

                ChessMove move = new ChessMove();
                move.WebID    = parms[0];
                move.ThisMove = parms[1];

                // here we will want to do some validation

                // first we will want to validate that the parameters look correct.
                // TODO: verify parameters

                var            movesList = DB.GetGameByWebID(move.WebID).ToList();
                CastleCriteria cc        = CheckForCastleCriteria(movesList);

                if (cc.lastPlayerIsWhite)
                {
                    //if last player was white then player is black
                    player = new Player(SQLChess.PlayerColor.Black);
                    player.KingHasMoved       = cc.BlackKingHasMoved;
                    player.KingsRookHasMoved  = cc.BlackKingsRookHasMoved;
                    player.QueensRookHasMoved = cc.BlackQueensRookHasMoved;
                    move.Color = "B";
                }
                else
                {
                    player = new Player(SQLChess.PlayerColor.White);
                    player.KingHasMoved       = cc.WhiteKingHasMoved;
                    player.KingsRookHasMoved  = cc.WhiteKingsRookHasMoved;
                    player.QueensRookHasMoved = cc.WhiteQueensRookHasMoved;
                    move.Color = "W";
                }

                if (movesList.Count == 0)
                {
                    player.OpponentsMove = "RNBKQBNRPPPPPPPP................................pppppppprnbkqbnr";
                    player.MyLastMove    = "";
                }

                else if (movesList.Count == 1)
                {
                    player.OpponentsMove = movesList.Last().Board;
                    player.MyLastMove    = "";
                }

                else
                {
                    player.OpponentsMove = movesList.Last().Board;
                    player.MyLastMove    = movesList.Skip(movesList.Count - 2).First().Board;
                }


                List <string> legalMoves = player.FindLegalMoves();

                if (legalMoves.Count < 1)
                {
                    bool inCheck = player.AmIChecked(player.OpponentsMove);
                    if (inCheck)
                    {
                        move.ThisMove    = string.Format("Checkmate: {0} loses.", player.PlayerIsWhite ? "White" : "Black");
                        move.IsCheckmate = true;
                        DB.SaveMove(move.WebID, move.ThisMove);
                        DB.SaveGameByWebID(move.WebID);
                        return(move);
                    }
                    else
                    {
                        move.ThisMove    = string.Format("Stalemate: {0} out of legal moves.", player.PlayerIsWhite ? "White" : "Black");
                        move.IsStalemate = true;
                        DB.SaveMove(move.WebID, move.ThisMove);
                        DB.SaveGameByWebID(move.WebID);
                        return(move);
                    }
                }

                else if (legalMoves.Contains(move.ThisMove))
                {
                    DB.SaveMove(move.WebID, move.ThisMove);
                    move.MyLastMove  = player.MyLastMove;
                    move.IsLegalMove = true;
                }
                else
                {
                    move.MyLastMove  = player.MyLastMove;
                    move.ThisMove    = player.OpponentsMove.Replace(".", "x");
                    move.IsLegalMove = false;
                    return(move);
                }

                //*-------------------------------------------


                movesList = DB.GetGameByWebID(move.WebID).ToList();
                cc        = CheckForCastleCriteria(movesList);

                if (cc.lastPlayerIsWhite)
                {
                    //if last player was white then player is black
                    player = new Player(SQLChess.PlayerColor.Black);
                    player.KingHasMoved       = cc.BlackKingHasMoved;
                    player.KingsRookHasMoved  = cc.BlackKingsRookHasMoved;
                    player.QueensRookHasMoved = cc.BlackQueensRookHasMoved;
                    move.Color = "B";
                }
                else
                {
                    player = new Player(SQLChess.PlayerColor.White);
                    player.KingHasMoved       = cc.WhiteKingHasMoved;
                    player.KingsRookHasMoved  = cc.WhiteKingsRookHasMoved;
                    player.QueensRookHasMoved = cc.WhiteQueensRookHasMoved;
                    move.Color = "W";
                }

                if (movesList.Count > 1)
                {
                    player.MyLastMove = movesList.Skip(movesList.Count - 2).First().Board;
                }
                else
                {
                    player.MyLastMove = "";
                }

                player.OpponentsMove = movesList.Skip(movesList.Count - 2).Last().Board;

                move.ThisMove = player.Move();

                if (move.ThisMove == string.Format("Checkmate: {0} loses.", player.PlayerIsWhite ? "White" : "Black"))
                {
                    move.IsCheckmate = true;
                    DB.SaveMove(move.WebID, move.ThisMove);
                    DB.SaveGameByWebID(move.WebID);
                    return(move);
                }

                else if (move.ThisMove == string.Format("Stalemate: {0} out of legal moves.", player.PlayerIsWhite ? "White" : "Black"))
                {
                    move.IsStalemate = true;
                    DB.SaveMove(move.WebID, move.ThisMove);
                    DB.SaveGameByWebID(move.WebID);
                    return(move);
                }

                else
                {
                    DB.SaveMove(move.WebID, move.ThisMove);
                    move.IsLegalMove = true;
                    move.ThisMove    = move.ThisMove.Replace(".", "x");
                    return(move);
                }
            }
        }
Example #28
0
        /// <summary>
        /// Validates a move. The framework uses this to validate the opponents move.
        /// </summary>
        /// <param name="currentBoard">The board as it currently is.</param>
        /// <param name="moveToCheck">This is the move that needs to be checked to see if it's valid.</param>
        /// <param name="colorOfPlayerMoving">This is the color of the player who's making the move.</param>
        /// <returns>Returns true if the move was valid</returns>
        public bool? IsValidMove(ChessBoard currentBoard, ChessMove moveToCheck)
        {
            _moveToReturn = null;
            _isGetNextMoveCall = false;
            _isValidMove = false;

            if (this.IsHuman)
            {
                // Humans don't check the AI's moves, so just always return true
                return true;
            }

            _currentBoard = currentBoard.Clone();
            _moveToCheck = moveToCheck.Clone();
            StartAiInTimedThread(UvsChess.Gui.Preferences.CheckMoveTimeout);
            if ((_moveToReturn != null) && (_moveToReturn.Flag == ChessFlag.AIWentOverTime))
            {
                // The AI Went over time while validating the move. Signal ChessGame of this.
                return null;
            }

            return _isValidMove;
        }
Example #29
0
        // Recursively find best moves
        private static float Minimax(List <ChessMove> allMoves, Dictionary <Square, AiChessPiece> board, float[,] strength, Stack <ChessMove> moveStack, Player currentPlayer, int turnDepth, int moveDepth, int threadIndex, int turnIndex)
        {
            // Base case
            if (turnDepth == 0)
            {
                return(EvaluationValues.BoardEvaluate(board, strength, false));
            }

            // If new turn, switch players
            if (moveDepth == 0)
            {
                Player opposite = currentPlayer.Name == "player1" ? Game.Controller.Player2 : Game.Controller.Player1;
                opposite.Commanders["M"].Moved    = false;
                opposite.Commanders["R"].Moved    = false;
                opposite.Commanders["L"].Moved    = false;
                _ratings[threadIndex][turnIndex] += Minimax(GetMovesForPlayer(board, strength, opposite), board, strength, moveStack,
                                                            opposite, turnDepth - 1, 3, threadIndex, turnIndex);
            }
            else
            {
                int movesSearched = 0;
                // Iterate over possible moves
                for (int i = 0; i < allMoves.Count; i++)
                {
                    if (i >= allMoves.Count || movesSearched >= PossibleMoveDepth)
                    {
                        break;
                    }

                    ChessMove move = allMoves[i];
                    if (!board.ContainsKey(move.InitialSquare) || move.Attack && !board.ContainsKey(move.TargetSquare))
                    {
                        continue;
                    }

                    int parentNodes = 3 - moveDepth;

                    // Store results in _turns
                    if (turnDepth == TurnSearchDepth)
                    {
                        turnIndex = GetIndex(_turns[threadIndex], _ratings[threadIndex]);
                        for (int j = 0; j < parentNodes; j++)
                        {
                            _turns[threadIndex][turnIndex][j] = moveStack.Skip(parentNodes - j - 1).First();
                            _ratings[threadIndex][turnIndex] += _ratings[threadIndex][turnIndex - (j + 1)];
                        }
                    }

                    movesSearched++;
                    _totalMovesSearched++;
                    if (turnDepth == TurnSearchDepth)
                    {
                        _turns[threadIndex][turnIndex][parentNodes] = move;
                    }

                    // Save state of piece/board before making a move
                    AiChessPiece holder = null;
                    float[,] holderStrength = null;
                    bool[] commanderState = new bool[3];

                    // Make a move
                    MakeMove(board, ref strength, moveStack, move, ref holder, ref holderStrength, currentPlayer, ref commanderState);

                    // Determine next best move
                    _ratings[threadIndex][turnIndex] += Minimax(GetMovesForPlayer(board, strength, currentPlayer), board, strength,
                                                                moveStack, currentPlayer, turnDepth, moveDepth - 1, threadIndex, turnIndex);

                    // Unmake move
                    UnmakeMove(board, ref strength, moveStack, ref holder, ref holderStrength, currentPlayer, ref commanderState);
                }
            }

            return(EvaluationValues.BoardEvaluate(board, strength, false));
        }
Example #30
0
        private void RunAiInThread()
        {
            // This is the only place that IsRunning should be set to true.
            this._isTurnOver = false;
            _hasAIEndedTurn = false;

            if (_isGetNextMoveCall)
            {
                try
                {
                    _moveToReturn = this.AI.GetNextMove(_currentBoard, this.Color);
                }
                catch (Exception e)
                {
                    throw (new Exception("StudentAI.GetNextMove() threw exception: " + e.Message));
                }
            }
            else
            {
                try
                {
                    _isValidMove = this.AI.IsValidMove(_currentBoard, _moveToCheck,
                        (this.Color == ChessColor.White ? ChessColor.Black : ChessColor.White));
                }
                catch (Exception e)
                {
                    throw (new Exception("StudentAI.IsValidMove() threw exception: " + e.Message));
                }
            }

            _hasAIEndedTurn = true;
        }
Example #31
0
        // Logic for handling a move being made in AI evaluation
        private static void MakeMove(Dictionary <Square, AiChessPiece> board, ref float[,] strength, Stack <ChessMove> moves, ChessMove move, ref AiChessPiece holder, ref float[,] holderStrength, Player player, ref bool[] commanderState)
        {
            holderStrength = strength.Clone() as float[, ];
            moves.Push(move);

            AiChessPiece piece = board[move.InitialSquare];

            // make the next move
            if (move.Attack)
            {
                holder = board[move.TargetSquare];
                board.Remove(move.TargetSquare);
                if (!move.AttackOnly)
                {
                    board.Remove(move.InitialSquare);
                    board.Add(move.TargetSquare, piece);
                    piece.Position = move.TargetSquare;
                }
            }
            else
            {
                board.Remove(move.InitialSquare);
                board.Add(move.TargetSquare, piece);
                piece.Position = move.TargetSquare;
            }

            player.Commanders[piece.GetDivision()].Moved = true;
            //player.RemainingMoves--;
            commanderState[0] = player.Commanders["M"].Moved;
            commanderState[1] = player.Commanders["R"].Moved;
            commanderState[2] = player.Commanders["L"].Moved;
        }
Example #32
0
 /// <summary>
 /// gets move for a specfic piece
 /// </summary>
 public static List<ChessMove> getmovesofpiece(StudentAI ai,ChessColor color, ChessBoard board,ChessLocation location)
 {
     List<ChessMove> piecemoves = new List<ChessMove>();
     ChessMove move = new ChessMove(location,location);
     switch (board[location])
     {
         case ChessPiece.BlackPawn:
             ChessMove bdiag1 = new ChessMove(location,new ChessLocation((location.X)-1,(location.Y)+1));
             ChessMove bdown = new ChessMove(location,new ChessLocation((location.X),(location.Y)+1));
             ChessMove bdown2 = new ChessMove(location, new ChessLocation((location.X), (location.Y) + 2));
             ChessMove bdiag2 = new ChessMove(location,new ChessLocation((location.X)+1,(location.Y)+1));
             if (ai.IsValidMove(board, bdiag1, color))
                 piecemoves.Add(bdiag1);
             if (ai.IsValidMove(board, bdown, color))
                 piecemoves.Add(bdown);
             if (ai.IsValidMove(board, bdiag2, color))
                 piecemoves.Add(bdiag2);
             if (ai.IsValidMove(board, bdown2, color))
                 piecemoves.Add(bdown2);
             break;
         case ChessPiece.WhitePawn:
             ChessMove wdiag1 = new ChessMove(location,new ChessLocation((location.X)-1,(location.Y)-1));
             ChessMove wup = new ChessMove(location,new ChessLocation((location.X),(location.Y)-1));
             ChessMove wup2 = new ChessMove(location, new ChessLocation((location.X), (location.Y) - 2));
             ChessMove wdiag2 = new ChessMove(location,new ChessLocation((location.X)+1,(location.Y)-1));
             if (ai.IsValidMove(board, wdiag1, color))
                 piecemoves.Add(wdiag1);
             if (ai.IsValidMove(board, wup, color))
                 piecemoves.Add(wup);
             if (ai.IsValidMove(board, wdiag2, color))
                 piecemoves.Add(wdiag2);
             if (ai.IsValidMove(board, wup2, color))
                 piecemoves.Add(wup2);
             break;
         case ChessPiece.BlackKing:
             for (int i = -1; i < 2; i++)
             {
                 for (int j = -1; j < 2; j++)
                 {
                     move = new ChessMove(location, new ChessLocation(location.X + i, location.Y + j));
                     if(ai.IsValidMove(board,move,color))
                         piecemoves.Add(move);
                 }
             }
             break;
         case ChessPiece.WhiteKing:
             for (int i = -1; i < 2; i++)
             {
                 for (int j = -1; j < 2; j++)
                 {
                     move = new ChessMove(location, new ChessLocation(location.X + i, location.Y + j));
                     if (ai.IsValidMove(board, move, color))
                         piecemoves.Add(move);
                 }
             }
             break;
         case ChessPiece.BlackKnight:
             move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + 1));
             if(ai.IsValidMove(board,move,color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + -1));
             if(ai.IsValidMove(board,move,color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + 2));
             if(ai.IsValidMove(board,move,color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + -2));
             if(ai.IsValidMove(board,move,color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + 1));
             if(ai.IsValidMove(board,move,color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + -1));
             if(ai.IsValidMove(board,move,color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + 2));
             if(ai.IsValidMove(board,move,color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + -2));
             if(ai.IsValidMove(board,move,color))
                 piecemoves.Add(move);
             break;
         case ChessPiece.WhiteKnight:
             move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + 1));
             if (ai.IsValidMove(board, move, color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + -1));
             if (ai.IsValidMove(board, move, color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + 2));
             if (ai.IsValidMove(board, move, color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + -2));
             if (ai.IsValidMove(board, move, color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + 1));
             if (ai.IsValidMove(board, move, color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + -1));
             if (ai.IsValidMove(board, move, color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + 2));
             if (ai.IsValidMove(board, move, color))
                 piecemoves.Add(move);
             move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + -2));
             if (ai.IsValidMove(board, move, color))
                 piecemoves.Add(move);
             break;
         case ChessPiece.BlackBishop:
         case ChessPiece.WhiteBishop:
             bool flag = true;
             int x = 1;
             while(flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X + x, location.Y + x));
                 if(ai.IsValidMove(board,move,color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             x = 1;
             flag = true;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X + x, location.Y - x));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             x = 1;
             flag = true;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X - x, location.Y - x));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             x = 1;
             flag = true;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X - x, location.Y + x));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             break;
         case ChessPiece.BlackRook:
         case ChessPiece.WhiteRook:
             flag = true;
             x = 1;
             while(flag)
             {
               move = new ChessMove(location, new ChessLocation(location.X + x, location.Y));
               if (ai.IsValidMove(board, move, color))
                   piecemoves.Add(move);
               else
                   flag = false;
               x++;
             }
             x = 1;
             flag = true;
             while(flag)
             {
               move = new ChessMove(location, new ChessLocation(location.X - x, location.Y));
               if (ai.IsValidMove(board, move, color))
                   piecemoves.Add(move);
               else
                   flag = false;
               x++;
             }
             x = 1;
             flag = true;
             while(flag)
             {
               move = new ChessMove(location, new ChessLocation(location.X, location.Y+x));
               if (ai.IsValidMove(board, move, color))
                   piecemoves.Add(move);
               else
                   flag = false;
               x++;
             }
             x = 1;
             flag = true;
             while(flag)
             {
               move = new ChessMove(location, new ChessLocation(location.X, location.Y-x));
               if (ai.IsValidMove(board, move, color))
                   piecemoves.Add(move);
               else
                   flag = false;
               x++;
             }
             break;
         case ChessPiece.BlackQueen:
         case ChessPiece.WhiteQueen:
             flag = true;
             x = 1;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X + x, location.Y + x));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             x = 1;
             flag = true;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X + x, location.Y - x));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             x = 1;
             flag = true;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X - x, location.Y - x));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             x = 1;
             flag = true;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X - x, location.Y + x));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             x = 1;
             flag = true;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X + x, location.Y));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             x = 1;
             flag = true;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X - x, location.Y));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             x = 1;
             flag = true;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X, location.Y + x));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             x = 1;
             flag = true;
             while (flag)
             {
                 move = new ChessMove(location, new ChessLocation(location.X, location.Y - x));
                 if (ai.IsValidMove(board, move, color))
                     piecemoves.Add(move);
                 else
                     flag = false;
                 x++;
             }
             break;
         default:
             return piecemoves;
     }
     return piecemoves;
 }
Example #33
0
 // copy constructor
 public ChessMove(ChessMove cm)
 {
     this.move = cm.move;
 }
Example #34
0
        /// <summary>
        /// This is an end-game heuristic used only when we're down to only a few select pieces
        /// </summary>
        /// <param name="state">The state to generate the heursitic for</param>
        /// <param name="move">The state move that was made to create this new state</param>
        /// <returns>Numeric value indicating a value for this state</returns>
        public int Endgame(int[,] state, ChessMove move)
        {
            int result = 0;
            // ek = enemyKing, k = our king, r = rook/queen
            int ekRow = -1, ekCol = -1, kRow = -1, kCol = -1, rRow = -1, rCol = -1;

            bool isQueen = true;

            for (int column = 0; column < ChessBoard.NumberOfColumns; column++)
            {
                for (int row = 0; row < ChessBoard.NumberOfRows; row++)
                {
                    switch (state[column, row])
                    {
                        case -SimpleState.King:
                            ekCol = column;
                            ekRow = row;
                            break;
                        case SimpleState.King:
                            kCol = column;
                            kRow = row;
                            break;
                        case SimpleState.Rook:
                            rCol = column;
                            rRow = row;
                            isQueen = false;
                            break;
                        case SimpleState.Queen:
                            rCol = column;
                            rRow = row;
                            break;
                    }
                }
            }
            // only evaluate if there is a rook/queen
            if (rCol != -1)
            {
                // if rook is by our king, add 64 points
                if ((rCol == kCol && rRow == kRow + 1) || (rCol == kCol && rRow == kRow - 1) || (rRow == kRow && rCol == kCol + 1) ||
                    (rRow == kRow && rCol == kCol - 1) || (rCol == kCol + 1 && rRow == kRow + 1) || (rCol == kCol + 1 && rRow == kRow - 1) ||
                    (rCol == kCol - 1 && rRow == kRow + 1) || (rCol == kCol - 1 && rRow == kRow - 1))
                {
                    result += 1000;

                    // if rook is by our king and between our king and his king, add 64 more points
                    if ((!((ekCol < rCol && kCol < rCol) || (ekCol > rCol && kCol > rCol))) ||
                        (!((ekRow < rRow && kRow < rRow) || (ekRow > rRow && kRow > rRow))))
                    {
                        result += 1000;
                    }
                }
                else
                {
                    if (moveGenerator.InDanger(state, new ChessLocation(rCol, rRow)))
                        result = int.MinValue + 1;
                    // If our king is nearing their king and our Rook/Queen is not by our king, so move it closer to our king
                    else if (Math.Abs(ekCol - kCol) == 2 || Math.Abs(ekRow - kRow) == 2 && ((Math.Abs(kCol - rCol) == 1) || (Math.Abs(kRow - rRow) == 1)))
                        result += 1500;
                    // Move our king closer to thier king
                    else
                        result += ((700 - Math.Abs(ekCol - kCol) * 100) + (700 - Math.Abs(ekRow - kRow) * 100));
                }

                // find the area his king is restricted to.  Add 64 - area so that the smaller the area, the better the move
                int area = 0;
                if (rCol > ekCol && rRow < ekRow) // ek is to right and above rook
                {
                    area = (rCol) * (ChessBoard.NumberOfRows - 1 - rRow);
                    result += (64 - area);

                }
                else if (rCol > ekCol && rRow > ekRow)// ek is to the right and below rook
                {
                    area = rCol * rRow;
                    result += (64 - area);
                }
                else if (rCol < ekCol && rRow < ekRow) // ek is to the left and above rook
                {
                    area = (ChessBoard.NumberOfColumns - 1 - rCol) * (ChessBoard.NumberOfRows - 1 - rRow);
                    result += (64 - area);
                }
                else if (rCol < ekCol && rRow > ekRow) // ek is to the left and below rook
                {
                    area = (ChessBoard.NumberOfColumns - 1 - rCol) * rRow;
                    result += (64 - area);
                }
                #region Top Right Checkmate
                // checkmate king in top right corner
                if ((ekCol == 0 || ekCol == 1) && (ekRow == 6 || ekRow == 7))
                {
                    if (isQueen)
                    {
                        if (kCol == 0 || kRow == 7)
                            result = 0;
                        else if (ekRow == 7 && ekCol == 0 && rRow == 5 && rCol == 1)
                            result = 0;
                        else if (ekRow == 7 && ekCol == 0 && rRow == 6 && rCol == 2)
                            result = 0;
                        else if (ekCol == 0 && ekRow == 6 && kCol == 2 && kRow == 6 && rCol == 2 && (rRow == 7 || rRow == 5))
                            result = 0;
                        else if (ekCol == 1 && ekRow == 7 && kCol == 1 && kRow == 5 && (rCol == 2 || rCol == 0) && rRow == 5)
                            result = 0;
                        else if (ekCol == 0 && (ekRow == 6 || ekRow == 7) && kCol == 2 && (kRow == 5 || kRow == 6) &&
                            rCol == 1 && rRow != 7) // mate in one
                            result += 1000;
                        else if ((ekCol == 0 || ekCol == 1) && ekRow == 7 && (kCol == 1 || kCol == 2) && kRow == 5 &&
                            rRow == 6)
                            result += 1000;
                    }

                    if (ekRow == 7 && ekCol == 0 && kRow == 5 && kCol == 0)
                        result = 0;
                    else if (!isQueen && ekRow == 7 && ekCol == 0 && rRow == 6 && rCol == 1)
                        result = 0;
                    else if ((ekRow == 7 || ekRow == 6) && ekCol == 0 && kRow == 5 && kCol == 2 && rRow == 5 && rCol == 1)
                        result += 500;
                    else if (ekRow == 7 && ekCol == 0 && kRow == 5 && kCol == 2 && rRow == 5 && rCol == 1)
                        result += 1000;
                    else if (ekRow == 7 && (ekCol == 0 || ekCol == 1) && kRow == 5 && kCol == 2 && rRow == 6 && rCol == 2)
                        result += 500;
                    else if (ekRow == 7 && ekCol == 1 && rRow == 6 && rCol == 2 && kRow == 5 && kCol == 1) // mate in one
                        result += 1000;
                    else if (ekRow == 7 && ekCol == 0 && rRow == 6 && rCol == 2 && kRow == 4 && kCol == 1) // mate in two
                        result += 4000;
                    else if (ekRow == 7 && ekCol == 0 && kRow == 6 && kCol == 3 && rRow == 5 && rCol == 1) // mate in two
                        result += 4000;
                    else if (ekRow == 6 && ekCol == 0 && kRow == 6 && kCol == 2 && rRow == 5 && rCol == 1) // mate in one
                        result += 1000;
                }
                #endregion

                #region Top Left Checkmate
                // checkmate king in top left corner
                else if ((ekCol == 7 || ekCol == 6) && (ekRow == 6 || ekRow == 7))
                {
                    if (isQueen)
                    {
                        if (kCol == 7 || kRow == 7)
                            result = 0;
                        else if (ekRow == 7 && ekCol == 7 && rRow == 5 && rCol == 6)
                            result = 0;
                        else if (ekCol == 7 && ekRow == 6 && kCol == 5 && kRow == 6 && rCol == 5 && (rRow == 7 || rRow == 5))
                            result = 0;
                        else if (ekCol == 6 && ekRow == 7 && kCol == 6 && kRow == 5 && (rCol == 5 || rCol == 7) && rRow == 5)
                            result = 0;
                        else if (ekRow == 7 && ekCol == 7 && rRow == 6 && rCol == 5)
                            result = 0;
                        else if (ekCol == 7 && (ekRow == 6 || ekRow == 7) && kCol == 5 && (kRow == 5 || kRow == 6) &&
                            rCol == 6 && rRow != 7) // mate in one
                            result += 1000;
                        else if ((ekCol == 7 || ekCol == 6) && ekRow == 7 && (kCol == 6 || kCol == 5) && kRow == 5 &&
                            rRow == 6)
                            result += 1000;
                    }
                    if (ekRow == 7 && ekCol == 7 && kRow == 5 && kCol == 7 && rCol == 6)
                        result = 0;
                    else if (!isQueen && ekRow == 7 && ekCol == 7 && rRow == 6 && rCol == 6)
                        result = 0;
                    else if ((ekRow == 7 || ekRow == 6) && ekCol == 7 && kRow == 5 && kCol == 5 && rRow == 5 && rCol == 6)
                        result += 500;
                    else if (ekRow == 7 && ekCol == 7 && kRow == 5 && kCol == 5 && rRow == 5 && rCol == 6)
                        result += 1000;
                    else if (ekRow == 7 && (ekCol == 7 || ekCol == 6) && kRow == 5 && kCol == 5 && rRow == 6 && rCol == 5)
                        result += 500;
                    else if (ekRow == 7 && ekCol == 6 && rRow == 6 && rCol == 5 && kRow == 5 && kCol == 6)
                        result += 1000;
                    else if (ekRow == 7 && ekCol == 7 && rRow == 6 && rCol == 5 && kRow == 4 && kCol == 6)
                        result += 4000;
                    else if (ekRow == 6 && ekCol == 7 && kRow == 6 && kCol == 5 && rRow == 5 && rCol == 6)
                        result += 1000;
                    else if (ekRow == 7 && ekCol == 7 && kRow == 6 && kCol == 4 && rRow == 5 && rCol == 6)
                        result += 4000;
                }
                #endregion

                #region Bottom Left checkmate

                // checkmate king in bottom left corner
                else if ((ekCol == 7 || ekCol == 6) && (ekRow == 1 || ekRow == 0))
                {
                    if (isQueen)
                    {
                        if (kCol == 7 || kRow == 0)
                            result = 0;
                        else if (ekRow == 0 && ekCol == 7 && rRow == 2 && rCol == 6)
                            result = 0;
                        else if (ekCol == 7 && ekRow == 1 && kCol == 5 && kRow == 1 && rCol == 5 && (rRow == 0 || rRow == 2))
                            result = 0;
                        else if (ekCol == 6 && ekRow == 0 && kCol == 6 && kRow == 2 && (rCol == 5 || rCol == 7) && rRow == 2)
                            result = 0;
                        else if (ekRow == 0 && ekCol == 7 && rRow == 1 && rCol == 5)
                            result = 0;
                        else if (ekCol == 7 && (ekRow == 1 || ekRow == 0) && kCol == 5 && (kRow == 2 || kRow == 1) &&
                            rCol == 6 && rRow != 0) // mate in one
                            result += 1000;
                        else if ((ekCol == 7 || ekCol == 6) && ekRow == 0 && (kCol == 6 || kCol == 5) && kRow == 2 &&
                            rRow == 1)
                            result += 1000;
                    }
                    if (ekRow == 0 && ekCol == 7 && kRow == 2 && kCol == 7)
                        result = 0;
                    else if (!isQueen && ekRow == 0 && ekCol == 7 && rRow == 1 && rCol == 6)
                        result = 0;
                    else if ((ekRow == 0 || ekRow == 1) && ekCol == 7 && kRow == 2 && kCol == 5 && rRow == 2 && rCol == 6)
                        result += 500;
                    else if (ekRow == 0 && ekCol == 7 && kRow == 2 && kCol == 5 && rRow == 2 && rCol == 6)
                        result += 1000;
                    else if (ekRow == 0 && (ekCol == 7 || ekCol == 6) && kRow == 2 && kCol == 5 && rRow == 1 && rCol == 5)
                        result += 500;
                    else if (ekRow == 0 && ekCol == 6 && rRow == 1 && rCol == 5 && kRow == 2 && kCol == 6)
                        result += 1000;
                    else if (ekRow == 0 && ekCol == 7 && rRow == 1 && rCol == 5 && kRow == 3 && kCol == 6)
                        result += 4000;
                    else if (ekRow == 1 && ekCol == 7 && kRow == 1 && kCol == 5 && rRow == 2 && rCol == 6)
                        result += 1000;
                    else if (ekRow == 0 && ekCol == 7 && kRow == 1 && kCol == 4 && rRow == 2 && rCol == 6)
                        result += 4000;
                }
                #endregion

                #region Bottom Right Checkmate
                // checkmate king in bottom right corner
                else if ((ekCol == 0 || ekCol == 1) && (ekRow == 1 || ekRow == 0))
                {
                    if (isQueen)
                    {
                        if (kCol == 0 || kRow == 0)
                            result = 0;
                        else if (ekRow == 0 && ekCol == 0 && rRow == 2 && rCol == 1)
                            result = 0;
                        else if (ekCol == 0 && ekRow == 1 && kCol == 2 && kRow == 1 && rCol == 2 && (rRow == 0 || rRow == 2))
                            result = 0;
                        else if (ekCol == 1 && ekRow == 0 && kCol == 1 && kRow == 2 && (rCol == 2 || rCol == 0) && rRow == 2)
                            result = 0;
                        else if (ekRow == 0 && ekCol == 0 && rRow == 1 && rCol == 2)
                            result = 0;
                        else if (ekCol == 0 && (ekRow == 1 || ekRow == 0) && kCol == 2 && (kRow == 2 || kRow == 1) &&
                            rCol == 1 && rRow != 0) // mate in one
                            result += 1000;
                        else if ((ekCol == 0 || ekCol == 1) && ekRow == 0 && (kCol == 1 || kCol == 2) && kRow == 2 &&
                            rRow == 1)
                            result += 1000;
                    }
                    if (ekRow == 0 && ekCol == 0 && kRow == 2 && kCol == 0)
                        result = 0;
                    else if (!isQueen && ekRow == 0 && ekCol == 0 && rRow == 1 && rCol == 1)
                        result = 0;
                    else if ((ekRow == 0 || ekRow == 1) && ekCol == 0 && kRow == 2 && kCol == 2 && rRow == 2 && rCol == 1)
                        result += 500;
                    else if (ekRow == 0 && ekCol == 0 && kRow == 2 && kCol == 2 && rRow == 2 && rCol == 1)
                        result += 1000;
                    else if (ekRow == 0 && (ekCol == 0 || ekCol == 1) && kRow == 2 && kCol == 2 && rRow == 1 && rCol == 2)
                        result += 500;
                    else if (ekRow == 0 && ekCol == 1 && rRow == 1 && rCol == 2 && kRow == 2 && kCol == 1)
                        result += 1000;
                    else if (ekRow == 0 && ekCol == 0 && rRow == 1 && rCol == 2 && kRow == 3 && kCol == 1)
                        result += 4000;
                    else if (ekRow == 1 && ekCol == 0 && kRow == 1 && kCol == 2 && rRow == 2 && rCol == 1)
                        result += 1000;
                    else if (ekRow == 0 && ekCol == 0 && kRow == 1 && kCol == 3 && rRow == 2 && rCol == 1)
                        result += 4000;
                }

                #endregion
            }
            else
                result = 0;

            if (move.Flag == ChessFlag.Checkmate)
            {
                result += 5000;
            }

            return result;
        }
Example #35
0
        public Hueristic getMinimax(StudentAI AI, ChessBoard board, ChessColor color, int depth, ChessColor maxColor, int alpha = -999999, int beta = 999999)
        {
            //TODO update to return heuristic instead of move and update get next move to return move of heuristic.
            if (depth > maxdepth)
            {
                return(new Hueristic(board, new ChessMove(null, null), color));
            }
            List <ChessMove> allmoves = new List <ChessMove>();

            allmoves.AddRange(PieceMoves.getmovesofcolor(AI, color, board));
            List <Hueristic> HueristicMoves = new List <Hueristic>();
            //DecisionTree descisions = new DecisionTree(board);
            //descisions.

            ChessColor oppositeColor = color == ChessColor.Black ? ChessColor.White : ChessColor.Black;

            //set check/checkmate flag and calculate hueristic on each move
            foreach (var move in allmoves)
            {
                var tempBoard = board.Clone();
                tempBoard.MakeMove(move);

                if (StudentAI.IsKingInCheck(tempBoard, oppositeColor))
                {
                    move.Flag = ChessFlag.Check;
                    //check for checkmate
                    if (PieceMoves.getmovesofcolor(AI, oppositeColor, tempBoard).Count == 0)
                    {
                        move.Flag = ChessFlag.Checkmate;
                        return(new Hueristic(board, move, color));
                    }
                }

                HueristicMoves.Add(new Hueristic(board, move, color));
                if (color == maxColor && move.Flag == ChessFlag.Check)
                {
                    HueristicMoves[HueristicMoves.Count - 1].HValue += 2;
                }
                if (color == maxColor && move.Flag == ChessFlag.Checkmate)
                {
                    HueristicMoves[HueristicMoves.Count - 1].HValue = 10000;
                    return(HueristicMoves[HueristicMoves.Count - 1]);
                }
            }

            HueristicMoves.Sort((x, y) => y.HValue.CompareTo(x.HValue));


            if (AI.IsMyTurnOver() && HueristicMoves.Count > 0)
            {
                return(HueristicMoves[0]);
            }

            //if (depth == maxdepth && HueristicMoves.Count>0)
            //    return HueristicMoves[0];
            List <Hueristic> updatedhueristic = new List <Hueristic>();
            //minimax and alpha beta pruning
            bool defined = false;
            var  temp    = new List <Hueristic>();

            do
            {
                //TODO, store previous move and if we ran out of time use that one since we don't know if optimal on the next one
                temp = new List <Hueristic>();
                foreach (var hmove in HueristicMoves)
                {
                    var tempBoard = board.Clone();
                    if (hmove.TheMove != null)
                    {
                        tempBoard.MakeMove(hmove.TheMove);
                        if (depth != maxdepth)
                        {
                            var oppositemove = getMinimax(AI, tempBoard, oppositeColor, depth + 1, maxColor, alpha, beta);
                            //get best move of the other color

                            if (oppositemove.TheMove.To != null && oppositemove.TheMove.From != null)
                            {
                                hmove.HValue -= oppositemove.HValue;
                                // update our moves score based on return of projected other move
                            }
                        }
                        temp.Add(hmove); // add new scored hueristic to new list
                        if (AI.IsMyTurnOver())
                        {
                            break;
                        }
                        //a=max(a,hueristic)
                        if (maxColor == color)
                        {
                            alpha = alpha > hmove.HValue ? alpha : hmove.HValue;
                            if (beta <= alpha)
                            {
                                break;
                            }
                        }
                        else
                        {
                            beta = beta < hmove.HValue ? beta : hmove.HValue;
                            if (beta <= alpha)
                            {
                                break;
                            }
                        }
                    }
                }
                if (!AI.IsMyTurnOver())
                {
                    if (depth == 0)
                    {
                        maxdepth        += 1;
                        defined          = true;
                        updatedhueristic = temp;
                    }
                }
            } while (!AI.IsMyTurnOver() && depth == 0);
            if (!defined)
            {
                updatedhueristic = temp;
            }

            updatedhueristic.Sort((x, y) => y.HValue.CompareTo(x.HValue)); // sort the new list

            if (color == maxColor)
            {
                if (updatedhueristic.Count == 0)
                {
                    var game_over = new ChessMove(null, null);
                    game_over.Flag = ChessFlag.Stalemate;
                    var game_overhueristic = new Hueristic(board, game_over, color);
                    return(game_overhueristic);
                }
                int tiecount = -1;
                foreach (var x in updatedhueristic)
                {
                    if (x.HValue == updatedhueristic[0].HValue)
                    {
                        tiecount++;
                    }
                }
                if (tiecount > 0)
                {
                    return(updatedhueristic[rand.Next(0, tiecount)]);
                }
            }

            if (updatedhueristic.Count == 0)
            {
                return(new Hueristic(board, new ChessMove(null, null), color));
            }
            return(updatedhueristic[0]);      //return the best value from the new list
        }
        /// <summary>
        /// Converts a string representation of a move into a ChessMove object.
        /// Must work with any string representation created by MoveToString.
        /// </summary>
        public ChessMove ParseMove(string moveText)
        {
            // BoardPosition start = ParsePosition(moveText.Substring(0,2));
            // BoardPosition end = ParsePosition(moveText.Substring(4,2));
            moveText = moveText.Replace(" ", "");

            if (moveText.StartsWith("(") && moveText.EndsWith(")"))
            {
                moveText = moveText.Replace("(", "");
                moveText = moveText.Replace(")", "");
            }
            else if (moveText.StartsWith("("))
            {
                moveText = moveText.Replace("(", "");
            }
            string[]      movesArr = moveText.Split(',');
            BoardPosition start    = ParsePosition(movesArr[0]);
            BoardPosition end      = ParsePosition(movesArr[1]);

            if (movesArr.Length > 2)
            {
                String moveType = movesArr[2];
                moveType.ToLower();
                ChessMove move = new ChessMove(start, end, ChessMoveType.Normal);

                switch (moveType)
                {
                case "queen":
                    move = new ChessMove(start, end, ChessPieceType.Queen);
                    break;

                case "rook":
                    move = new ChessMove(start, end, ChessPieceType.Rook);
                    break;

                case "bishop":
                    move = new ChessMove(start, end, ChessPieceType.Bishop);
                    break;

                case "knight":
                    move = new ChessMove(start, end, ChessPieceType.Knight);
                    break;

                case "castlequeenside":
                    move = new ChessMove(start, end, ChessMoveType.CastleQueenSide);
                    break;

                case "castlekingside":
                    move = new ChessMove(start, end, ChessMoveType.CastleKingSide);
                    break;

                case "enpassant":
                    move = new ChessMove(start, end, ChessMoveType.EnPassant);
                    break;

                case "Queen":
                    move = new ChessMove(start, end, ChessPieceType.Queen);
                    break;

                case "Rook":
                    move = new ChessMove(start, end, ChessPieceType.Rook);
                    break;

                case "Bishop":
                    move = new ChessMove(start, end, ChessPieceType.Bishop);
                    break;

                case "Knight":
                    move = new ChessMove(start, end, ChessPieceType.Knight);
                    break;

                case "Castlequeenside":
                    move = new ChessMove(start, end, ChessMoveType.CastleQueenSide);
                    break;

                case "Castlekingside":
                    move = new ChessMove(start, end, ChessMoveType.CastleKingSide);
                    break;

                case "Enpassant":
                    move = new ChessMove(start, end, ChessMoveType.EnPassant);
                    break;
                }
                return(move);
            }
            else if (moveText.Equals("e1,g1") || moveText.Equals("e8,g8"))
            {
                return(new ChessMove(start, end, ChessMoveType.CastleKingSide));
            }
            else if (moveText.Equals("e1,c1") || moveText.Equals("e8,c8"))
            {
                return(new ChessMove(start, end, ChessMoveType.CastleQueenSide));
            }
            else
            {
                return(new ChessMove(start, end, ChessMoveType.Normal));
            }
        }
Example #37
0
        /// <summary>
        /// Applies a move for the current player at the given position.
        /// </summary>
        public void ApplyMove(BoardPosition position)
        {
            var possMoves = mBoard.GetPossibleMoves() as IEnumerable <ChessMove>;

            // Validate the move as possible.
            foreach (var move in possMoves)
            {
                if (SelectedSquare.Position.Equals(move.StartPosition) && move.EndPosition.Equals(position))
                {
                    if (move.MoveType == ChessMoveType.PawnPromote)
                    {
                        var window = new PawnPromotionWindow(this, move.StartPosition, move.EndPosition);
                        window.ShowDialog();
                        Promote = window.promotePicked;
                        ChessMove m = new ChessMove(move.StartPosition, move.EndPosition, ChessMove.StringToPromoType(Promote), ChessMoveType.PawnPromote);
                        mBoard.ApplyMove(m);
                        foreach (var s in mSquares)
                        {
                            s.KingInCheck = false;
                        }
                        SelectedState = false;
                        break;
                    }

                    else
                    {
                        mBoard.ApplyMove(move);
                        foreach (var s in mSquares)
                        {
                            s.KingInCheck = false;
                        }
                        SelectedState = false;
                        break;
                    }
                }
            }

            RebindState();

            if (mBoard.IsFinished)
            {
                GameFinished?.Invoke(this, new EventArgs());
            }
        }
Example #38
0
 public bool CheckAndMakeAMove(ChessMove move)
 {
     return((chessClient.InvokeMethod <bool?>("CheckAndMakeAMove", new object[] { move })).Value);
 }
Example #39
0
        public async Task WriteBoard(ChessMove lastMove, ChessGame chessGame, Stream stream)
        {
            await Task.Run(() =>
            {
                var board = SixLabors.ImageSharp.Image.Load(_assetService.GetImagePath("board.png"));

                var boardPieces = chessGame.GetBoard();

                Dictionary <int, int> RankToRowMap = new Dictionary <int, int>
                {
                    { 1, 7 },
                    { 2, 6 },
                    { 3, 5 },
                    { 4, 4 },
                    { 5, 3 },
                    { 6, 2 },
                    { 7, 1 },
                    { 8, 0 }
                };

                board.Mutate(processor =>
                {
                    for (var columnIndex = 0; columnIndex < boardPieces.Length; columnIndex++)
                    {
                        for (var rowIndex = 0; rowIndex < boardPieces[columnIndex].Length; rowIndex++)
                        {
                            if (
                                lastMove != null &&
                                (
                                    ((int)lastMove.OriginalFile == columnIndex && RankToRowMap[lastMove.OriginalRank] == rowIndex) ||
                                    ((int)lastMove.NewFile == columnIndex && RankToRowMap[lastMove.NewRank] == rowIndex)
                                )
                                )
                            {
                                DrawImage(processor, "yellow_square", columnIndex, rowIndex);
                            }

                            var piece = boardPieces[rowIndex][columnIndex];

                            if (piece != null)
                            {
                                var fenCharacter = piece.GetFenCharacter();

                                if (fenCharacter.ToString().ToUpper() == "K" && chessGame.IsInCheck(piece.Owner))
                                {
                                    DrawImage(processor, "red_square", columnIndex, rowIndex);
                                }

                                var prefix = "white";

                                if (new[] { 'r', 'n', 'b', 'q', 'k', 'p' }.Contains(fenCharacter))
                                {
                                    prefix = "black";
                                }

                                DrawImage(processor, $"{prefix}_{fenCharacter.ToString().ToLower()}", columnIndex, rowIndex);
                            }
                        }
                    }
                });

                board.SaveAsPng(stream);
            });
        }
Example #40
0
        private int MinValue(int[,] state, ChessMove move, int depth, int alpha, int beta)
        {
            if (depth < 0 || move.Flag == ChessFlag.Checkmate)
                return move.ValueOfMove;

            state = moveGenerator.GetEnemyState(state);

            int value = int.MaxValue;

            List<ChessMove> allPossibleMoves = moveGenerator.GetAllMoves(state, true, boardEvaluator);

            // Sort the moves to get the most out of Alpha Beta Pruning
            allPossibleMoves.Sort((x, y) => y.ValueOfMove.CompareTo(x.ValueOfMove));

            for (int i = 0; i < allPossibleMoves.Count && !timesUp(); i++)
            {
                ChessMove currentMove = allPossibleMoves[i];

                value = Math.Min(value, MaxValue(moveGenerator.GetStateAfterMove(state, currentMove), currentMove, depth - 1, alpha, beta));

                if (value <= alpha)
                    return value;

                beta = Math.Min(beta, value);
            }

            return value;
        }
        /// <summary>
        /// Applies a move for the current player at the given position.
        /// </summary>
        public async Task ApplyMove(BoardPosition position)
        {
            var possMoves = mBoard.GetPossibleMoves() as IEnumerable <ChessMove>;

            // Validate the move as possible.
            foreach (var move in possMoves)
            {
                if (SelectedSquare.Position.Equals(move.StartPosition) && move.EndPosition.Equals(position))
                {
                    if (move.MoveType == ChessMoveType.PawnPromote)
                    {
                        var window = new PawnPromotionWindow(this, move.StartPosition, move.EndPosition);
                        window.ShowDialog();
                        Promote = window.promotePicked;
                        ChessMove m = new ChessMove(move.StartPosition, move.EndPosition, ChessMove.StringToPromoType(Promote), ChessMoveType.PawnPromote);
                        mBoard.ApplyMove(m);
                        foreach (var s in mSquares)
                        {
                            s.KingInCheck = false;
                        }
                        SelectedState = false;
                        break;
                    }

                    else
                    {
                        mBoard.ApplyMove(move);
                        foreach (var s in mSquares)
                        {
                            s.KingInCheck = false;
                        }
                        SelectedState = false;
                        break;
                    }
                }
            }
            RebindState();

            if (Players == NumberOfPlayers.One && !mBoard.IsFinished)
            {
                var bestMove = await Task.Run(() => mGameAi.FindBestMove(mBoard));

                if (bestMove != null)
                {
                    mBoard.ApplyMove(bestMove as ChessMove);
                }
            }

            RebindState();

            if (mBoard.IsFinished)
            {
                GameFinished?.Invoke(this, new EventArgs());
            }
            //Show Boardweight in a message box when a move is applied
            //MessageBox.Show("Board Weight: " + mBoard.BoardWeight);
        }
        public void WhenBlackKingIsCheckedReturnsTrue()
        {
            //BK - black king
            //WP - white pawn
            //7             BK
            //6          WP
            //5
            //4
            //3
            //2
            //1
            //0
            //  0  1  2  3  4  5  6  7
            var boardMock    = new Mock <IChessBoard>(MockBehavior.Strict);
            var movementMock = new Mock <IMovement>(MockBehavior.Strict);

            var kingColor       = ChessColor.Black;
            var kingMock        = new Mock <IReadOnlyChessPiece>(MockBehavior.Strict);
            var enemyMock       = new Mock <IReadOnlyChessPiece>(MockBehavior.Strict);
            var kingPosition    = new Position(4, 7);
            var enemyPosition   = new Position(3, 6);
            var enemyChessMove1 = new ChessMove(enemyPosition, kingPosition, true);
            var enemyChessMove2 = new ChessMove(enemyPosition, new Position(3, 7), false);

            kingMock
            .SetupGet(k => k.Position)
            .Returns(kingPosition);
            kingMock
            .SetupGet(k => k.Color)
            .Returns(kingColor);

            enemyMock
            .SetupGet(e => e.Position)
            .Returns(enemyPosition);
            enemyMock
            .SetupGet(e => e.Color)
            .Returns(kingColor.Opposite());

            boardMock
            .Setup(b => b.GetKing(kingColor))
            .Returns(kingMock.Object);
            boardMock
            .SetupGet(b => b.Pieces)
            .Returns(new List <IReadOnlyChessPiece>()
            {
                kingMock.Object, enemyMock.Object
            });

            movementMock
            .Setup(m => m.GetAvailableMoves(enemyMock.Object))
            .Returns(new List <ChessMove>()
            {
                enemyChessMove1, enemyChessMove2
            });

            var checkDetector = new CheckDetector(boardMock.Object,
                                                  movementMock.Object);

            var isChecked = checkDetector.IsChecked(kingColor);

            Assert.AreEqual(true, isChecked);
        }
Example #43
0
    public bool move(int i, int j)
    {
        ChessMove move = new ChessMove();

        move.castling    = false;
        move.initialPos  = new Vector2(selectedI, selectedJ);
        move.finalPos    = new Vector2(i, j);
        move.eatenPiece  = board [i, j].pieceSquare;
        move.moved       = board [selectedI, selectedJ].moved;
        move.eatenSide   = board [i, j].sideSquare;
        move.eatenMoved  = board [i, j].moved;
        move.movingPiece = board [selectedI, selectedJ].pieceSquare;

        /* Guardamos los datos de las 2 */
        ChessSquare oldInitial = board [selectedI, selectedJ].Clone();
        ChessSquare oldNext    = board [i, j].Clone();

        /* Se copian los datos de la ficha */
        board [i, j].sideSquare  = board [selectedI, selectedJ].sideSquare;
        board [i, j].pieceSquare = board [selectedI, selectedJ].pieceSquare;
        board [i, j].moved       = true;

        /* Se formatea la antigua celda */
        board [selectedI, selectedJ].sideSquare  = side.None;
        board [selectedI, selectedJ].pieceSquare = piece.None;
        board [selectedI, selectedJ].moved       = true;

        /* Comprobamos futuro jaque. Restablecemos si es invalido el movimiento. */
        AttacksTable t = new AttacksTable(board, !white);

        if (checkCheck(board, oldInitial.sideSquare, t))
        {
            board [i, j].sideSquare  = oldNext.sideSquare;
            board [i, j].pieceSquare = oldNext.pieceSquare;
            board [i, j].moved       = oldNext.moved;

            board [selectedI, selectedJ].sideSquare  = oldInitial.sideSquare;
            board [selectedI, selectedJ].pieceSquare = oldInitial.pieceSquare;
            board [selectedI, selectedJ].moved       = oldInitial.moved;

            checkedCooldown = Time.time;
            return(false);
        }


        /* Se paran los botecitos y se desplaza la ficha */
        board [i, j].obj.GetComponent <Bouncy>().stopBounce();
        paintPiece(i, j);
        showPiece(i, j);
        hidePiece(selectedI, selectedJ);

        /* Se comprueba coronamiento y se efectua */
        if (board [i, j].pieceSquare == piece.Pawn && (i == 9 || i == 2))
        {
            selectedI = i;
            selectedJ = j;

            promotion = true;
            playing   = false;
            Deselect();
            board [i, j].square.GetComponent <Square>().range();
        }
        else
        {
            changeTurn();
            if (oldNext.pieceSquare == piece.King)
            {
                theEnd();
            }
        }

        history.Add(move);
        return(true);
    }
Example #44
0
 public void HumanMovedPieceEvent(ChessMove move)
 {
     if (this.IsHuman)
     {
         _moveToReturn = move;
         _waitForPlayerEvent.Set();
     }
 }
Example #45
0
File: AI.CS Project: mhs294/Csharp
    //This function is called each time it is your turn
    //Return true to end your turn, return false to ask the server for updated information
    public override bool run()
    {
        // Print out the current board state
        Console.WriteLine("+---+---+---+---+---+---+---+---+");
        for (int rank = 8; rank > 0; rank--)
        {
            Console.Write("|");
            for (int file = 1; file <= 8; file++)
            {
                bool found = false;
                // Loops through all of the pieces
                for (int p = 0; !found && p < pieces.Length; p++)
                {
                    // determines if that piece is at the current rank and file
                    if (pieces[p].getRank() == rank && pieces[p].getFile() == file)
                    {
                        found = true;
                        // Checks if the piece is black
                        if (pieces[p].getOwner() == 1)
                        {
                            Console.Write("*");
                        }
                        else
                        {
                            Console.Write(" ");
                        }
                        // prints the piece's type
                        Console.Write((char)pieces[p].getType() + " ");
                    }
                }
                if (!found)
                {
                    Console.Write("   ");
                }
                Console.Write("|");
            }
            Console.WriteLine("\n+---+---+---+---+---+---+---+---+");
        }

        // Looks through information about the players
        for (int p = 0; p < players.Length; p++)
        {
            Console.Write(players[p].getPlayerName());
            // if playerID is 0, you're white, if its 1, you're black
            if (players[p].getId() == myID)
            {
                Console.Write(" (ME)");

                // update timeRemaining
                timeRemaining = players[p].getTime();
            }
            Console.WriteLine(" time remaining: " + players[p].getTime());
        }

        // if there has been a move, print the most recent move
        if (moves.Length > 0)
        {
            Console.Write("Last Move Was: ");
            Console.WriteLine(files[moves[0].getFromFile() - 1] + "" + moves[0].getFromRank() + "-" + files[moves[0].getToFile() - 1] + "" + moves[0].getToRank());
        }

        /////////////////////////////////////
        // <-- END OF STOCK AI.cs CODE --> //
        /////////////////////////////////////

        // print current move number
        Console.WriteLine("\nMove " + turnNumber().ToString("D3") + "\n========\n");

        // add to GameState List and update ChessBoard
        if (moves.Length <= 1)
        {
            board = new ChessBoard(ref pieces, myID);
            states.Add(new GameState(null, null));
        }
        else
        {
            ChessMove lastMove = ChessMove.GetChessMove(moves[0].getFromFile(), moves[0].getToFile(), moves[0].getFromRank(), moves[0].getToRank(),
                                                        moves[0].getPromoteType(), states[states.Count - 1].enPassant);
            board = new ChessBoard(ref pieces, myID);
            states.Add(new GameState(states[states.Count - 1], lastMove));
        }

        // display current score information for player
        Console.Write("Score for ");
        if (myID == ChessBoard.WHITE)
        {
            Console.WriteLine("WHITE:\n");
        }
        else if (myID == ChessBoard.BLACK)
        {
            Console.WriteLine("BLACK:\n");
        }
        int material = Score.GetMaterialScore(myID);
        int position = Score.GetPositionScore(myID);
        // int mobility = Score.GetPositionScore(myID);
        int pawn_structure = Score.GetPawnStructureScore(myID);
        int king_safety    = Score.GetKingSafetyScore(myID);

        Console.WriteLine("Net Material = " + material);
        Console.WriteLine("Net Position = " + position);
        //Console.WriteLine("Net Mobility = " + mobility);
        Console.WriteLine("Net Pawn Structure = " + pawn_structure);
        Console.WriteLine("Net King Safety = " + king_safety + "\n");
        Console.WriteLine("Overall Score = " + (material + position + /*mobility +*/ pawn_structure + king_safety) + "\n");

        // if playing as human, get move from console prompt
        while (HUMAN_PLAYER)
        {
            // get legal moves for this position
            List <ChessMove> legalMoves = MoveGen.GenerateMoves(myID, false);

            // prompt user for move
            Console.Write("Enter a move ([from] [to] <promotion type>): ");
            string[] humanMove = Console.ReadLine().Split(' ');

            // get origin square
            int humanFromFile = 0, humanFromRank = 0;
            for (int i = 0; i < 8; i++)
            {
                if (humanMove[0][0] == files[i])
                {
                    humanFromFile = i + 1;
                    break;
                }
            }
            humanFromRank = (int)Char.GetNumericValue(humanMove[0][1]);

            // get destination square
            int humanToFile = 0, humanToRank = 0;
            for (int i = 0; i < 8; i++)
            {
                if (humanMove[1][0] == files[i])
                {
                    humanToFile = i + 1;
                    break;
                }
            }
            humanToRank = (int)Char.GetNumericValue(humanMove[1][1]);

            // if promotion type is specified, get the promotion piece from move
            int humanPromote = 0;
            if (humanMove.Length > 2)
            {
                humanPromote = (int)humanMove[2][0];
            }

            // check for legality of human move
            bool isLegal = false;
            for (int i = 0; i < legalMoves.Count; i++)
            {
                ChessMove m = legalMoves[i];
                if ((ChessMove.GetFile(m.GetFromSq()) + 1) == (uint)humanFromFile &&
                    (ChessMove.GetRank(m.GetFromSq()) + 1) == (uint)humanFromRank &&
                    (ChessMove.GetFile(m.GetToSq()) + 1) == (uint)humanToFile &&
                    (ChessMove.GetRank(m.GetToSq()) + 1) == (uint)humanToRank)
                {
                    isLegal = true;
                    break;
                }
            }

            // if move is legal, make move
            if (isLegal)
            {
                // get Piece associated with move
                Piece humanPiece = pieces[FindPiece(humanFromFile, humanFromRank)];

                // make move
                humanPiece.move(humanToFile, humanToRank, humanPromote);
                return(true);
            }
            else if (!isLegal)
            {
                Console.WriteLine("ILLEGAL MOVE. Please input a legal move.\n");
            }
        }

        // reset TIME_EXPIRED and timer
        TIME_EXPIRED = false;
        timer.Reset();

        // reset history table
        history = new HistoryTable();

        // run ABMiniMax
        int  moveScore = 0, n = 0, toFile = -1, toRank = -1;
        uint fromSq = 0, toSq = 0, thePiece = 0;

        depth = 0;
        List <ChessMove> completeBestMoves = new List <ChessMove>(0);

        Search.UpdateTimePerMove(moves.Length);
        timer.Start();
        while (!TIME_EXPIRED)
        {
            depth                  += 1;
            nodes                   = 0;
            Search.MAX_DEPTH        = depth;
            Search.NULLMOVE_ALLOWED = true;
            Search.FOLLOW_PV        = true;
            Search.PV               = new List <ChessMove>(0);
            int score = Search.PVABMiniMax(0, Search.SMALL_NUM, Search.LARGE_NUM);
            if (score != Score.TIME_EXPIRED_SCORE)
            {
                moveScore         = score;
                completeBestMoves = new List <ChessMove>(Search.PV);
            }

            // select random move from bestMoves List
            if (completeBestMoves.Count > 0)
            {
                n = generator.Next(0, completeBestMoves.Count - 1);

                // get bestMove info
                fromSq   = completeBestMoves[n].GetFromSq();
                thePiece = completeBestMoves[n].GetPiece();
                toSq     = completeBestMoves[n].GetToSq();
                toFile   = (int)((toSq % 8) + 1);
                toRank   = (int)((toSq / 8) + 1);

                // print bestMove info
                Console.WriteLine("Best Move: " + completeBestMoves[n].GetMoveString() + ", Score: " + moveScore + ", Depth: " + depth + " (t = " +
                                  (timer.ElapsedMilliseconds / 1000.0).ToString("F3") + "s, nodes = " + nodes + ")");
            }

            // if checkmate is found, stop searching
            if (score == Score.CHECKMATE_WIN_SCORE)
            {
                break;
            }
        }
        timer.Stop();

        // output number of best moves
        Console.WriteLine("completeBestMoves = " + completeBestMoves.Count);

        // make bestMove
        pieces[FindPiece(fromSq, thePiece)].move(toFile, toRank, completeBestMoves[n].GetPromoteType());

        // update ChessBoard and GameState List
        completeBestMoves[n].DoMove(Search.MAKE);

        return(true);
    }
Example #46
0
 private void GracePeriodTimer(object state)
 {
     if (! _hasAIEndedTurn)
     {
         // The AI is still running, even after the grace period.
         // They've now lost!
         _moveToReturn = new ChessMove(null, null);
         _moveToReturn.Flag = ChessFlag.AIWentOverTime;
         _aiThread.Abort();
     }
 }
Example #47
0
        public void WhenThereIsCapture_Move_ReturnsCapturedPiece_IncrementsMoveCounter_AndAddsMoveToMovmentHistory()
        {
            var movementHistory    = new Mock <IMovementHistory>(MockBehavior.Strict);
            var promoterMock       = new Mock <IPiecePromoter>(MockBehavior.Strict);
            var castlingMoverMock  = new Mock <ICastlingMover>(MockBehavior.Strict);
            var enPassantMoverMock = new Mock <IEnPassantMover>(MockBehavior.Strict);
            var movedPieceMock     = new Mock <IChessPiece>(MockBehavior.Strict);
            var otherPieceMock     = new Mock <IChessPiece>(MockBehavior.Strict);
            var capturedPieceMock  = new Mock <IChessPiece>(MockBehavior.Strict);

            var piecePosition = new Position(3, 1);
            var destination   = new Position(3, 3);
            var chessMove     = new ChessMove(piecePosition, destination);

            movedPieceMock
            .SetupGet(p => p.Position)
            .Returns(piecePosition);
            movedPieceMock
            .SetupSet(p => p.Position = destination);
            movedPieceMock
            .Setup(p => p.IncrementMoveCounter());

            otherPieceMock
            .SetupGet(p => p.Position)
            .Returns(new Position(1, 1));
            capturedPieceMock
            .SetupGet(p => p.Position)
            .Returns(destination);

            var pieces = new List <IChessPiece>()
            {
                movedPieceMock.Object,
                otherPieceMock.Object,
                capturedPieceMock.Object
            };

            promoterMock
            .Setup(p => p.PromoteIfPromotionMove(chessMove, pieces))
            .Returns(false);

            castlingMoverMock
            .Setup(c => c.PerformCastlingIfCastlingMove(chessMove, pieces))
            .Returns(false);

            enPassantMoverMock
            .Setup(e => e.PerformEnPassantIfApplicable(chessMove, pieces))
            .Returns <IChessPiece>(null);

            movementHistory
            .Setup(h => h.Add(chessMove.ReturnWithCaptureAsTrue()));

            var pieceMover = new PieceMover(movementHistory.Object, promoterMock.Object,
                                            castlingMoverMock.Object, enPassantMoverMock.Object);
            var result = pieceMover.Move(chessMove, pieces);

            Assert.AreEqual(capturedPieceMock.Object, result);
            movedPieceMock
            .VerifySet(p => p.Position = destination);
            movedPieceMock
            .Verify(p => p.IncrementMoveCounter());
            movementHistory
            .Verify(h => h.Add(chessMove.ReturnWithCaptureAsTrue()));
        }
        // Make a new board state by applying a new move to an already existing board state.
        public BoardState(BoardState previousState, ChessMove newMove, bool lookForCheck = true)
        {
            BoardGrid = new ChessPiece[8, 8];
            if (!newMove.KingsideCastle && !newMove.QueensideCastle)
            {
                HashSet<ChessMove> previousPossibleMoves = previousState.GetPossibleMoves(newMove.From);
                if (!previousPossibleMoves.Contains(newMove))
                {
                    throw new BoardStateException("Illegal move.");
                }
            }
            // Copy elements.
            for (int row = 0; row < 8; row++)
            {
                for (int column = 0; column < 8; column++)
                {
                    Coordinate coordinate = new Coordinate(row, column);
                    SetPieceAtCoordinate(previousState.GetPieceAtCoordinate(coordinate), coordinate);
                }
            }
            // Copy other board state values.
            BlackKingsideCastling = previousState.BlackKingsideCastling;
            BlackQueensideCastling = previousState.BlackQueensideCastling;
            WhiteKingsideCastling = previousState.WhiteKingsideCastling;
            WhiteQueensideCastling = previousState.WhiteQueensideCastling;
            // Turn color will be flipped and fullmove/halfmove will be incremented after move is applied.
            TurnColor = previousState.TurnColor;
            FullMove = previousState.FullMove;
            HalfMove = previousState.HalfMove;
            // Reset En Passant.
            EnPassantTarget = new Coordinate(-1, -1);
            // Castling special case.
            if (newMove.KingsideCastle || newMove.QueensideCastle)
            {
                int row = TurnColor == ChessPieceColor.White ? FirstRowWhite : FirstRowBlack;
                int rookStartColumn = newMove.KingsideCastle ? KingsideRookColumn : QueensideRookColumn;
                int kingEndColumn = newMove.KingsideCastle ? KingsideCastledKingColumn : QueensideCastledKingColumn;
                int rookEndColumn = newMove.KingsideCastle ? KingsideCastledRookColumn : QueensideCastledRookColumn;
                var kingStart = new Coordinate(row, KingStartColumn);
                var kingEnd = new Coordinate(row, kingEndColumn);
                var rookStart = new Coordinate(row, rookStartColumn);
                var rookEnd = new Coordinate(row, rookEndColumn);
                SetPieceAtCoordinate(new ChessPiece(ChessPieceColor.None, ChessPieceType.None), kingStart);
                SetPieceAtCoordinate(new ChessPiece(ChessPieceColor.None, ChessPieceType.None), rookStart);
                SetPieceAtCoordinate(new ChessPiece(TurnColor, ChessPieceType.King), kingEnd);
                SetPieceAtCoordinate(new ChessPiece(TurnColor, ChessPieceType.Rook), rookEnd);
                if (TurnColor == ChessPieceColor.White)
                {
                    WhiteKingsideCastling = false;
                    WhiteQueensideCastling = false;
                }
                else
                {
                    BlackKingsideCastling = false;
                    BlackQueensideCastling = false;
                }
            }
            // All other move types.
            else
            {
                // If en passant
                if (newMove.PieceType == ChessPieceType.Pawn)
                {
                    if (previousState.EnPassantTarget.Equals(newMove.To))
                    {
                        if (TurnColor == ChessPieceColor.White)
                        {
                            SetPieceAtCoordinate(new ChessPiece(ChessPieceColor.None, ChessPieceType.None), new Coordinate(newMove.To, -1, 0));
                        }
                        else
                        {
                            SetPieceAtCoordinate(new ChessPiece(ChessPieceColor.None, ChessPieceType.None), new Coordinate(newMove.To, 1, 0));
                        }
                    }
                    // Mark if the new move triggers the possibilty of an En Passant from the following turn.

                    int pawnDoubleFromRow = TurnColor == ChessPieceColor.White ? 1 : 6;
                    int pawnDoubleToRow = TurnColor == ChessPieceColor.White ? 3 : 4;
                    int enPassantTargetTargetRow = TurnColor == ChessPieceColor.White ? 2 : 5;
                    if (newMove.From.Row == pawnDoubleFromRow && newMove.To.Row == pawnDoubleToRow)
                    {
                        EnPassantTarget = new Coordinate(enPassantTargetTargetRow, newMove.From.Column);
                    }
                }
                // King movements disable castling.
                else if (newMove.PieceType == ChessPieceType.King)
                {
                    if (TurnColor == ChessPieceColor.White)
                    {
                        WhiteKingsideCastling = false;
                        WhiteQueensideCastling = false;
                    }
                    else
                    {
                        BlackKingsideCastling = false;
                        BlackQueensideCastling = false;
                    }
                }
                // Rook movements disable on their side.
                else if (newMove.PieceType == ChessPieceType.Rook)
                {
                    if (TurnColor == ChessPieceColor.White)
                    {
                        if (newMove.From.Equals(new Coordinate(FirstRowWhite, KingsideRookColumn)))
                        {
                            WhiteKingsideCastling = false;
                        }
                        else if (newMove.From.Equals(new Coordinate(FirstRowWhite, QueensideRookColumn)))
                        {
                            WhiteQueensideCastling = false;
                        }
                    }
                    else
                    {
                        if (newMove.From.Equals(new Coordinate(FirstRowBlack, KingsideRookColumn)))
                        {
                            BlackKingsideCastling = false;
                        }
                        else if (newMove.From.Equals(new Coordinate(FirstRowBlack, QueensideRookColumn)))
                        {
                            BlackQueensideCastling = false;
                        }
                    }
                }
                // Set square that the piece is moving from to empty, and moving to to have the piece.
                SetPieceAtCoordinate(new ChessPiece(ChessPieceColor.None, ChessPieceType.None), newMove.From);
                SetPieceAtCoordinate(new ChessPiece(TurnColor, newMove.IsPromotionToQueen ? ChessPieceType.Queen : newMove.PieceType), newMove.To);
            }

            // Reset or increment halfMove.
            if (newMove.IsCapture || newMove.PieceType == ChessPieceType.Pawn)
            {
                HalfMove = 0;
            }
            else
            {
                HalfMove++;
            }

            // Set applied move to be the previous move.
            PreviousMove = newMove;

            // Increment fullMove after blacks turn;
            if (TurnColor == ChessPieceColor.Black)
            {
                FullMove++;
            }

            // Switch turns.
            TurnColor = previousState.TurnColor == ChessPieceColor.White ? ChessPieceColor.Black : ChessPieceColor.White;

            bool isCheck = false;
            bool isCheckMate = false;
            if (lookForCheck)
            {
                new BoardState(this, out isCheck, out isCheckMate);
                PreviousMove = new ChessMove(PreviousMove.From, PreviousMove.To, PreviousMove.PieceType, PreviousMove.IsCapture, PreviousMove.IsPromotionToQueen, PreviousMove.DrawOfferExtended, isCheck, isCheckMate, PreviousMove.KingsideCastle, PreviousMove.QueensideCastle);
            }
            // Finally, determine the list of legal moves.
            InitializeAllPossibleMoves();
        }
Example #49
0
 public ChessOption(ChessMove move, int score)
 {
     this.move   = move;
     this.points = score;
 }
        // Determine what the previous move was using Long Algebraic Notation, for example: Rd3xd7Q.
        private void ParseLongAlgebraicNotation(string moveString)
        {
            moveString = moveString.Trim();
            int rowFrom, columnFrom, rowTo, columnTo;
            ChessPieceType movePieceType;
            bool isCapture = false, isPromotionToQueen = false, drawOfferExtended = false, isCheck = false, isCheckMate = false;

            int i = 0;
            int minLength;

            bool moveIsKingsideCastle = false;
            bool moveIsQueensideCastle = false;

            // Special case: no moves yet.
            if (moveString.Length == 0)
            {
                PreviousMove = new ChessMove(new Coordinate(-1, -1), new Coordinate(-1, -1), ChessPieceType.None, false, false, false, false, false, false, false);
                return;
            }

            // Special case: castling moves. Must be done in this order because QUEENSIDE_CASTLING_STRING ("0-0-0") starts with KINGSIDE_CASTLING_STRING("0-0").
            if (moveString.StartsWith(QueensideCastlingString))
            {
                movePieceType = ChessPieceType.King;
                moveIsQueensideCastle = true;
                i += QueensideCastlingString.Length;
                // Set to invalid values for special case of castling.
                rowFrom = -1; columnFrom = -1; rowTo = -1; columnTo = -1;
            }
            else if (moveString.StartsWith(KingsideCastlingString))
            {
                movePieceType = ChessPieceType.King;
                moveIsKingsideCastle = true;
                i += KingsideCastlingString.Length;
                // Set to invalid values for special case of castling.
                rowFrom = -1; columnFrom = -1; rowTo = -1; columnTo = -1;
            }
            else
            {

                // Check to see if the first character refers to the type of piece. If it is not, it is implicity a pawn.
                if (moveString.Length > 0 && CharToChessPieceType.ContainsKey(moveString[i]))
                {
                    movePieceType = CharToChessPieceType[moveString[i]];
                    i++;
                    // How many characters to inspect depends on whether or not the piece type was implicitly a pawn
                    minLength = MinimumAlgebraicNotationLength + 1;
                }
                else
                {
                    movePieceType = ChessPieceType.Pawn;
                    minLength = MinimumAlgebraicNotationLength;
                }

                if (moveString.Length < minLength)
                {
                    throw new BoardStateException(string.Format("Invalid Long Algebraic Notation '{0}'. Long Algebraic Notation is too few characters to be valid.", moveString));
                }

                if (FileToColumn.ContainsKey(moveString[i]))
                {
                    columnFrom = FileToColumn[moveString[i]];
                    i++;
                }
                else
                {
                    throw new BoardStateException(string.Format("Invalid Long Algebraic Notation '{0}'. Ivalid file character '{1}'", moveString, moveString[i]));
                }
                if (Char.IsNumber(moveString[i]) && moveString[i] != '0' && moveString[i] != '9')
                {
                    rowFrom = Convert.ToInt32(Char.GetNumericValue(moveString[i])) - 1;
                    i++;
                }
                else
                {
                    throw new BoardStateException(string.Format("Invalid Long Algebraic Notation '{0}'. Ivalid rank character '{1}'", moveString, moveString[i]));
                }
                if (moveString[i] == '-')
                {
                    isCapture = false;
                    i++;
                }
                else if (moveString[i] == 'x')
                {
                    isCapture = true;
                    i++;
                }
                else
                {
                    throw new BoardStateException(string.Format("Invalid Long Algebraic Notation '{0}'. Ivalid capture character '{1}'", moveString, moveString[i]));
                }

                if (FileToColumn.ContainsKey(moveString[i]))
                {
                    columnTo = FileToColumn[moveString[i]];
                    i++;
                }
                else
                {
                    throw new BoardStateException(string.Format("Invalid Long Algebraic Notation '{0}'. Ivalid file character '{1}'", moveString, moveString[i]));
                }
                if (Char.IsNumber(moveString[i]) && moveString[i] != '0' && moveString[i] != '9')
                {
                    rowTo = Convert.ToInt32(Char.GetNumericValue(moveString[i])) - 1;
                    i++;
                }
                else
                {
                    throw new BoardStateException(string.Format("Invalid Long Algebraic Notation '{0}'. Ivalid rank character '{1}'", moveString, moveString[i]));
                }
            }

            // Loop the rest of the characters, if any, which are flags that can be in any order
            while (i < moveString.Length)
            {
                if (moveString[i] == 'Q')
                {
                    isPromotionToQueen = true;
                }
                else if (moveString[i] == '=')
                {
                    drawOfferExtended = true;
                }
                else if (moveString[i] == '+')
                {
                    isCheck = true;
                }
                else if (moveString[i] == '#')
                {
                    isCheckMate = true;
                }
                else
                {
                    throw new BoardStateException(string.Format("Invalid Long Algebraic Notation '{0}'. Invalid flag character '{1}'", moveString, moveString[i]));
                }
                i++;
            }
            PreviousMove = new ChessMove(new Coordinate(rowFrom, columnFrom), new Coordinate(rowTo, columnTo), movePieceType, isCapture, isPromotionToQueen, drawOfferExtended, isCheck, isCheckMate, moveIsKingsideCastle, moveIsQueensideCastle);
        }
Example #51
0
 public ChessMoveWrapper(ChessMove chessMove)
 {
     ChessMove = chessMove;
 }
Example #52
0
        public void MakeMove(ChessMove move)
        {
            PreviousMove = move;
            PreviousBoard = CurrentBoard.Clone();
            CurrentBoard.MakeMove(move);

            if (CurrentPlayerColor == ChessColor.White)
            {
                CurrentPlayerColor = ChessColor.Black;
            }
            else
            {
                CurrentPlayerColor = ChessColor.White;
            }
        }
        private async void Border_MouseUpAsync(object sender, MouseButtonEventArgs e)
        {
            Border b                 = sender as Border;
            var    square            = b.DataContext as ChessSquare;
            var    currentlySelected = ChessViewModel.CurrentlySelected;

            if (currentlySelected != null)
            {
                if (currentlySelected.Position.Equals(square.Position))
                {
                    square.IsSelected                = false;
                    square.IsHighlighted             = true;
                    ChessViewModel.CurrentlySelected = null;
                }
                else
                {
                    var possibleMoves = from ChessMove m in GetPossibleMovesByStartPosition(currentlySelected)
                                        where m.EndPosition.Equals(square.Position)
                                        select m;
                    if (possibleMoves.Any())
                    {
                        ChessMove move = possibleMoves.First();
                        if (move.MoveType == ChessMoveType.PawnPromote)
                        {
                            PawnPromotion window = new PawnPromotion(ChessViewModel, currentlySelected.Position, square.Position)
                            {
                                ResizeMode  = ResizeMode.NoResize,
                                WindowStyle = WindowStyle.None
                            };
                            window.ShowDialog();
                        }
                        else
                        {
                            if (ChessViewModel.IsCheck)
                            {
                                ChessViewModel.FindKingSquareInCheck().IsInCheck = false;
                            }
                            var window = Window.GetWindow(this);
                            window.IsEnabled = false;
                            await ChessViewModel.ApplyMove(move);

                            window.IsEnabled = true;
                        }
                        square.IsHighlighted = false;
                    }
                    else
                    {
                        ChessViewModel.CurrentlySelected.IsSelected = false;
                        if (IncomingSelectionIsValidChessPiece(square))
                        {
                            square.IsSelected = true;
                            ChessViewModel.CurrentlySelected = square;
                        }
                        else
                        {
                            ChessViewModel.CurrentlySelected = null;
                        }
                    }
                }
            }
            else
            {
                if (IncomingSelectionIsValidChessPiece(square))
                {
                    square.IsHighlighted             = false;
                    square.IsSelected                = true;
                    ChessViewModel.CurrentlySelected = square;
                }
            }
        }