Example #1
0
        private Move GetHumanMove(int squareIndex)
        {
            List <Move> availableMoves = MoveGenerator.GetAvailableMoves(this.chessboard);

            if (availableMoves.Count == 0)
            {
                return(new Move());
            }

            Piece movingPiece = this.chessboard.Board[fromSquare].OccupiedBy;

            this.toSquare = squareIndex;
            bool isKing               = (movingPiece.Type == PieceType.King);
            bool isCastleAttempt      = isKing ? (Math.Abs(this.fromSquare - this.toSquare) > 1) : false;
            bool canCastle            = availableMoves.Any(m => m.Direction == Direction.Castle);
            bool isValidCastleAttempt = (isKing && isCastleAttempt && canCastle) ?
                                        availableMoves.Any(m => m.KingToSquare == this.toSquare) : false;
            bool isValidNonCastleMove = isValidCastleAttempt ? false :
                                        availableMoves.Any(m => m.FromSquare == this.fromSquare && m.ToSquare == this.toSquare);

            if (isValidNonCastleMove)
            {
                return(availableMoves.FirstOrDefault(m => m.FromSquare == this.fromSquare && m.ToSquare == this.toSquare));
            }
            else if (isValidCastleAttempt)
            {
                return(availableMoves.FirstOrDefault(m => m.KingFromSquare == this.fromSquare && m.KingToSquare == this.toSquare));
            }

            return(new Move());
        }
Example #2
0
        public void Chessboard_ShouldCorrectlyIdentifyWhenKingInCheck()
        {
            Chessboard position = Utils.LoadPositionFromFenString("3k4/4q3/8/2Q1r3/2PN1P2/3p1K2/8/8 b - - 38 72");

            position.MakeMove(new Move(12, 9, Direction.Horizontal));

            List <Move> availableMoves = MoveGenerator.GetAvailableMoves(position);

            Assert.AreEqual(true, position.WhiteInCheck);
            Assert.AreEqual(false, position.BlackInCheck);
        }
Example #3
0
        public void Chessboard_ShouldCorrectlyIdentifyWhenKingInCheckByKnight()
        {
            Chessboard position = Utils.LoadPositionFromFenString("3k4/5q1n/P7/2Q1r3/2PN1P2/3p1K2/8/8 b - - 15 58");

            position.MakeMove(new Move(15, 30, Direction.L));

            List <Move> availableMoves = MoveGenerator.GetAvailableMoves(position);

            Assert.AreEqual(true, position.WhiteInCheck);
            Assert.AreEqual(false, position.BlackInCheck);
        }
Example #4
0
        private bool IsGameOver()
        {
            List <Move> availableMoves = MoveGenerator.GetAvailableMoves(this.chessboard);

            if (availableMoves.Count == 0)
            {
                if (this.chessboard.KingInCheck)
                {
                    string victor = this.chessboard.OppositeColor == Engine.Defaults.Color.White ? "White" : "Black";

                    MessageBox.Show(victor + " wins.");
                }
                else
                {
                    MessageBox.Show("Game drawn.");
                }

                return(true);
            }

            return(false);
        }
Example #5
0
        private static int DoAlphaBetaPruning(int depth, int alpha, int beta)
        {
            VisitedNodes++;

            List <Move> availableMoves = MoveGenerator.GetAvailableMoves(position);

            position.PieceActivity = availableMoves.Count;
            int gameStateScore = GetGameStateScore(position, availableMoves.Count, depth);

            if (gameStateScore != 9999)
            {
                return(gameStateScore);
            }

            MoveSorter.SortMoves(position, availableMoves, killerMoves, depth);

            for (int moveIndex = 0; moveIndex < availableMoves.Count; moveIndex++)
            {
                Move currentMove = availableMoves[moveIndex];

                position.MakeMove(currentMove);

                long zobristKey = ZobristHasher.GetZobristHash(position);

                if (!position.GameHistory.ContainsKey(zobristKey))
                {
                    position.GameHistory.Add(zobristKey, 1);
                }
                else
                {
                    position.GameHistory[zobristKey]++;
                }

                int score =
                    (position.TranspositionTable.ContainsKey(zobristKey) &&
                     position.TranspositionTable[zobristKey].Depth >= depth) ?
                    position.TranspositionTable[zobristKey].Score :
                    DoAlphaBetaPruning(depth + 1, alpha, beta);

                position.UndoMove(currentMove);
                position.GameHistory.Remove(zobristKey);

                if (position.SideToMove == maximizingSide)
                {
                    if (score >= beta)
                    {
                        TryAddKillerMove(currentMove, depth);

                        return(beta);
                    }

                    if (score > alpha)
                    {
                        alpha = score;

                        if (depth == 0)
                        {
                            position.MaximizingSideBestMove = currentMove;
                        }

                        UpdatePrincipalVariation(depth, currentMove);
                        TryAddTableEntry(zobristKey, score, depth, currentMove);
                    }
                }
                else
                {
                    if (score <= alpha)
                    {
                        return(alpha);
                    }

                    if (score <= beta)
                    {
                        beta = score;

                        UpdatePrincipalVariation(depth, currentMove);
                    }
                }
            }

            return((position.SideToMove == maximizingSide) ? alpha : beta);
        }