예제 #1
0
        /// <summary>
        /// Alpha beta fail hard version
        /// </summary>
        /// <param name="arrState"></param>
        /// <param name="arrposition"></param>
        /// <param name="depth"></param>
        /// <param name="side"></param>
        /// <param name="alpha"></param>
        /// <param name="beta"></param>
        /// <returns></returns>
        public static int AlphaBeta(ChessState[,] arrState, Dictionary <string, int> arrposition, int depth, eChessSide side, int alpha, int beta)
        {
            int bestScore = EvaluateChessBoard(arrState, side);

            if (depth == 0)
            {
                return(bestScore);
            }
            if (bestScore < _lowestScore)
            {
                return(bestScore);
            }

            bestScore = alpha;
            ChessMove bestMove = null;

            //Find all possible moves of this side => sort this to make alpha beta be faster
            ArrayList arrCanMoves = new ArrayList();

            if (depth > 1)
            {
                arrCanMoves = SortChessMoves(arrState, FindAllPosibleMovesNotRule(arrState, side, _ownSide), side);
            }
            else
            {
                arrCanMoves = FindAllPosibleMovesNotRule(arrState, side, _ownSide);
            }

            //If no more moves
            if (arrCanMoves.Count == 0)
            {
                //opSide win
                if (Checked(arrState, _mySide, _ownSide) == true)
                {
                    if (side == _mySide)
                    {
                        return(_lowestScore);
                    }
                    else
                    {
                        return(-_lowestScore);
                    }
                }

                //mySide win
                if (Checked(arrState, _opSide, _ownSide) == true)
                {
                    if (side == _mySide)
                    {
                        return(-_lowestScore);
                    }
                    else
                    {
                        return(_lowestScore);
                    }
                }

                //Draw
                return(0);
            }

            while (arrCanMoves.Count > 0 && bestScore < beta)
            {
                //Pop a ChessMove
                ChessMove m = (ChessMove)arrCanMoves[arrCanMoves.Count - 1];
                arrCanMoves.RemoveAt(arrCanMoves.Count - 1);

                //Compute new State after move
                PredictMove(arrState, m);

                //Add this Position
                string newPosition = MakePosition(arrState);
                if (arrposition.ContainsKey(newPosition))
                {
                    arrposition[newPosition]++;
                }
                else
                {
                    arrposition.Add(newPosition, 1);
                }

                //Another side's move
                eChessSide newSide = eChessSide.Black;
                if (newSide == side)
                {
                    newSide = eChessSide.White;
                }

                //Next move genneration
                int value = 0;
                if (arrposition[newPosition] < 3)
                {
                    value = -AlphaBeta(arrState, arrposition, depth - 1, newSide, -beta, -alpha);
                }

                UnPredictMove(arrState, m);

                //Undo this Position
                if (arrposition[newPosition] > 1)
                {
                    arrposition[newPosition] -= 1;
                }
                else
                {
                    arrposition.Remove(newPosition);
                }


                //Update best
                if (value > bestScore)
                {
                    bestScore = value;
                    bestMove  = m;

                    if (depth == _maxDepth)
                    {
                        if (_myBestScore < bestScore)
                        {
                            _myBestScore = bestScore;
                            _myBestMove  = bestMove;
                        }
                    }

                    if (value > alpha)
                    {
                        alpha = value;
                    }
                    if (value >= beta)
                    {
                        bestScore = beta;
                        beta      = bestScore - 1;
                    }
                }
            }
            //_myBestMove = bestMove;
            return(bestScore);
        }
예제 #2
0
        /// <summary>
        /// Unpredict a move - return a ChessState[,]
        /// </summary>
        /// <param name="A"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        public static void UnPredictMove(ChessState[,] A, ChessMove m)
        {
            A[m.MoveFrom.X, m.MoveFrom.Y].Side  = A[m.MoveTo.X, m.MoveTo.Y].Side;
            A[m.MoveFrom.X, m.MoveFrom.Y].Type  = A[m.MoveTo.X, m.MoveTo.Y].Type;
            A[m.MoveFrom.X, m.MoveFrom.Y].Moves = m.FromMoves;
            A[m.MoveTo.X, m.MoveTo.Y].Type      = eChessPieceType.Null;

            if (m.ChessPieceEated != eChessPieceType.Null)
            {
                A[m.MoveEated.X, m.MoveEated.Y].Side = eChessSide.Black;
                if (A[m.MoveFrom.X, m.MoveFrom.Y].Side == eChessSide.Black)
                {
                    A[m.MoveEated.X, m.MoveEated.Y].Side = eChessSide.White;
                }
                A[m.MoveEated.X, m.MoveEated.Y].Type  = m.ChessPieceEated;
                A[m.MoveEated.X, m.MoveEated.Y].Moves = m.Moves;
            }

            if (m.HowMove == eMove.Castling)
            {
                if (m.MoveFrom.X == m.MoveTo.X)
                {
                    if (m.MoveFrom.Y < m.MoveTo.Y)
                    {
                        //King side castling
                        A[m.MoveFrom.X, 8].Side  = A[m.MoveTo.X, 6].Side;
                        A[m.MoveFrom.X, 8].Type  = A[m.MoveTo.X, 6].Type;
                        A[m.MoveFrom.X, 8].Moves = A[m.MoveTo.X, 6].Moves - 1;

                        A[m.MoveTo.X, 6].Type = eChessPieceType.Null;
                    }
                    else
                    {
                        //Queen side castling
                        A[m.MoveFrom.X, 1].Side  = A[m.MoveTo.X, 4].Side;
                        A[m.MoveFrom.X, 1].Type  = A[m.MoveTo.X, 4].Type;
                        A[m.MoveFrom.X, 1].Moves = A[m.MoveTo.X, 4].Moves - 1;

                        A[m.MoveTo.X, 4].Type = eChessPieceType.Null;
                    }
                }
                else
                {
                    //promotion side castling
                    if (m.MoveFrom.X == 1)
                    {
                        //Black
                        A[8, 5].Side  = A[2, 5].Side;
                        A[8, 5].Type  = A[2, 5].Type;
                        A[8, 5].Moves = A[2, 5].Moves - 1;
                        A[2, 5].Type  = eChessPieceType.Null;
                    }
                    else
                    {
                        //White
                        A[1, 5].Side  = A[7, 5].Side;
                        A[1, 5].Type  = A[7, 5].Type;
                        A[1, 5].Moves = A[7, 5].Moves - 1;
                        A[7, 5].Type  = eChessPieceType.Null;
                    }
                }
            }
            else if (m.HowMove == eMove.Promotion)
            {
                A[m.MoveFrom.X, m.MoveFrom.Y].Type = eChessPieceType.Pawn;
            }
        }