예제 #1
0
        private List <float> GetHardWeights(AIBoard board)
        {
            float p1spWeight = 1f;
            float p2spWeight = 1f;

            //Variables used in weight calculations.
            int playerOneSP            = BoardAnalysis.FindShortestPath(board, true);
            int playerTwoSP            = BoardAnalysis.FindShortestPath(board, true);
            int playerTwoNumWalls      = CurrentBoard.GetPlayerTwoNumWalls();
            int distanceBetweenPlayers = BoardAnalysis.FindDistanceBetween(CurrentBoard, CurrentBoard.GetPlayerOnePos(), CurrentBoard.GetPlayerTwoPos());

            if (playerOneSP - playerTwoSP > 2)
            {
                p1spWeight = 5;
            }
            else if (playerOneSP < 5)
            {
                p1spWeight = 2;
            }


            List <float> w = new List <float> {
                p1spWeight, p2spWeight
            };

            return(w);
        }
예제 #2
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);
        }