Esempio n. 1
0
        public double BuildABTree(StishMiniMaxNode CurrentNode, int DepthCount, double Alpha, double Beta, int colour)
        {
            if (CurrentNode == null || DepthCount == 0)
            {
                //returns if this is the root node or is a leaf node
                return(colour * CurrentNode.FindValue(CurrentNode, CurrentNode.NodeBoardState, CurrentNode.Allegiance));
            }

            double Value = double.MinValue;
            double ChildValue;

            ForeSight.Instance.GenerateChildren(CurrentNode);
            for (int index = 0; index < CurrentNode.CountChildren(); index++)
            {
                ChildValue = -1 * BuildABTree((StishMiniMaxNode)CurrentNode.GetChild(index), DepthCount - 1, -Beta, -Alpha, -colour);
                if (Value < ChildValue)
                {
                    Value = ChildValue;
                    CurrentNode.BestChild    = (StishMiniMaxNode)CurrentNode.GetChild(index);
                    CurrentNode.NegaMaxValue = Value;
                }
                Alpha = Math.Max(Alpha, Value);

                if (Alpha > Beta)
                {
                    //this return statement "prunes" the tree and prevents further growth on the tree in those bad areas
                    return(colour * CurrentNode.FindValue(CurrentNode, CurrentNode.NodeBoardState, CurrentNode.Allegiance));
                }
            }

            //if the node does not need to be pruned
            return(colour * CurrentNode.FindValue(CurrentNode, CurrentNode.NodeBoardState, CurrentNode.Allegiance));
        }
Esempio n. 2
0
        public double TraverseTree(StishMiniMaxNode CurrentNode, int DepthCount, int colour)
        {
            //Depth count is given as 0 when called at root

            if (CurrentNode == null || DepthCount == 0)
            {
                //the number 3 is a variable to be changed as sight increases
                return(colour * CurrentNode.FindValue(CurrentNode, CurrentNode.NodeBoardState, CurrentNode.Allegiance));
            }

            double Value = double.MinValue;
            double ChildValue;

            for (int index = 0; index < CurrentNode.CountChildren(); index++)
            {
                ChildValue = -TraverseTree((StishMiniMaxNode)CurrentNode.GetChild(index), DepthCount - 1, -colour);
                if (Value < ChildValue)
                {
                    Value = ChildValue;
                    CurrentNode.BestChild    = (StishMiniMaxNode)CurrentNode.GetChild(index);
                    CurrentNode.NegaMaxValue = Value;
                }
            }
            return(Value);
        }
Esempio n. 3
0
        //the foresight class helps us build new nodes by predicting all possible moves from a node
        //these functions will be called by the node objects in order to tell the nodes, how to configure their children

        public void UnitBasedMovement(StishMiniMaxNode Sibling, BoardState Now, List <Coordinate> Path, Player Side)
        {
            //this will check what is on the destination square and then use the game master function.
            //the game master currently only works with the StishBoard. if i make StishBoard a dervived class from the board state, i can generalize the game master functions and use them here
            Player     NewSide;
            BoardState UnitMovedChild = new BoardState(Now);

            if (Side.GetPlayerNum == "Player1")
            {
                NewSide = UnitMovedChild.Player1;
            }
            else
            {
                NewSide = UnitMovedChild.Player2;
            }

            for (int index = 0; index < Path.Count - 1; index++)
            {
                //from index to the one ahead of it therefore the function finishes one place short of the end
                GameMaster.Instance.Action(Path[index], Path[index + 1], NewSide, UnitMovedChild);
            }

            //Parent.Parent as "parent" is actually just an updated model of the "real" parent where no actions were taken
            StishMiniMaxNode UnitMoveNode = new StishMiniMaxNode(Sibling.Parent, Sibling.Allegiance, UnitMovedChild);

            PredctionCount();

            //changes to the boardstate are made here using the FindPath function and itterating through the list with the gamemaster functions
        }
Esempio n. 4
0
        //this may not need to be void however i dont yet know if or what the output will be (currently just counts)
        public void SweepSearch(StishMiniMaxNode Sibling, BoardState Now, Coordinate UnitPos, Player Side)
        {
            Coordinate Upper = new Coordinate();
            Coordinate Lower = new Coordinate();
            Coordinate Look  = new Coordinate();

            //upper refers to the upper left corner (lower coordinate values)
            //assigns full values to the bounds and then changes them if they are inappropriate
            Upper.X = UnitPos.X - StishBoard.Instance.GameMP;
            Upper.Y = UnitPos.Y - StishBoard.Instance.GameMP;
            Lower.X = UnitPos.X + StishBoard.Instance.GameMP;
            Lower.Y = UnitPos.Y + StishBoard.Instance.GameMP;

            //checks if the unit is losing movement positions because it is too close to the edge of the board
            if (UnitPos.X < StishBoard.Instance.GameMP)
            {
                Upper.X = 0;
            }
            if (UnitPos.X > Now.BoardSizeX - StishBoard.Instance.GameMP)
            {
                Lower.X = Now.BoardSizeX;
            }
            if (UnitPos.Y < StishBoard.Instance.GameMP)
            {
                Upper.Y = 0;
            }
            if (UnitPos.Y > Now.BoardSizeY - StishBoard.Instance.GameMP)
            {
                Lower.Y = Now.BoardSizeY;
            }

            for (uint y = Upper.Y; y <= Lower.Y; y++)
            {
                for (uint x = Upper.X; x <= Lower.X; x++)
                {
                    Look.X = x;
                    Look.Y = y;
                    //stishboard.instance is okay here as this variable is global and is not dependant on a particular state
                    if (UnitPos.Get2DDistance(Look) <= StishBoard.Instance.GameMP)
                    {
                        //general squares around unit within range
                        if ((Now.getSquare(Look) != null) && !((Now.getSquare(Look).Owner) == Side && ((Now.getSquare(Look).Dep.DepType == "Unit") || (Now.getSquare(Look).Dep.DepType == "Base"))))
                        {
                            //the unit can legally move to any of these positions however the events of this action are not distinguished
                            //obstructions are not accounted for
                            List <Coordinate> Path = FindPath(UnitPos, Look, Now);
                            if (Path != null)
                            {
                                UnitBasedMovement(Sibling, Now, Path, Side);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 5
0
 private void TestSquare(StishMiniMaxNode Sibling, BoardState Now, Player Side, Coordinate Invest, uint cost)
 {
     if ((Now.getSquare(Invest).Owner == Side) && (Now.getSquare(Invest).Dep.DepType == "Empty"))
     {
         //can buy possibly buy
         BuyPossibility(Sibling, Now, Side, Invest, cost);
     }
     if ((Now.getSquare(Invest).Owner == Side) && (Now.getSquare(Invest).Dep.DepType == "Unit"))
     {
         //sweeps through all possible unit moves
         SweepSearch(Sibling, Now, Invest, Side);
     }
 }
Esempio n. 6
0
        public override void MakeMove()
        {
            StishMiniMaxNode GameNode = new StishMiniMaxNode(null, StishBoard.Instance.Player1);

            GameNode.NodeBoardState = new BoardState(StishBoard.Instance);

            //double evaluation = MiniMaxMind.Instance.BuildABTree(GameNode, 4, int.MinValue, int.MaxValue, -1);
            MiniMaxMind.Instance.RecBuildMMTree(GameNode, 4);
            double evaluation = MiniMaxMind.Instance.TraverseTree(GameNode, 4, -1);

            //ForeSight.Instance.PredctionCount();

            StishBoard.Instance.ReplaceState(GameNode.BestChild.NodeBoardState);
        }
Esempio n. 7
0
        public void RecBuildMMTree(StishMiniMaxNode CurrentNode, int DepthCount)
        {
            //Depth count is given as 0 when called at root
            //the number quoted below  will not occur in the depth sequence

            if (CurrentNode == null || DepthCount == 0)
            {
                return;
            }

            ForeSight.Instance.GenerateChildren(CurrentNode);

            for (int index = 0; index < CurrentNode.CountChildren(); index++)
            {
                RecBuildMMTree((StishMiniMaxNode)CurrentNode.GetChild(index), DepthCount - 1);
            }
        }
Esempio n. 8
0
        public void GenerateChildren(StishMiniMaxNode NodeParent)
        {
            //parent argument will always contain "this" when called.
            Player OppositeAllegience;

            //ASSUMES THAT PLAYER 2 IS COMPUTER!
            if (NodeParent.Allegiance.GetPlayerNum == "Player1")
            {
                OppositeAllegience = new Computer((Computer)NodeParent.NodeBoardState.Player2);
            }
            else
            {
                OppositeAllegience = new Human(NodeParent.NodeBoardState.Player1);
            }

            //is a child of NodeParent as this is a turn spent doing nothing. the balance and MP are updated below and then this node is used as an example for others
            BoardState       SiblingBoardState = new BoardState(NodeParent.NodeBoardState);
            StishMiniMaxNode Sibling           = new StishMiniMaxNode(NodeParent, OppositeAllegience, SiblingBoardState);

            m_TurnPredictionCount = 0;

            Sibling.Allegiance.TurnBalance(Sibling.NodeBoardState);
            Sibling.Allegiance.MaxMP(Sibling.NodeBoardState);

            uint       cost = BarracksCost(Sibling.NodeBoardState, Sibling.Allegiance);
            Coordinate Look = new Coordinate();

            for (uint y = 0; y < Sibling.NodeBoardState.BoardSizeY; y++)
            {
                for (uint x = 0; x < Sibling.NodeBoardState.BoardSizeX; x++)
                {
                    Look.Y = y;
                    Look.X = x;

                    TestSquare(Sibling, Sibling.NodeBoardState, Sibling.Allegiance, Look, cost);
                }
            }
        }
Esempio n. 9
0
        public void BuildMMTree(StishMiniMaxNode RootNode, int DepthLimit)
        {
            StishMiniMaxNode        InvestNode;
            List <StishMiniMaxNode> GenQueue = new List <StishMiniMaxNode>();

            GenQueue.Add(RootNode);

            while (GenQueue.Count > 0)
            {
                InvestNode = GenQueue[0];
                ForeSight.Instance.GenerateChildren(InvestNode);
                //creates the depth layer but doesnt generate from them
                if (InvestNode.FindDepth() + 1 < DepthLimit)
                {
                    for (int index = 0; index < InvestNode.CountChildren(); index++)
                    {
                        GenQueue.Add((StishMiniMaxNode)InvestNode.GetChild(index));
                    }
                }

                GenQueue.Remove(InvestNode);
            }
        }
Esempio n. 10
0
        public void BuyPossibility(StishMiniMaxNode Sibling, BoardState Now, Player Side, Coordinate look, uint cost)
        {
            if (Side.Balance > 0)
            {
                //can afford a unit

                BoardState UnitBoardState = new BoardState(Now);
                if (Side.GetPlayerNum == "Player1")
                {
                    GameMaster.Instance.BuyUnit(look, UnitBoardState.Player1, UnitBoardState);
                }
                else
                {
                    GameMaster.Instance.BuyUnit(look, UnitBoardState.Player2, UnitBoardState);
                }

                /*
                 * if (Side.GetPlayerNum == "Player1")
                 * {
                 *  //opposite allegiance to it's parent
                 *  PlayersTurn = UnitBoardState.Player2;
                 * }
                 * else
                 * {
                 *  PlayersTurn = UnitBoardState.Player1;
                 * }
                 */

                //Parent.Parent as "parent" is actually just an updated model of the "real" parent where no actions were taken
                StishMiniMaxNode UnitCaseNode = new StishMiniMaxNode(Sibling.Parent, Sibling.Allegiance, UnitBoardState);
                PredctionCount();
            }
            if (Side.Balance >= cost)
            {
                //can afford a barracks

                BoardState BarracksBoardState = new BoardState(Now);
                if (Side.GetPlayerNum == "Player1")
                {
                    GameMaster.Instance.BuyBarracks(look, BarracksBoardState.Player1, BarracksBoardState);
                }
                else
                {
                    GameMaster.Instance.BuyBarracks(look, BarracksBoardState.Player2, BarracksBoardState);
                }

                /*
                 * if (Side.GetPlayerNum == "Player1")
                 * {
                 *  //opposite allegiance to it's parent
                 *  PlayersTurn = BarracksBoardState.Player2;
                 * }
                 * else
                 * {
                 *  PlayersTurn = BarracksBoardState.Player1;
                 * }
                 */

                //Parent.Parent as "parent" is actually just an updated model of the "real" parent where no actions were taken
                StishMiniMaxNode BarracksCaseNode = new StishMiniMaxNode(Sibling.Parent, Sibling.Allegiance, BarracksBoardState);
                PredctionCount();
            }
        }