Example #1
0
        public void PieceMoustActuallyMove()
        {
            // Given
            Piece             rook     = new Rook(Colour.White);
            StartSquare       a1       = new StartSquare("a1");
            DestinationSquare a1AsWell = new DestinationSquare("a1");

            long gameId = 101;
            Game target = new Game(gameId);

            target.Board.PutPieceOn(a1, rook);

            // When
            MakeMove command = new MakeMove(gameId, new Move(rook.Code, a1, a1AsWell));
            Action   act     = () =>
            {
                target.MakeMove(command);
            };

            // Then
            var ex = Assert.ThrowsException <BusinessRuleViolationException>(act);

            Assert.AreEqual("Rule Violations: 1 violations have been detected.", ex.Message);
            Assert.AreEqual(1, ex.Violations.Count());
            Assert.IsTrue(ex.Violations.Any(v => v.ViolationMessage == "The start square cannot be the same as the destination square."));
        }
Example #2
0
        public static int GetLine(int depth, Board board)
        {
            Debug.Assert(depth < Variables.MAX_DEPTH);

            int move  = PvTable.Probe(board);
            int count = 0;

            while (move != Variables.NO_MOVE && count < depth)
            {
                if (MakeMove.MoveExists(board, move))
                {
                    MakeMove.Make_Move(board, move);
                    board.PvArray[count++] = move;
                }
                else
                {
                    break;
                }

                move = PvTable.Probe(board);
            }

            // Take back the performed moves, so board position stay unchanged.
            while (board.Ply > 0)
            {
                MakeMove.TakeMove(board);
            }

            return(count);
        }
Example #3
0
        /// <summary>
        ///     Counts the amount of leafNode at the parameter input depth,
        ///     by an inorder recursive tree traversion algorithm.
        ///     It checks all legal moves with the parameter input depth,
        ///     and increments the leafNode counter when the "last" move
        ///     (the leaf) has been located.
        /// </summary>
        /// <param name="depth"> The depth to traverse </param>
        /// <param name="board"> The chess board operate on </param>
        /// <exception cref="Exception"></exception>
        public void _Perft(int depth, Board board)   // For counting the TOTAL available moves
        {
            Debug.Assert(BoardOperations.CheckBoard(board));
            // Increment leafNode and return.
            if (depth == 0)
            {
                LeafNodes++;
                return;
            }

            // Generate moves for rootposition
            MoveList list = new MoveList();

            MoveGen.GenerateAllMoves(board, list, false);

            for (int i = 0; i < list.Count; ++i)
            {
                if (!MakeMove.Make_Move(board, list.Moves[i].Move))
                {
                    continue;
                }

                _Perft(depth - 1, board);
                MakeMove.TakeMove(board);
            }
        }
Example #4
0
        public void MakeMoveRaisesEvent()
        {
            // Given
            Piece             rook = new Rook(Colour.White);
            StartSquare       a1   = new StartSquare("a1");
            DestinationSquare a4   = new DestinationSquare("a4");

            long gameId = 101;
            Game target = new Game(gameId);

            target.Board.PutPieceOn(a1, rook);

            // When
            MakeMove command = new MakeMove(gameId, new Move(rook.Code, a1, a4));

            target.MakeMove(command);

            // Then
            DomainEvent result = target.Events.Single();

            Assert.IsInstanceOfType(result, typeof(MoveMade));
            MoveMade movemade = (MoveMade)result;

            Assert.AreEqual(gameId, movemade.GameId);
            Assert.AreEqual('R', movemade.PieceCode);
            Assert.AreEqual("a1", movemade.StartSquare);
            Assert.AreEqual("a4", movemade.DestinationSquare);
        }
Example #5
0
        public void Perft_Test(int depth, Board board)   // Also prints information regarding the moves
        {
            Debug.Assert(BoardOperations.CheckBoard(board));
            var startTime = Variables.Watch.ElapsedMilliseconds;

            Console.Write("\nStarting Perft Test to Depth {0}", depth);
            BoardOperations.PrintBoard(board);

            LeafNodes = 0;

            MoveList list = new MoveList();

            MoveGen.GenerateAllMoves(board, list, false);


            for (int i = 0; i < list.Count; ++i)
            {
                int move = list.Moves[i].Move;

                if (!MakeMove.Make_Move(board, list.Moves[i].Move))
                {
                    continue;
                }

                long cumulativeNodes = LeafNodes;
                _Perft(depth - 1, board);
                MakeMove.TakeMove(board);
                long oldNodes = LeafNodes - cumulativeNodes;
                Console.Write("\nmove {0} : {1} : {2}", i + 1, Io.MoveToString(move), oldNodes);
            }

            Console.Write("\nTest Complete: {0} nodes visited in {1} miliseconds\n", LeafNodes, Variables.Watch.ElapsedMilliseconds - startTime);
        }
Example #6
0
        private void playCurrentPlayerTurn(Move i_CurrentMove, Player i_PlayerTurn, Player i_NotPlayerTurn)
        {
            bool isLegal = isLegalMove(i_CurrentMove, i_PlayerTurn);

            if (!isLegal)
            {
                InvalidMove.Invoke(this, EventArgs.Empty);
            }
            else
            {
                MakeMove.Invoke(i_CurrentMove, EventArgs.Empty);
                i_CurrentMove.MoveOnTable(r_GameTable);

                if (i_PlayerTurn.IsJumpTurn)
                {
                    if (hasAnotherJump(i_CurrentMove, i_PlayerTurn))
                    {
                        m_LegalJumps = getListOfJumpsForPiece(i_PlayerTurn.GetShapeType(), i_CurrentMove.TargetPiece);
                    }
                    else
                    {
                        v_TurnPlayer1           = !v_TurnPlayer1;
                        i_PlayerTurn.IsJumpTurn = false;
                    }
                }
                else
                {
                    v_TurnPlayer1 = !v_TurnPlayer1;
                }
            }
        }
        public static MakeMove FromDTO(long id, DTO.MakeMove dtoCommand)
        {
            string notation = dtoCommand.Notation;

            PieceCode         pieceCode;
            StartSquare       start;
            DestinationSquare destination;

            if ("RNBQK".Contains(notation.First()))
            {
                Enum.TryParse(dtoCommand.Notation.Substring(0, 1), out pieceCode);
                start       = new StartSquare(dtoCommand.Notation.Substring(1, 2));
                destination = new DestinationSquare(dtoCommand.Notation.Substring(4, 2));
            }
            else
            {
                pieceCode   = PieceCode.None;
                start       = new StartSquare(dtoCommand.Notation.Substring(0, 2));
                destination = new DestinationSquare(dtoCommand.Notation.Substring(3, 2));
            }

            var move   = new Move(pieceCode, start, destination);
            var result = new MakeMove(id, move);

            return(result);
        }
Example #8
0
        private void playCurrentPlayerTurn(Move i_CurrentMove, Player i_PlayerTurn, Player i_NotPlayerTurn)
        {
            bool isValid = isValidMove(i_CurrentMove, i_PlayerTurn);

            if (!isValid)
            {
                InvalidMove.Invoke(this, EventArgs.Empty);
            }
            else
            {
                MakeMove.Invoke(i_CurrentMove, EventArgs.Empty);
                i_CurrentMove.MoveOnBoard(m_BoardGame);

                if (i_PlayerTurn.IsJumpTurn)
                {
                    if (hasAnotherJump(i_CurrentMove, i_PlayerTurn))
                    {
                        m_LegalJumps = getListOfJumpsForPiece(i_PlayerTurn.GetShapeType(), i_CurrentMove.ToSquare);
                    }
                    else
                    {
                        v_Turn = !v_Turn;
                        i_PlayerTurn.IsJumpTurn = false;
                    }
                }
                else
                {
                    v_Turn = !v_Turn;
                }
            }
        }
Example #9
0
        public async Task <IActionResult> MakeMove(long id, [FromBody] DTO.MakeMove dtoCommand)
        {
            //if (!ModelState.IsValid)
            //{
            //    return BadRequest("not a valid move.");
            //}

            try
            {
                MakeMove command = DTOMapper.FromDTO(id, dtoCommand);
                await _makeMoveCommandHandler.HandleCommandAsync(command);

                return(Ok());
            }
            catch (GameNotFoundException ex)
            {
                return(NotFound(ex.Message));
            }
            catch (BusinessRuleViolationException brve)
            {
                return(StatusCode(StatusCodes.Status409Conflict, brve.Violations));
            }
            //catch
            //{
            //    return StatusCode(501);
            //}
        }
Example #10
0
 void Start()
 {
     GameManager.Instance.OnGameStateChanged.AddListener(HandleGameStateChanged);
     actions = transform.GetComponentInChildren <ActionList>().actions;
     foreach (var act in actions)
     {
         act.Initialize(gameObject);
         act.onActionFinished.AddListener(HandleOnActionFinished);
     }
     action += actions[actionNum].makeAction;
 }
Example #11
0
    // Use this for initialization
    void Start()
    {
        actions = transform.GetComponentInChildren <ActionList>().actions;
        foreach (var action in actions)
        {
            action.Initialize(gameObject);
            action.onActionFinished.AddListener(HandleOnActionFinished);
        }

        action += actions[actionNum].makeAction;
    }
Example #12
0
        public MakeMoveResponse CreateMove(string gameId, string playerId, [FromBody] MakeMove request)
        {
            var game = GetGame(gameId);

            if (request?.Column == null)
            {
                throw new HttpResponseException(HttpStatusCode.BadRequest);
            }

            var moveNumber = game.AddMove(playerId, request.Column);

            return(new MakeMoveResponse(gameId, moveNumber));
        }
Example #13
0
        private void OnPawnMakeMove(object sender, EventArgs e)
        {
            var pawnControl        = gameBoardTableLayoutPanel.Controls.OfType <CellControl>().Single(x => x.CapturedMouse);
            var placeholderControl = (CellControl)sender;
            var position           = gameBoardTableLayoutPanel.GetPositionFromControl(placeholderControl);

            var move = pawnControl.Pawn.AvailableMoves.Single(x => x.DestinatedPosition.Row == position.Row && x.DestinatedPosition.Column == position.Column);

            if (MakeMove != null)
            {
                MakeMove.Invoke(this, move);
            }
        }
Example #14
0
        public void MakeMove(MakeMove command)
        {
            BusinessRule.ThrowIfNotSatisfied(
                new PieceMustActuallyMove(command.Move)
                & new PieceMustOccupyStartingSquare(Board, command.Move)
                & new MoveIsValidForPiece(Board, command.Move)
                // & new MovePathIsUnobstructed(Board, command.Move)
                );

            MoveMade e = command.Move.MapToMoveMade(this.Id);

            RaiseEvent(e);
        }
Example #15
0
    private void HandleOnActionFinished(Move thatMove)
    {
        Debug.Log("Action finished");

        if (!thatMove.dontUnsub)
        {
            action -= thatMove.makeAction;
        }

        if (actionNum < actions.Count - 1)
        {
            actionNum++;
            action += actions[actionNum].makeAction;
        }
    }
Example #16
0
        /*
         * private void playFirstMoveOfGame()
         * {
         *  string currentMoveString = GameUI.GetFirstMoveFromUser(m_Player1, m_BoardGame);
         *
         *  if (GameUI.IsQuitInput(currentMoveString))
         *  {
         *      m_GameStatus = eGameStatus.Draw;
         *      GameUI.PrintGamePointStatus(this);
         *  }
         *
         *  else
         *  {
         *      Move currentMove = getMoveFromString(currentMoveString);
         *
         *      while (!currentMove.CheckIsValidMove(m_Player1.GetShapeType()))
         *      {
         *          GameUI.PrintErrorOfMove(Move.eTypeOfMove.Regular);
         *          currentMoveString = GameUI.GetFirstMoveFromUser(m_Player1, m_BoardGame);
         *          currentMove = getMoveFromString(currentMoveString);
         *      }
         *
         *      currentMove.MoveOnBoard(m_BoardGame);
         *      this.v_Turn = false;
         *  }
         *
         *
         * }
         *
         *
         *
         */

        public void playComputerTurn()
        {
            List <Move> computerJumpsMoves     = m_BoardGame.GetListOfPlayerJumps(Player.eShapeType.O);
            int         lengthOfJumpsList      = computerJumpsMoves.Count;
            Move        currentMoveForComputer = null;

            if (lengthOfJumpsList > 0)
            {
                while (lengthOfJumpsList > 0)
                {
                    int indexOfJumplMove = s_Random.Next(0, lengthOfJumpsList);
                    currentMoveForComputer          = computerJumpsMoves[indexOfJumplMove];
                    currentMoveForComputer.MoveType = Move.eTypeOfMove.Jump;


                    MakeMove.Invoke(currentMoveForComputer, EventArgs.Empty);
                    currentMoveForComputer.MoveOnBoard(m_BoardGame);

                    m_Player2.IsJumpTurn = true;

                    if (hasAnotherJump(currentMoveForComputer, m_Player2))
                    {
                        computerJumpsMoves = getListOfJumpsForPiece(m_Player2.GetShapeType(), currentMoveForComputer.ToSquare);
                        lengthOfJumpsList  = computerJumpsMoves.Count;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else
            {
                List <Move> computerDiagonalMoves = m_BoardGame.GetListOfPlayerDiagonalMoves(Player.eShapeType.O);
                int         lengthOfListDiagonal  = computerDiagonalMoves.Count;
                int         indexOfDiagonalMove   = s_Random.Next(0, lengthOfListDiagonal);
                currentMoveForComputer          = computerDiagonalMoves[indexOfDiagonalMove];
                currentMoveForComputer.MoveType = Move.eTypeOfMove.Regular;
                currentMoveForComputer.MoveOnBoard(m_BoardGame);
                MakeMove.Invoke(currentMoveForComputer, EventArgs.Empty);
            }
            v_Turn = !v_Turn;
        }
        public async Task HandleCommandAsync(MakeMove command)
        {
            // restore game
            Game game = await _gameRepo.FindAsync(command.GameId);

            if (game == null)
            {
                throw new GameNotFoundException($"A game with id {command.GameId} could not be found.");
            }

            // handle command
            game.MakeMove(command);

            // persist game
            await _gameRepo.SaveAsync(game);

            // publish events
            await _eventPublisher.PublishEventsAsync(game.Events);
        }
Example #18
0
        public void MakeMoveMovesPieceOnBoard()
        {
            // Given
            Piece             rook = new Rook(Colour.White);
            StartSquare       a1   = new StartSquare("a1");
            DestinationSquare a4   = new DestinationSquare("a4");

            Game target = new Game(1);

            target.Board.PutPieceOn(a1, rook);

            // When
            MakeMove command = new MakeMove(1, new Move(rook.Code, a1, a4));

            target.MakeMove(command);

            // Then
            Assert.IsTrue(target.Board.IsEmptyAt(a1), "rook should not be on a1");
            Assert.IsTrue(target.Board.HasThisPieceOn(a4, rook.Code), "rook should be on a4");
        }
Example #19
0
        internal void PlayComputerTurn()
        {
            List <Move> computerJumpsMoves     = r_GameTable.GetPlayerJumpsList(eShapeType.O);
            int         lengthOfJumpsList      = computerJumpsMoves.Count;
            Move        currentMoveForComputer = null;

            if (lengthOfJumpsList > 0)
            {
                while (lengthOfJumpsList > 0)
                {
                    int indexOfJumplMove = r_Random.Next(0, lengthOfJumpsList);
                    currentMoveForComputer          = computerJumpsMoves[indexOfJumplMove];
                    currentMoveForComputer.MoveType = eMoveType.Jump;
                    MakeMove.Invoke(currentMoveForComputer, EventArgs.Empty);
                    currentMoveForComputer.MoveOnTable(r_GameTable);
                    r_Player2.IsJumpTurn = true;

                    if (hasAnotherJump(currentMoveForComputer, r_Player2))
                    {
                        computerJumpsMoves = getListOfJumpsForPiece(r_Player2.GetShapeType(), currentMoveForComputer.TargetPiece);
                        lengthOfJumpsList  = computerJumpsMoves.Count;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else
            {
                List <Move> computerDiagonalMoves = r_GameTable.GetListOfPlayerDiagonalMoves(eShapeType.O);
                int         lengthOfListDiagonal  = computerDiagonalMoves.Count;
                int         indexOfDiagonalMove   = r_Random.Next(0, lengthOfListDiagonal);
                currentMoveForComputer          = computerDiagonalMoves[indexOfDiagonalMove];
                currentMoveForComputer.MoveType = eMoveType.Diagonal;
                MakeMove.Invoke(currentMoveForComputer, EventArgs.Empty);
                currentMoveForComputer.MoveOnTable(r_GameTable);
            }
            v_TurnPlayer1 = !v_TurnPlayer1;
        }
Example #20
0
        public GameManager(Field[,] boardFields, PlayerManager playerManager, GameConfiguration gameConfiguration)
        {
            GameConfiguration = gameConfiguration;
            BoardFields       = boardFields;
            BoardSize         = boardFields.GetLength(0);
            PlayerManager     = playerManager;
            RegisterDelegates();

            MakeMove MakeMove = new MakeMove(BoardFields, PlayerManager, GameConfiguration);

            MakeMove.FieldClicked += FieldClickedSecondTimeHandler;

            CheckerMoves.Add(new UnclickRedundantFields(BoardFields));
            CheckerMoves.Add(new SelectCurrentField(BoardFields, PlayerManager));
            CheckerMoves.Add(new ShowPossibleMoves(BoardFields, PlayerManager, GameConfiguration));
            CheckerMoves.Add(new IsSelectedAsPossibleMove());
            CheckerMoves.Add(MakeMove);
            CheckerMoves.Add(new CheckWinner(BoardFields, PlayerManager, GameConfiguration));
            CheckerMoves.Add(new MakeQueen(BoardSize));

            GlowPossibleMoves = new GlowPossibleMoves(BoardFields, GameConfiguration);
            GlowPossibleMoves.MarkPossibleMoves(PlayerManager.GetCurrentPlayer());
            PlayerManager.PlayerChanged += GlowPossibleMoves.PlayerChangedHandler;
        }
Example #21
0
        private void OnPanelMouseClick(object sender, MouseEventArgs e)
        {
            if (IsPlaceholder)
            {
                if (MakeMove != null)
                {
                    MakeMove.Invoke(this, EventArgs.Empty);
                }

                return;
            }

            if (Pawn == null || !Pawn.AvailableMoves.Any())
            {
                return;
            }

            if (CapturedMouse)
            {
                CapturedMouse = false;

                if (ReleaseMouse != null)
                {
                    ReleaseMouse.Invoke(this, EventArgs.Empty);
                }
            }
            else
            {
                CapturedMouse = true;

                if (CaptureMouse != null)
                {
                    CaptureMouse.Invoke(this, EventArgs.Empty);
                }
            }
        }
Example #22
0
 public static void All()
 {
     Hash.Init();
     MakeMove.InitCastleBoard();
     MoveGenerator.InitMoveGenerator();
 }
Example #23
0
        // should read "position fen"
        //             "position startpos"
        // which could possibly be followed by  "... moves a2a3 a3a4" etc.
        public void ParsePosition(string lineIn, Board board)
        {
            int stringIndex = 9;                       // starts at 9 cause position is length 8
            int moveIndex   = lineIn.IndexOf("moves"); // is there any moves to consider?

            if (lineIn.Length >= stringIndex + 8 &&
                lineIn.Substring(stringIndex, 8).Equals("startpos"))
            {
                BoardOperations.ParseFen(Fens.START_FEN, board);
            }
            else     // Else "position fen fenstring"
            {
                if (lineIn.Length >= stringIndex + 3 &&
                    lineIn.Substring(stringIndex, 3).Equals("fen"))
                {
                    stringIndex += 4; // should be at start of fenstring now.
                    if (moveIndex == -1)
                    {
                        BoardOperations.ParseFen(lineIn.Substring(stringIndex), board);
                    }
                    else
                    {
                        BoardOperations.ParseFen(
                            lineIn.Substring(stringIndex, moveIndex - stringIndex - 1), board);
                    }
                }
                else
                {
                    BoardOperations.ParseFen(Fens.START_FEN, board);
                }
            }

            if (moveIndex != -1)             // moves were found.
            {
                stringIndex = moveIndex + 6; // We are now at start of command moves. moves |a2a3
                int move = Variables.NO_MOVE;

                while (stringIndex <= lineIn.Length - 1)
                {
                    stringIndex += 5;

                    if (lineIn.Length > stringIndex && lineIn[stringIndex - 1] == ' ')
                    {
                        move = Io.ParseMove(board, lineIn.Substring(stringIndex - 5, 4).ToCharArray()); // not a promotion move.
                    }
                    else if (stringIndex == lineIn.Length + 1)                                          // if at last move
                    {
                        move = Io.ParseMove(board,
                                            lineIn.Substring(stringIndex - 5, 4).ToCharArray());
                    }
                    else if (stringIndex == lineIn.Length)     // promotion move at end of line
                    {
                        move = Io.ParseMove(board,
                                            lineIn.Substring(stringIndex - 5, 5).ToCharArray());
                    }
                    else if (lineIn.Length >= stringIndex && lineIn[stringIndex - 1] != ' ')
                    {
                        move = Io.ParseMove(board,
                                            lineIn.Substring(stringIndex - 5, 5).ToCharArray());
                        stringIndex++;
                    }

                    if (move == Variables.NO_MOVE)
                    {
                        break;
                    }

                    MakeMove.Make_Move(board, move);
                    board.Ply = 0;
                }
            }

            BoardOperations.PrintBoard(board);
        }
Example #24
0
        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            // say what about stopping spamming of key presses?
            // maybe we should throttle that..

            if (mode == DisplayMode.Play)
            {
                Direction directionToMove = Direction.Omit;
                bool      makeMove        = true;

                // shouldn't we send off to an algorithym about e.g. a move?
                // also is keys bindable?

                switch (e.Key)
                {
                case Key.Left:
                    // left arrow
                    directionToMove = Direction.Left;
                    break;

                case Key.Right:
                    // right arrow
                    directionToMove = Direction.Right;
                    break;

                case Key.Up:
                    // up arrow
                    directionToMove = Direction.Up;
                    break;

                case Key.Down:
                    // down arrow
                    directionToMove = Direction.Down;
                    break;

                case Key.Space:
                    // how about skipping a turn?
                    //directionToMove = Direction.Omit; // waste of code as its already default
                    break;

                default:
                    // ignore this case (could be anything)
                    makeMove = false;
                    break;
                }

                // so.. now lets go change the data models with the new moves.
                // that we may or may not be able to make. We'd know if we checked the return value.
                if (makeMove)
                {
                    if (MakeMove.TheseusTurn(ref board, ref entities, directionToMove))
                    {
                        MoveTaken();
                        // TODO redraw
                        InvalidateVisual();
                    }
                }

                if (entities[EntityType.Theseus].ToString() == entities[EntityType.Minotaur].ToString())
                {
                    EntityTouched();
                }
                else
                {
                    foreach (Cell cell in board.cells)
                    {
                        if (cell.x == entities[EntityType.Theseus].X && cell.y == entities[EntityType.Theseus].Y && cell.isExit)
                        {
                            TheseusExited();
                            break;
                        }
                    }
                }
            }
            else if (mode == DisplayMode.Design)
            {
                // explicitly saying this instead of else'ing. It _should_ be optimized out.
                // good practice.

                // anything specific required for design key wise?
            }
            base.OnPreviewKeyDown(e);
        }
Example #25
0
        /// <summary>
        /// Search all capture positions, to help avoid the Horizon effect.
        /// </summary>
        private int Quiescence(int alpha, int beta, ref S_SearchInfo info)
        {
            Debug.Assert(BoardOperations.CheckBoard(board));

            if ((info.Nodes & 2047) == 0)
            {
                CheckUp(ref info);
            }

            info.Nodes++;

            // If position is a draw.
            if ((IsRepetition() || board.FiftyMoves >= 100) && board.Ply != 0)
            {
                return(0);
            }

            int score = Evaluate.Position(board); // Stand_pat.

            if (board.Ply > Variables.MAX_DEPTH - 1)
            {
                return(score);
            }

            if (score >= beta)
            {
                return(beta);
            }

            if (score > alpha)
            {
                alpha = score;
            }


            MoveList list = new MoveList();

            MoveGen.GenerateAllMoves(board, list, true); // Only capture moves

            int oldAlpha = alpha;

            score = -infinite;
            int legal    = 0; // Will increment when we find a legal move.
            int bestMove = Variables.NO_MOVE;
            int PvMove   = PvTable.Probe(board);

            for (int i = 0; i < list.Count; ++i)
            {
                PickNextMove(i, list);

                var move = list.Moves[i].Move;

                if (!MakeMove.Make_Move(board, move))
                {
                    continue;
                }

                legal++;
                score = -Quiescence(-beta, -alpha, ref info);
                MakeMove.TakeMove(board); // Take back the made move.

                if (info.Stopped)
                {
                    return(0);
                }

                // We have a new alpha or beta cutoff.
                if (score > alpha)
                {
                    bool isCaptureMove = (move & MoveOperations.MoveFlagCapture) != 0;
                    // beta cutoff?
                    if (score >= beta)
                    {
                        if (legal == 1)
                        {
                            info.Fhf++; // We searched the best move first.
                        }

                        info.Fh++;
                        return(beta);
                    }

                    // Alpha cutoff
                    alpha    = score;
                    bestMove = move;
                }
            }

            if (alpha != oldAlpha)
            {
                PvTable.StoreMove(board, bestMove);
            }

            return(alpha);
        }
Example #26
0
        public int AlphaBeta(int alpha, int beta, int depth, ref S_SearchInfo info, bool DoNull)
        {
            Debug.Assert(BoardOperations.CheckBoard(board));

            if (depth == 0)
            {
                return(Quiescence(alpha, beta, ref info));
            }

            if ((info.Nodes & 2047) == 0)
            {
                CheckUp(ref info);
            }

            info.Nodes++;

            // If position is a draw.
            if ((IsRepetition() || board.FiftyMoves >= 100) && board.Ply != 0)
            {
                return(0);
            }

            if (board.Ply > Variables.MAX_DEPTH - 1)
            {
                return(Evaluate.Position(board));
            }

            bool kingInCheck = Attack.IsSqAttacked(board.KingSq[board.Side], board.Side ^ 1, board);

            // If king is in check, search deeper to get out of check.
            if (kingInCheck)
            {
                depth++;
                // The two following lines are possibly ERROR.
                long timeInc = (info.StopTime - info.StartTime) * (1 / 2);
                info.StopTime += timeInc;
            }

            MoveList list = new MoveList();

            MoveGen.GenerateAllMoves(board, list, false);
            int oldAlpha = alpha;
            int score    = -infinite;
            int legal    = 0; // Will increment when we find a legal move.
            int bestMove = Variables.NO_MOVE;
            int PvMove   = PvTable.Probe(board);

            // Prioritize Principle Variation move if it's found.
            if (PvMove != Variables.NO_MOVE)
            {
                for (int i = 0; i < list.Count; ++i)
                {
                    var move = list.Moves[i].Move;
                    if (move == PvMove)
                    {
                        list.Moves[i].Score = 2000000;
                        break;
                    }
                }
            }

            for (int i = 0; i < list.Count; ++i)
            {
                PickNextMove(i, list);

                var move = list.Moves[i].Move;
                if (!MakeMove.Make_Move(board, move))
                {
                    continue;
                }

                legal++;
                score = -AlphaBeta(-beta, -alpha, depth - 1, ref info, true);
                MakeMove.TakeMove(board); // Take back the made move.

                if (info.Stopped)
                {
                    return(0); // Back up to the root if times up.
                }

                // We have a new alpha or beta cutoff.
                if (score > alpha)
                {
                    bool isCaptureMove = (move & MoveOperations.MoveFlagCapture) != 0;
                    // beta cutoff?
                    if (score >= beta)
                    {
                        if (legal == 1)
                        {
                            info.Fhf++; // We searched the best move first.
                        }

                        info.Fh++;

                        // If beta cutoff, but no capture move.
                        if (!isCaptureMove)
                        {
                            board.SearchKillers[1, board.Ply] = board.SearchKillers[0, board.Ply];
                            board.SearchKillers[0, board.Ply] = move;
                        }
                        return(beta);
                    }

                    // Alpha cutoff
                    alpha    = score;
                    bestMove = move;

                    if (!isCaptureMove)
                    {
                        int from = MoveOperations.FromSq(move);
                        int to   = MoveOperations.ToSq(move);
                        board.SearchHistory[board[from], to] += depth; // Prioritizes move near the root of the tree.
                    }
                }
            }

            // If we haven't had any legal moves.
            if (legal == 0)
            {
                // If in check with no legal moves checkmate.
                if (kingInCheck)
                {
                    return(-mate + board.Ply); // Return the amount of moves it takes to mate.
                    // Returning in this way, allows the method to "prefer" the fastest checkmate combination.
                }
                else
                {
                    return(0); // Stalemate.
                }
            }

            if (alpha != oldAlpha)
            {
                PvTable.StoreMove(board, bestMove);
            }

            return(alpha);
        }