Пример #1
0
        /********************************************************************************************/
        /********************************************************************************************/
        /***                                                                                      ***/
        /***                                     MAIN SETUP                                       ***/
        /***                                                                                      ***/
        /********************************************************************************************/
        /********************************************************************************************/

        //implements abstract rectangle interface: used to setup the initial information so that the agent has basic knowledge about the level
        public void Setup(CountInformation nI, RectangleRepresentation rI, CircleRepresentation cI, ObstacleRepresentation[] oI, ObstacleRepresentation[] rPI, ObstacleRepresentation[] cPI, CollectibleRepresentation[] colI, Rectangle area, double timeLimit)
        {
            ground                 = new Platform(0, area.Bottom, 0, 0, PlatformType.Black);
            utils                  = new Utils(ground, circleInfo.Radius, area);
            numbersInfo            = nI;
            nCollectiblesLeft      = nI.CollectiblesCount;
            rectangleInfo          = rI;
            circleInfo             = cI;
            obstaclesInfo          = utils.joinObstacles(oI, rPI);
            rectanglePlatformsInfo = rPI;
            circlePlatformsInfo    = cPI;
            collectiblesInfo       = colI;
            uncaughtCollectibles   = new List <CollectibleRepresentation>(collectiblesInfo);
            this.area              = area;
            gSpeed                 = 1.0f;
            goalMode               = GoalType.FirstPossible;

            //setup level layout
            levelLayout = utils.getLevelLayout(obstaclesInfo, area);

            //calculates the area of the rectangle since only the info of the height is available
            rectangleArea = utils.setRectangleArea(rectangleInfo.Height);

            //gets the initial position of the Rectangle to test is the game has started or is still at the menu
            previousRectanglePosX = rectangleInfo.X;
            previousRectanglePosY = rectangleInfo.Y;

            Platforms = utils.setupPlatforms(obstaclesInfo, rPI, cPI);
            Diamonds  = utils.setupDiamonds(collectiblesInfo, levelLayout);

            /*************TESTS*************/
            //inform a level has started
            utils.writeStart(1);

            //search - state - original; action - original; no partial plans
            //RRT = new RRTUtilsGS(actionTime, simTime, simTimeFinish, getPossibleMoves(), type, area, collectiblesInfo.Length, RRTTypes.Original, RRTTypes.Original, obstaclesInfo, gSpeed, Diamonds, Platforms, utils, false, false);
            //search - state - original; action - STP; biasSTP - 0.25/0.5/0.75; no partial plans
            //RRT = new RRTUtils(actionTime, simTime, simTimeFinish, getPossibleMoves(), type, area, collectiblesInfo.Length, RRTTypes.Original, RRTTypes.STP, obstaclesInfo, gSpeed, Diamonds, Platforms, utils, false, false);
            //search - state - bias - 0.25/0.50/0.75; action - STP; biasSTP;  no partial plans
            //RRT = new RRTUtils(actionTime, simTime, simTimeFinish, getPossibleMoves(), type, area, collectiblesInfo.Length, RRTTypes.Bias, RRTTypes.STP, obstaclesInfo, gSpeed, Diamonds, Platforms, utils, false, false);
            //search - state - bgt - 10/50/10; action - STP; biasSTP; no partial plans
            //RRT = new RRTUtils(actionTime, simTime, simTimeFinish, getPossibleMoves(), type, area, collectiblesInfo.Length, RRTTypes.BGT, RRTTypes.STP, obstaclesInfo, gSpeed, Diamonds, Platforms, utils, false, false);
            //search - state - bgt zoom - 50; action - STP; biasSTP; no partial plans
            //RRT = new RRTUtils(actionTime, simTime, simTimeFinish, getPossibleMoves(), type, area, collectiblesInfo.Length, RRTTypes.BGTAreaBias, RRTTypes.STP, obstaclesInfo, gSpeed, Diamonds, Platforms, utils, false, false);
            //search - state - bgt bias - 50; action - STP; biasSTP; no partial plans
            //RRT = new RRTUtils(actionTime, simTime, simTimeFinish, getPossibleMoves(), type, area, collectiblesInfo.Length, RRTTypes.BGTBias, RRTTypes.STP, obstaclesInfo, gSpeed, Diamonds, Platforms, utils, false, false);
            //search - state - zoom; action - STP; biasSTP; no partial plans
            //RRT = new RRTUtils(actionTime, simTime, simTimeFinish, getPossibleMoves(), type, area, collectiblesInfo.Length, RRTTypes.AreaBias, RRTTypes.STP, obstaclesInfo, gSpeed, Diamonds, Platforms, utils, false, false);

            /*************FINAL*************/
            RRT = new RRTUtilsGS(actionTime, simTime, simTimeFinish, getPossibleMoves(), type, area, collectiblesInfo.Length, RRTTypes.BGT, RRTTypes.STP, obstaclesInfo, gSpeed, Diamonds, Platforms, utils, true, true);

            //RRT = new RRTUtils(actionTime, simTime, simTimeFinish, getPossibleMoves(), type, area, collectiblesInfo.Length, RRTTypes.BGT, RRTTypes.Original, obstaclesInfo, gSpeed, Diamonds, Platforms, utils, false, false);

            RRT.setRadius(rectangleInfo.Height / 2);
            pathPlan   = new PathPlan(cutplan, colI.GetLength(0), utils);
            controller = new RectangleController(gSpeed, utils);
        }
Пример #2
0
        public PathPlan joinPlans(PathPlan plan1, PathPlan plan2)
        {
            List <Point> newPoints = new List <Point>();

            newPoints.AddRange(plan1.getPathPoints());
            newPoints.AddRange(plan2.getPathPoints());

            PathPlan newPlan = new PathPlan(cutPlan, plan1.totalCollectibles, newPoints, utils);

            return(newPlan);
        }
Пример #3
0
        public PathPlan clone()
        {
            PathPlan newPlan = new PathPlan(cutPlan, totalCollectibles, utils);

            newPlan.setTotalCollectibles(this.totalCollectibles);

            foreach (Point point in this.pathPoints)
            {
                newPlan.addPointEnd(point);
            }

            return(newPlan);
        }
Пример #4
0
        /*******************************************************/
        /*                  Planning - aux                     */
        /*******************************************************/

        //used when trying to recover a plan where the agent is not on a platform and state of the plan
        //join plans on utils

        //simple plan recovery - check if agent is on a platform that belongs to the plan and with the same state
        private void recoverPlan()
        {
            //TODO - update debug drawing
            currentAction           = Moves.NO_ACTION;
            lastMove                = Moves.NO_ACTION;
            controller.morphReached = false;
            controller.slideReached = false;

            //see if there is a point in the original plan that is the same as the one the agent is on and that has the same number or less of diamonds caught
            bool pointFound = false;

            Platform     currentPlatform = utils.onPlatform(rectangleInfo.X, rectangleInfo.Y + rectangleInfo.Height / 2, 25, 10);
            List <Point> pathPoints      = pathPlan.getOriginalPoints();

            int i;

            for (i = 0; i < pathPoints.Count; i++)
            {
                if (pathPoints[i].getUncaughtColl().Count >= uncaughtCollectibles.Count)
                {
                    Platform pointPlatform = utils.onPlatform(pathPoints[i].getPosX(), pathPoints[i].getPosY() + rectangleInfo.Height / 2, 25, 10);

                    if (utils.samePlatform(currentPlatform, pointPlatform) && !utils.obstacleBetween(rectangleInfo.X, pathPoints[i].getPosX(), currentPlatform))
                    {
                        pointFound = true;
                        break;
                    }
                }
            }

            if (pointFound)
            {
                //create a new plan from the point we got previously
                pathPlan = new PathPlan(cutplan, remaining.Count, utils);
                pathPlan.setTotalCollectibles(originalPlan.getTotalCollectibles());
                pathPlan.setCurrentPoint(i);

                for (int j = i; j < pathPoints.Count; j++)
                {
                    pathPlan.addPointEnd(pathPoints[j]);
                }
                pathPlan.setOriginalPoints(pathPoints);
                firstAction = true;
            }
            //if no platform in common was found, then replan
            else
            {
                replan(false);
            }
        }
Пример #5
0
        /********************************************************************************************/
        /********************************************************************************************/
        /***                                                                                      ***/
        /***                                         PLAN                                         ***/
        /***                                                                                      ***/
        /********************************************************************************************/
        /********************************************************************************************/

        //used when trying to recover a plan where the agent is not on a platform and state of the plan
        public PathPlan joinPlans(PathPlan correction, PathPlan original, Point connectionPoint)
        {
            List <Point> points = original.getPathPoints();
            int          i;

            for (i = 0; i < points.Count; i++)
            {
                if (points[i].getPosX() == connectionPoint.getPosX() && points[i].getPosY() == connectionPoint.getPosY() &&
                    points[i].getUncaughtColl().Count == connectionPoint.getUncaughtColl().Count)
                {
                    break;
                }
            }
            for (int j = i; j < points.Count; j++)
            {
                correction.addPoint(points[j]);
            }

            return(correction);
        }
Пример #6
0
 private void replan(bool correct)
 {
     //TODO - make a new version for this
     correct = false;
     //if correct is true, it means the agent should try to first recover the previous plan
     //but it should also be careful not to repeat the same failures and should understand when it completed its plan
     if (correct && !pathPlan.checkIfConstantFail() && !checkPlanCompletion())
     {
         recoverPlan();
     }
     else
     {
         currentAction           = Moves.NO_ACTION;
         planRRT                 = true;
         newPlan                 = true;
         controller.slideReached = false;
         controller.morphReached = false;
         previousPlan            = pathPlan;
         pathPlan                = new PathPlan(cutplan, remaining.Count, utils);
     }
 }
        private void replan(bool correct)
        {
            //if correct is true, it means the agent should try to first recover the previous plan
            //but it should also be careful not to repeat the same failures and should understand when it completed its plan

            //Since search is so fast, removed recovering due to faulty plans (e.g bad physics simulation on a platform

            /*
             * if (correct && !pathPlan.checkIfConstantFail() && !checkPlanCompletion())
             * {
             *  recoverPlan();
             * }
             * else
             * {
             */
            currentAction          = Moves.NO_ACTION;
            planRRT                = true;
            newPlan                = true;
            controller.jumpReached = false;
            controller.rollReached = false;
            previousPlan           = pathPlan;
            pathPlan               = new PathPlan(cutplan, remaining.Count, utils);
            //}
        }
Пример #8
0
        /********************************************************************************************/
        /********************************************************************************************/
        /***                                                                                      ***/
        /***                                     PLANNING                                         ***/
        /***                                                                                      ***/
        /********************************************************************************************/
        /********************************************************************************************/

        private void planSolution()
        {
            //The agent must be still so it starts at the same position as the one in the first point of the plan
            //This is to guarantee that the agent stops before start planning, and keeps still
            if (rectangleInfo.VelocityY < correctVelYMargin && rectangleInfo.VelocityY > -correctVelYMargin &&
                rectangleInfo.VelocityX < correctVelXMargin && rectangleInfo.VelocityX > -correctVelXMargin)
            {
                //make sure there is nothing moving the agent when planning
                currentAction = Moves.NO_ACTION;

                //if the plan is new build a new tree
                if (newPlan)
                {
                    //update the diamond list
                    RRT.setDiamonds(Diamonds);
                    State initialState = new State(rectangleInfo.X, rectangleInfo.Y, rectangleInfo.VelocityX, rectangleInfo.VelocityY, rectangleInfo.Height / 2, 0, caughtCollectibles, uncaughtCollectibles);
                    //run algorithm
                    T = RRT.buildNewRRT(initialState, predictor, iterationsS);
                }
                else //continue the previous tree
                {
                    T = RRT.RRT(T);
                }
                //draw the nodes of the tree
                if (debugTree)
                {
                    debugInfo = RRT.getDebugTreeInfo(T).ToArray();
                }

                newPlan = false;

                //if the argorithm reached a goal state or a semi plan then get the plan
                if (T.getGoal() != null)
                {
                    if (!written)
                    {
                        int exploredNodesOnce  = RRT.getExploredNodesOnce();
                        int exploredNodesTotal = RRT.getExploredNodesTotal();
                        int totalNodes         = T.getNodes().Count;
                        utils.writeTimeToFile(1, 1, searchTime, exploredNodesOnce, exploredNodesTotal, totalNodes, gSpeed);
                        written = true;
                    }

                    pathPlan = RRT.getPlan(T);

                    firstAction = true;

                    //do not plan on the next iteration
                    planRRT      = false;
                    getDebugInfo = true;

                    //save a copy of the original plan
                    originalPlan = pathPlan.clone();
                    pathPlan.saveOriginal();
                }
            }
            else
            {
                keepStill();
            }
        }
        /*******************************************************/
        /*                  Planning - aux                     */
        /*******************************************************/

        //used when trying to recover a plan where the agent is not on a platform and state of the plan
        //join plans on utils

        //simple plan recovery - check if agent is on a platform that belongs to the plan and with the same state
        private void recoverPlan()
        {
            //TODO - update debug drawing
            currentAction          = Moves.NO_ACTION;
            lastMove               = Moves.NO_ACTION;
            controller.jumpReached = false;
            controller.rollReached = false;

            //see if there is a point in the original plan that is the same as the one the agent is on and that has the same number or less of diamonds caught
            bool pointFound = false;

            Platform     currentPlatform = utils.onPlatform(circleInfo.X, circleInfo.Y + circleInfo.Radius, 25, 10);
            List <Point> pathPoints      = pathPlan.getOriginalPoints();

            int i;

            //start from the end
            for (i = pathPoints.Count - 1; i >= 0; i--)
            {
                if (pathPoints[i].getUncaughtDiamonds().Count >= uncaughtCollectibles.Count)
                {
                    Platform pointPlatform = utils.onPlatform(pathPoints[i].getPosX(), pathPoints[i].getPosY() + circleInfo.Radius, 25, 10);

                    if (utils.samePlatform(currentPlatform, pointPlatform) && !utils.obstacleBetween(circleInfo.X, pathPoints[i].getPosX(), currentPlatform))
                    {
                        pointFound = true;
                        break;
                    }
                }
            }
            if (pointFound)
            {
                //create a new plan from the point we got previously
                pathPlan = new PathPlan(cutplan, remaining.Count, utils);
                pathPlan.setTotalCollectibles(originalPlan.getTotalCollectibles());
                pathPlan.setCurrentPoint(i);

                for (int j = i; j < pathPoints.Count; j++)
                {
                    pathPlan.addPointEnd(pathPoints[j]);
                }
                pathPlan.setOriginalPoints(pathPoints);
                firstAction = true;
                return;
            }
            //if no platform in common was found, then try to find a way to a platform in the plan and replan if this fails
            else if (pathPlan.getPathPoints().Count != 0)
            {
                List <DiamondInfo> remainingDiamonds = new List <DiamondInfo>();
                List <DiamondInfo> caughtDiamonds    = new List <DiamondInfo>();
                foreach (DiamondInfo diamond in Diamonds)
                {
                    if (!diamond.wasCaught())
                    {
                        remainingDiamonds.Add(diamond);
                    }
                    else
                    {
                        caughtDiamonds.Add(diamond);
                    }
                }

                //Simulator
                Simulator sim = new CircleSimulator(Platforms);
                sim.setSimulator(circleInfo.X, circleInfo.Y, circleInfo.VelocityX, circleInfo.VelocityY, remainingDiamonds);

                //TEST
                RRT.setDiamonds(Diamonds);

                State   initialState = new State(circleInfo.X, circleInfo.Y, circleInfo.VelocityX, circleInfo.VelocityY, circleInfo.Radius, circleInfo.Radius, caughtDiamonds, remainingDiamonds);
                float[] returnPos    = new float[2];
                returnPos[0] = pathPlan.getPathPoints()[0].getPosX();
                returnPos[1] = pathPlan.getPathPoints()[0].getPosY();
                RRT.setReturnPos(returnPos);
                Tree t = RRT.buildNewMPRRT(initialState, sim, GoalType.Return, iterationsS);

                if (t.getGoal() != null)
                {
                    PathPlan shortPlan = RRT.getPlan(t);
                    pathPlan = pathPlan.joinPlans(shortPlan, pathPlan);
                    pathPlan.cleanPlan(obstaclesInfo, remainingDiamonds, area, circleInfo.Radius, true, true);
                    getDebugInfo = true;
                    return;
                }
                else
                {
                    replan(false);
                }
            }
            replan(false);
        }
        /********************************************************************************************/
        /********************************************************************************************/
        /***                                                                                      ***/
        /***                                     PLANNING                                         ***/
        /***                                                                                      ***/
        /********************************************************************************************/
        /********************************************************************************************/

        private void planSolution()
        {
            //The agent must be still so it starts at the same position as the one in the first point of the plan
            //This is to guarantee that the agent stops before start planning, and keeps still
            if (circleInfo.VelocityY < correctVelYMargin && circleInfo.VelocityY > -correctVelYMargin &&
                circleInfo.VelocityX < correctVelXMargin && circleInfo.VelocityX > -correctVelXMargin &&
                utils.onPlatform(circleInfo.X, circleInfo.Y + circleInfo.Radius, 25, 10) != null)
            {
                //make sure there is nothing moving the agent when planning
                currentAction = Moves.NO_ACTION;

                //if the plan is new build a new tree
                if (newPlan)
                {
                    List <DiamondInfo> remainingDiamonds = new List <DiamondInfo>();
                    List <DiamondInfo> caughtDiamonds    = new List <DiamondInfo>();
                    foreach (DiamondInfo diamond in Diamonds)
                    {
                        if (!diamond.wasCaught())
                        {
                            remainingDiamonds.Add(diamond);
                        }
                        else
                        {
                            caughtDiamonds.Add(diamond);
                        }
                    }

                    //Simulator
                    Simulator sim = new CircleSimulator(Platforms);
                    sim.setSimulator(circleInfo.X, circleInfo.Y, circleInfo.VelocityX, circleInfo.VelocityY, remainingDiamonds);

                    //update the diamond list
                    RRT.setDiamonds(Diamonds);
                    //create initial state
                    State initialState = new State(circleInfo.X, circleInfo.Y, circleInfo.VelocityX, circleInfo.VelocityY, circleInfo.Radius, circleInfo.Radius, caughtDiamonds, remainingDiamonds);
                    //run algorithm
                    T = RRT.buildNewRRT(initialState, sim, iterationsS);
                }
                else //continue the previous tree
                {
                    T = RRT.RRT(T);
                }
                //draw the nodes of the tree
                if (debugTree)
                {
                    debugInfo = RRT.getDebugTreeInfo(T).ToArray();
                }

                newPlan = false;

                //if the argorithm reached a goal state or a semi plan then get the plan
                if (T.getGoal() != null)
                {
                    if (!written)
                    {
                        int exploredNodesOnce  = RRT.getExploredNodesOnce();
                        int exploredNodesTotal = RRT.getExploredNodesTotal();
                        int totalNodes         = T.getNodes().Count;
                        utils.writeTimeToFile(1, 0, searchTime, exploredNodesOnce, exploredNodesTotal, totalNodes, gSpeed);
                        written = true;
                    }

                    pathPlan = RRT.getPlan(T);

                    firstAction = true;
                    lastMove    = Moves.NO_ACTION;


                    //do not plan on the next iteration
                    planRRT      = false;
                    getDebugInfo = true;

                    //save a copy of the original plan
                    if (cutplan)
                    {
                        pathPlan.cleanPlan(obstaclesInfo, Diamonds, area, circleInfo.Radius, true, true);
                    }
                    originalPlan = pathPlan.clone();
                    pathPlan.saveOriginal();
                }
            }
            else
            {
                keepStill();
            }
        }