/********************************************************************************************/ /********************************************************************************************/ /*** ***/ /*** 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); }
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); }
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); }
/*******************************************************/ /* 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); } }
/********************************************************************************************/ /********************************************************************************************/ /*** ***/ /*** 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); }
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); //} }
/********************************************************************************************/ /********************************************************************************************/ /*** ***/ /*** 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(); } }