Пример #1
0
        public AIMove GetAIMove(ChessEngine.Engine.Engine engine)
        {
            PieceList.Clear();

            Squares   = engine.ChessBoard.Squares;
            WhoseTurn = engine.WhoseMove;

            //Find all pieces that can be moved on this turn
            for (byte i = 0; i < Squares.Length; i++)
            {
                if (Squares[i].Piece != null && Squares[i].Piece.PieceColor == WhoseTurn && Squares[i].Piece.ValidMoves.Count > 0)
                {
                    PieceList.Add(i);
                }
            }

            //If piecelist is empty, no moves can be made
            if (PieceList.Count == 0)
            {
                return(null);
            }

            //Randomly select Piece
            byte Piece = PieceList[RandomGenerator.Next(0, PieceList.Count)];

            //Calculate piece position
            byte SquareCount = 7;
            byte Row         = 0;

            while (SquareCount < 64)
            {
                if (Piece <= SquareCount)
                {
                    break;
                }

                Row++;
                SquareCount += 8;
            }

            byte Column = (byte)(Piece - Row * 8);

            AIMove.SourceRow    = Row;
            AIMove.SourceColumn = Column;

            //Randomly select a move
            LegalMoves = engine.GetValidMoves(Column, Row);

            int MoveIndex = RandomGenerator.Next(0, LegalMoves.Length);

            AIMove.DestinationRow    = LegalMoves[MoveIndex][1];
            AIMove.DestinationColumn = LegalMoves[MoveIndex][0];

            Console.WriteLine("(" + AIMove.SourceColumn + ", " + AIMove.SourceRow + ")" + "   (" + AIMove.DestinationColumn + ", " + AIMove.DestinationRow + ")" + "\n---------------");

            return(AIMove);
        }
Пример #2
0
        private ChessEngine.Engine.Engine ReturnNewState(ChessEngine.Engine.Engine engine, byte piece, byte move)
        {
            ChessEngine.Engine.Engine newState = new Engine.Engine();
            newState.ChessBoard = new Board(engine.ChessBoard);
            byte[] sourcePos      = engine.CalculateColumnAndRow((byte)(piece));
            byte[] destinationPos = engine.CalculateColumnAndRow(move);

            if (!newState.MovePiece(sourcePos[0], sourcePos[1], destinationPos[0], destinationPos[1]))
            {
                return(null);
            }

            return(newState);
        }
Пример #3
0
        private DynamicArray ReturnAllMovablePieces(ChessEngine.Engine.Engine engine)
        {
            DynamicArray pieceList = new DynamicArray();

            Square[] squares = engine.ChessBoard.Squares;

            //Find all pieces that can be moved on this turn
            for (byte i = 0; i < squares.Length; i++)
            {
                if (squares[i].Piece != null && squares[i].Piece.PieceColor == engine.WhoseMove && squares[i].Piece.ValidMoves.Count > 0)
                {
                    pieceList.Add(i);
                }
            }

            return(pieceList);
        }
Пример #4
0
        private void debugWrite(ChessEngine.Engine.Engine engine)
        {
            string line = "";

            for (int i = 0; i < engine.ChessBoard.Squares.Length; i++)
            {
                if (i == 59)
                {
                }

                Square square = engine.ChessBoard.Squares[i];

                if (square.Piece != null)
                {
                    if (square.Piece.PieceType == ChessPieceType.Knight)
                    {
                        line += "H";
                    }
                    else
                    {
                        line += square.Piece.PieceType.ToString().Substring(0, 1);
                    }
                }
                else
                {
                    line += ".";
                }

                if ((i + 1) % 8 == 0)
                {
                    Debug.WriteLine(line);
                    line = "";
                }
            }
            Debug.WriteLine("\n\n\n");
        }
Пример #5
0
        public void NewGame()
        {
            //ChessEngine
            engine = new Engine();

            currentSource = new Selection();
            currentDestination = new Selection();

            if (engine.HumanPlayer != engine.WhoseMove)
            {
                EngineMove();
            }

            Refresh();
        }
Пример #6
0
        private double MaxValue(int depth, double alpha, double beta, ChessEngine.Engine.Engine engine)
        {
            //Check if stalemate
            if (engine.IsStalemateBy50MoveRule())
            {
                return(0);
            }

            //Check if checkmate
            if (engine.IsCheckMate())
            {
                return(Double.MinValue);
            }

            //A leaf node, return value of board state
            if ((depth == 0 && maxDepth != 0) || (maxTime.Seconds != 0 && timer.Elapsed > maxTime))
            {
                if (maxTime.Seconds != 0 && timer.Elapsed > maxTime)
                {
                    overTime = true;
                }

                double boardValue = evaluator.ValuateBoard(engine.ChessBoard.Squares);
                return(boardValue);
            }

            double value = Double.MinValue;

            //Find all pieces that can be moved on this turn
            DynamicArray pieceList = ReturnAllMovablePieces(engine);

            //Go through all possible moves
            foreach (byte piece in pieceList)
            {
                foreach (byte move in engine.ChessBoard.Squares[piece].Piece.ValidMoves)
                {
                    //Create the next board stage
                    ChessEngine.Engine.Engine newState = ReturnNewState(engine, piece, move);

                    //Invalid move, continue to next move
                    if (newState == null)
                    {
                        continue;
                    }

                    //Pass parameters to the next node
                    value = MinValue(depth - 1, alpha, beta, newState);

                    //Check if alpha can be given bigger value
                    if (value > alpha)
                    {
                        alpha = value;

                        if (depth == maxDepth)
                        {
                            //Back at the root node with a better move than the previous best
                            byte[] source      = engine.CalculateColumnAndRow(piece);
                            byte[] destination = engine.CalculateColumnAndRow(move);
                            bestMove.SourceColumn      = source[0];
                            bestMove.SourceRow         = source[1];
                            bestMove.DestinationColumn = destination[0];
                            bestMove.DestinationRow    = destination[1];
                        }
                    }

                    //If alpha is bigger than beta, don't investigate branch further
                    if (alpha > beta)
                    {
                        return(alpha);
                    }

                    if (overTime)
                    {
                        break;
                    }
                }

                if (overTime)
                {
                    break;
                }
            }
            return(alpha);
        }
Пример #7
0
        private double MinValue(int depth, double alpha, double beta, ChessEngine.Engine.Engine engine)
        {
            //Check if stalemate
            if (engine.IsStalemateBy50MoveRule())
            {
                return(0);
            }

            //Check if checkmate
            if (engine.IsCheckMate())
            {
                return(Double.MaxValue);
            }

            //A leaf node, return value of board state
            if ((depth == 0 && maxDepth != 0) || (maxTime.Seconds != 0) && timer.Elapsed > maxTime)
            {
                if (maxTime.Seconds != 0 && timer.Elapsed > maxTime)
                {
                    overTime = true;
                }

                double boardValue = evaluator.ValuateBoard(engine.ChessBoard.Squares);
                return(boardValue);
            }

            double value = Double.MaxValue;

            //Find all pieces that can be moved on this turn
            DynamicArray pieceList = ReturnAllMovablePieces(engine);

            //Go through all possible moves
            foreach (byte piece in pieceList)
            {
                foreach (byte move in engine.ChessBoard.Squares[piece].Piece.ValidMoves)
                {
                    //Create the next board stage and pass it to the next node
                    ChessEngine.Engine.Engine newState = ReturnNewState(engine, piece, move);

                    //Invalid move, continue to next move
                    if (newState == null)
                    {
                        continue;
                    }

                    value = MaxValue(depth - 1, alpha, beta, newState);

                    //Check if beta can be given smaller value
                    if (value < beta)
                    {
                        beta = value;
                    }

                    //If beta is smaller than alpha, don't investigate branch further
                    if (beta < alpha)
                    {
                        return(beta);
                    }

                    if (overTime)
                    {
                        break;
                    }
                }

                if (overTime)
                {
                    break;
                }
            }
            return(beta);
        }