Ejemplo n.º 1
0
        //Initiates a minimax search 2 layers deep.
        public string GetHardMove(string playerMove)
        {
            timer.Start();
            TreeNode.weights    = GetHardWeights(CurrentBoard);
            TreeNode.wallValues = new List <float> {
                2f, 2f, 2f, 2f, 1f, 1f, 1f, 1f, 1f, 0f
            };

            //AI starts on e9 and makes the first move of the game.
            if (playerMove == "gamestart")
            {
                CurrentBoard.PlayerTwoGoesFirst();
            }
            //AI starts on e1 and makes the first move of the game.
            else if (playerMove == "")
            {
            }
            //Updates the board with the player's move.
            else
            {
                CurrentBoard.MakeMove(playerMove);
            }

            TreeNode rootNode      = new TreeNode(CurrentBoard);
            float    rootNodeValue = rootNode.CalcValue();

            List <TreeNode> possibleMoves = rootNode.GetChildren();

            //Create dictionary of all useful values of first two levels of analysis.
            Dictionary <string, MoveInfo> moveValues = new Dictionary <string, MoveInfo>();

            foreach (TreeNode moveNode in possibleMoves)
            {
                if (timer.ElapsedMilliseconds > 5980)
                {
                    break;
                }
                MoveInfo thisMovesInfo = new MoveInfo();
                foreach (TreeNode childNode in moveNode.GetChildren())
                {
                    thisMovesInfo.UpdateValues(childNode.CalcValue(), moveNode.CalcValue());
                }
                moveValues.Add(moveNode.GetMoveMade(), thisMovesInfo);
            }

            string selectedMove = "none1";

            //Minimax of the first two levels.
            List <string> movesSelected = new List <string>();
            float         value         = float.NegativeInfinity;

            foreach (KeyValuePair <string, MoveInfo> pair in moveValues)
            {
                if (pair.Value.singleLevelValue > 10000)
                {
                    value = pair.Value.singleLevelValue;
                    movesSelected.Clear();
                    movesSelected.Add(pair.Key);
                    break;
                }
                if (pair.Value.min > value)
                {
                    value = pair.Value.min;
                    movesSelected.Clear();
                    movesSelected.Add(pair.Key);
                }
                else if (pair.Value.min == value)
                {
                    movesSelected.Add(pair.Key);
                }
            }

            selectedMove = movesSelected[new System.Random().Next(0, movesSelected.Count)];

            //If selected move isn't a wall then use the pawn moves single level evaluation.
            //And if jump next move isn't a possibility.
            bool isPawnMove   = !(selectedMove.EndsWith("h") || selectedMove.EndsWith("v"));
            bool jumpPossible = BoardAnalysis.FindDistanceBetween(CurrentBoard, CurrentBoard.GetPlayerOnePos(), CurrentBoard.GetPlayerTwoPos()) == 2;

            if (isPawnMove && !jumpPossible)
            {
                List <string> pawnMoves = CurrentBoard.GetPawnMoves();
                value        = float.NegativeInfinity;
                selectedMove = "none2";
                foreach (string pm in pawnMoves)
                {
                    float tempVal = moveValues[pm].singleLevelValue;
                    if (tempVal > value)
                    {
                        selectedMove = pm;
                        value        = tempVal;
                    }
                }
            }

            float testVal = value - rootNodeValue;

            if (value - rootNodeValue < 3)
            {
                float currentPotential = float.NegativeInfinity;
                float currentRisk      = float.NegativeInfinity;
                movesSelected.Clear();
                foreach (KeyValuePair <string, MoveInfo> pair in moveValues)
                {
                    if (pair.Key.EndsWith("h") || pair.Key.EndsWith("v"))
                    {
                        float optimisticPotential  = pair.Value.max - rootNodeValue;
                        float pessemisticPotential = pair.Value.min - rootNodeValue;
                        float risk = optimisticPotential - pessemisticPotential;
                        if (optimisticPotential > 2)
                        {
                            if (optimisticPotential > currentPotential)
                            {
                                movesSelected.Clear();
                                movesSelected.Add(pair.Key);
                                currentPotential = optimisticPotential;
                                currentRisk      = risk;
                            }
                            else if (optimisticPotential == currentPotential)
                            {
                                if (risk < currentRisk)
                                {
                                    movesSelected.Clear();
                                    movesSelected.Add(pair.Key);
                                    currentPotential = optimisticPotential;
                                    currentRisk      = risk;
                                }
                                else if (risk == currentRisk)
                                {
                                    movesSelected.Add(pair.Key);
                                }
                            }
                        }
                    }
                }
                if (movesSelected.Count > 0)
                {
                    selectedMove = movesSelected[new System.Random().Next(0, movesSelected.Count)];
                }
            }

            timer.Reset();
            CurrentBoard.MakeMove(selectedMove);
            return(selectedMove);
        }
Ejemplo n.º 2
0
        //Initiates a minimax search 2 layers deep.
        public string GetHardMove(string playerMove)
        {
            TreeNode.weights = new List <float> {
                1f, 1f, 1f, 0f
            };

            //AI starts on e9 and makes the first move of the game.
            if (playerMove == "gamestart")
            {
                CurrentBoard.PlayerTwoGoesFirst();
            }
            //AI starts on e1 and makes the first move of the game.
            else if (playerMove == "")
            {
            }
            //Updates the board with the player's move.
            else
            {
                CurrentBoard.MakeMove(playerMove);
            }

            TreeNode rootNode      = new TreeNode(CurrentBoard);
            float    rootNodeValue = rootNode.CalcValue();

            List <TreeNode> possibleMoves = rootNode.GetChildren();

            Dictionary <string, MoveInfo> moveValues = new Dictionary <string, MoveInfo>();

            foreach (TreeNode moveNode in possibleMoves)
            {
                MoveInfo thisMovesInfo = new MoveInfo();
                foreach (TreeNode childNode in moveNode.GetChildren())
                {
                    thisMovesInfo.UpdateValues(childNode.CalcValue(), moveNode.CalcValue());
                }
                moveValues.Add(moveNode.GetMoveMade(), thisMovesInfo);
            }

            //Analyzing the results of tree evaluation starts here.
            bool   moveFound         = false;
            string moveSelected      = "none";
            float  moveSelectedValue = float.NegativeInfinity;

            //Check for level 2 single wall placement.
            float requiredChangedInEval = 5;

            foreach (KeyValuePair <string, MoveInfo> move in moveValues)
            {
                if (move.Value.min > requiredChangedInEval)
                {
                    moveFound = true;
                    if (moveSelectedValue < move.Value.min)
                    {
                        moveSelected = move.Key;
                    }
                }
            }
            //Check for level 2 double wall placement.
            if (!moveFound)
            {
            }
            //Check for pawn moves.
            if (!moveFound)
            {
                List <string> possiblePawnMoves = CurrentBoard.GetPawnMoves();
                float         currentMax        = float.NegativeInfinity;
                foreach (string move in possiblePawnMoves)
                {
                    TreeNode n  = new TreeNode(CurrentBoard, move);
                    MoveInfo mi = moveValues[move];
                    if (!(mi.singleLevelValue - mi.min == 2))
                    {
                        if (mi.min > currentMax)
                        {
                            currentMax   = mi.min;
                            moveSelected = move;
                            moveFound    = true;
                        }
                    }
                }
            }

            if (!moveFound)
            {
                float         max      = float.NegativeInfinity;
                List <string> maxMoves = new List <string>();
                foreach (KeyValuePair <string, MoveInfo> move in moveValues)
                {
                    if (move.Value.min > max)
                    {
                        max = move.Value.min;
                        maxMoves.Clear();
                        maxMoves.Add(move.Key);
                    }
                    else if (move.Value.min == max)
                    {
                        maxMoves.Add(move.Key);
                    }
                }

                moveSelected = maxMoves[new Random().Next(0, maxMoves.Count)];
            }

            CurrentBoard.MakeMove(moveSelected);
            return(moveSelected);
        }