Example #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);
        }
Example #2
0
 public WallDiffNode(AIBoard copy)
 {
     Board    = new AIBoard(copy);
     Depth    = 0;
     MoveMade = "rootnode";
     Diff     = BoardAnalysis.FindShortestPath(Board, true) - BoardAnalysis.FindShortestPath(Board, false);
 }
Example #3
0
 public override void StartGame(Dictionary <PlayerInfo, int> allPlayersAndScores)
 {
     _turnAdviser = new TurnAdviser {
         MyId = Info.ID
     };
     _boardAnalysis = new BoardAnalysis {
         MyId = Info.ID
     };
 }
Example #4
0
        //This returns all walls adjacent to the wall move made in
        public List <WallDiffNode> GetChildren()
        {
            List <WallDiffNode> children      = new List <WallDiffNode>();
            List <string>       adjacentWalls = DictionaryLookup.PerformWallsOfInterestLookup(MoveMade);

            foreach (string wall in adjacentWalls)
            {
                AIBoard tempBoard = new AIBoard(Board);
                tempBoard.MakeMove(wall);
                if (BoardAnalysis.CheckPathExists(tempBoard, true) && BoardAnalysis.CheckPathExists(tempBoard, false))
                {
                    children.Add(new WallDiffNode(this, wall));
                }
            }
            return(children);
        }
Example #5
0
        //Constructs a list of treenodes that result from every move made that is possible.
        //Pruning function (SetNodesOfInterest) will cut of many nodes that are not of interest.
        public List <TreeNode> GetChildren()
        {
            List <TreeNode> children = new List <TreeNode>();

            foreach (string move in Board.GetPawnMoves())
            {
                //This checks to make sure walls are valid
                AIBoard tempBoard = new AIBoard(Board);
                tempBoard.MakeMove(move);
                children.Add(new TreeNode(tempBoard, move));
            }

            //This gets only valid walls but is done here so that it will only check walls of interest.
            //This avoids checking if a ton of walls are valid that we don't care about.
            //This is why we do not just call GetWallMoves()
            if ((Board.GetIsPlayerOneTurn() && Board.GetPlayerOneNumWalls() == 0) ||
                (!Board.GetIsPlayerOneTurn() && Board.GetPlayerTwoNumWalls() == 0))
            {
            }
            else
            {
                HashSet <string> wallMoves = Board.GetAllValidWalls();
                SetNodesOfInterest(ref wallMoves);
                foreach (string wall in wallMoves)
                {
                    //This checks to make sure walls are valid
                    AIBoard tempBoard = new AIBoard(Board);
                    tempBoard.MakeMove(wall);
                    if (BoardAnalysis.CheckPathExists(tempBoard, true) && BoardAnalysis.CheckPathExists(tempBoard, false))
                    {
                        children.Add(new TreeNode(tempBoard, wall));
                    }
                }
            }

            //end of wall selection

            return(children);
        }
Example #6
0
        public List <string> GetWallMoves()
        {
            List <string> possibleMoves = new List <string>();

            if ((IsPlayerOneTurn && PlayerOneNumWalls == 0) || (!IsPlayerOneTurn && PlayerTwoNumWalls == 0))
            {
            }
            else
            {
                foreach (string wall in ValidWallPlacements)
                {
                    //This checks to make sure walls are valid
                    AIBoard tempBoard = new AIBoard(this);
                    tempBoard.MakeMove(wall);

                    if (BoardAnalysis.CheckPathExists(tempBoard, true) && BoardAnalysis.CheckPathExists(tempBoard, false))
                    {
                        possibleMoves.Add(wall);
                    }
                }
            }
            return(possibleMoves);
        }
Example #7
0
        //Static evaluation function of the gameboard.
        private void EvaluateNode()
        {
            value = 0;

            //If a player won, assigns node proper value and then returns.
            if (EvaluateWinPossibility(ref value))
            {
            }
            //Calculates factors of interest and calculates the value.
            else
            {
                int P1SP       = BoardAnalysis.FindShortestPath(Board, true);
                int P2SP       = BoardAnalysis.FindShortestPath(Board, false);
                int P1NumWalls = Board.GetPlayerOneNumWalls();
                int P2NumWalls = Board.GetPlayerTwoNumWalls();
                for (int i = 0; i < P2NumWalls; ++i)
                {
                    value += wallValues[i];
                }

                value += (weights[0] * P1SP - weights[1] * P2SP);
            }
        }
Example #8
0
 //If it is positive P2SP's path got that much shorter.
 public int CalcChangeInDiff()
 {
     Diff = BoardAnalysis.FindShortestPath(Board, true) - BoardAnalysis.FindShortestPath(Board, false);
     return(PreviousDiff - Diff);
 }
Example #9
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);
        }
Example #10
0
        /**
         * Returns a list of all possible pawn moves for whichever players turn it is.
         **/
        public List <string> GetPawnMoves()
        {
            List <string> possibleMoves;

            if (IsPlayerOneTurn)
            {
                possibleMoves = GetAdjacentMoves(PlayerOneLocation);
                foreach (string move in possibleMoves.ToArray())
                {
                    if (PlayerTwoLocation == move)
                    {
                        possibleMoves.Remove(move);

                        string        jumpDirection      = BoardAnalysis.GetMoveDirection(PlayerOneLocation, PlayerTwoLocation);
                        List <string> possibleJumps      = GetAdjacentMoves(PlayerTwoLocation);
                        List <string> perpendicularJumps = new List <string>();
                        string        straightJump       = "n";
                        possibleJumps.Remove(PlayerOneLocation);
                        foreach (string jump in possibleJumps)
                        {
                            string possibleDirection = BoardAnalysis.GetMoveDirection(PlayerTwoLocation, jump);
                            if (possibleDirection == jumpDirection)
                            {
                                straightJump = jump;
                            }
                            else
                            {
                                perpendicularJumps.Add(jump);
                            }
                        }
                        if (straightJump != "n")
                        {
                            possibleMoves.Add(straightJump);
                        }
                        else
                        {
                            possibleMoves.AddRange(perpendicularJumps);
                        }
                        break;
                    }
                }
            }
            else
            {
                possibleMoves = GetAdjacentMoves(PlayerTwoLocation);
                foreach (string move in possibleMoves.ToArray())
                {
                    if (PlayerOneLocation == move)
                    {
                        possibleMoves.Remove(move);

                        string        jumpDirection      = BoardAnalysis.GetMoveDirection(PlayerTwoLocation, PlayerOneLocation);
                        List <string> possibleJumps      = GetAdjacentMoves(PlayerOneLocation);
                        List <string> perpendicularJumps = new List <string>();
                        string        straightJump       = "n";
                        possibleJumps.Remove(PlayerTwoLocation);
                        foreach (string jump in possibleJumps)
                        {
                            string possibleDirection = BoardAnalysis.GetMoveDirection(PlayerOneLocation, jump);
                            if (possibleDirection == jumpDirection)
                            {
                                straightJump = jump;
                            }
                            else
                            {
                                perpendicularJumps.Add(jump);
                            }
                        }
                        if (straightJump != "n")
                        {
                            possibleMoves.Add(straightJump);
                        }
                        else
                        {
                            possibleMoves.AddRange(perpendicularJumps);
                        }
                        break;
                    }
                }
            }
            return(possibleMoves);
        }