/********************************************************************************************/ /********************************************************************************************/ /*** ***/ /*** AGENT SETUP ***/ /*** ***/ /********************************************************************************************/ /********************************************************************************************/ //Organize the diamonds by height and platform public List <DiamondInfo> setupDiamonds(CollectibleRepresentation[] collectiblesInfo, int[,] levelLayout) { List <DiamondInfo> Diamonds = new List <DiamondInfo>(); Platform platform; int i; foreach (CollectibleRepresentation diamond in collectiblesInfo) { //create diamond info platform = getDiamondPlatform(diamond.X, diamond.Y); //the levelLayout is used to calculate the areas of bias of the diamond DiamondInfo diamondInfo = new DiamondInfo(diamond.X, diamond.Y, platform, levelLayout); //add diamond to the list according to its position and platform - the highest diamonds on the highest platforms come first i = 0; if (Diamonds.Count == 0) { Diamonds.Add(diamondInfo); } else { foreach (DiamondInfo dInfo in Diamonds) { //if the diamond belongs to a higher platform if (diamondInfo.getPlatform().getY() < dInfo.getPlatform().getY()) { Diamonds.Insert(i, diamondInfo); break; } else if (diamondInfo.getPlatform().getY() == dInfo.getPlatform().getY()) { //if the diamond is in a platform at the same height but is higher than the other if (diamondInfo.getY() < dInfo.getY()) { Diamonds.Insert(i, diamondInfo); break; } } //if it is at the end of the list, then it is the lowest if (i == Diamonds.Count - 1) { Diamonds.Add(diamondInfo); break; } i++; } } } //give the diamonds their respective id for (i = 0; i < Diamonds.Count; i++) { Diamonds[i].setId(i); Diamonds[i].getPlatform().addDiamondOn(i); } return(Diamonds); }
public Moves skillLowerPlatform(Node node, DiamondInfo dInfo) { State agent = node.getState(); Platform platform = dInfo.getPlatform(); //if the diamond cant be reached from its platform then this skill does not apply if (Math.Abs(dInfo.getY() - (dInfo.getPlatform().getY() - dInfo.getPlatform().getHeight() / 2)) > agentMaxReach) { //TODO - create a new skill return(utils.randomAction(node, rnd, morphBias)); } //check if the agent is in between walls bool leftWall = false; bool rightWall = false; Platform agentPlatform = utils.onPlatform(agent.getPosX(), agent.getPosY(), 50, 10); if (agentPlatform != null && utils.obstacleBetween(agent.getPosX(), agentPlatform.getX() - agentPlatform.getWidth() / 2, agentPlatform)) { leftWall = true; } if (agentPlatform != null && utils.obstacleBetween(agent.getPosX(), agentPlatform.getX() + agentPlatform.getWidth() / 2, agentPlatform)) { rightWall = true; } //if the agent is completely stuck //TODO make a new skill to differentiate the cases when the agent is completely stuck from the ones when it only has one wall if (leftWall || rightWall) { //TODO - create a new skill return(utils.randomAction(node, rnd, morphBias)); } //roll to the one of the sides if (node.getRemainingMoves().Exists(x => x == Moves.MOVE_LEFT)) { return(Moves.MOVE_LEFT); } else if (node.getRemainingMoves().Exists(x => x == Moves.MOVE_RIGHT)) { return(Moves.MOVE_RIGHT); } else { node.noRemainingSTPActions(); return(Moves.NO_ACTION); } }
public Moves skillHigherPlatform(Node node, DiamondInfo dInfo) { State agent = node.getState(); Platform platform = dInfo.getPlatform(); //check if agent can jump to the platform if (Math.Abs(agent.getPosY() - (platform.getY() - platform.getHeight() / 2)) < circleMaxJump) { //if agent is under the platform - roll to one of the sides if (agent.getPosX() >= platform.getX() - platform.getWidth() / 2 && agent.getPosX() <= platform.getX() + platform.getWidth() / 2) { //TODO - check the there isn't a wall if (node.getRemainingMoves().Exists(x => x == Moves.ROLL_LEFT)) { return(Moves.ROLL_LEFT); } else if (node.getRemainingMoves().Exists(x => x == Moves.ROLL_RIGHT)) { return(Moves.ROLL_RIGHT); } else { node.noRemainingSTPActions(); return(Moves.NO_ACTION); } } else { //TODO - check if there isn't another platform in the way of the jump //if the agent is at the platform's left, roll right or jump if (agent.getPosX() < platform.getX()) { if (node.getRemainingMoves().Exists(x => x == Moves.ROLL_RIGHT)) { return(Moves.ROLL_RIGHT); } else if (node.getRemainingMoves().Exists(x => x == Moves.JUMP)) { return(Moves.JUMP); } else { node.noRemainingSTPActions(); return(Moves.NO_ACTION); } } //if the agent is at the platform's right, roll left or jump else { if (node.getRemainingMoves().Exists(x => x == Moves.ROLL_LEFT)) { return(Moves.ROLL_LEFT); } else if (node.getRemainingMoves().Exists(x => x == Moves.JUMP)) { return(Moves.JUMP); } else { node.noRemainingSTPActions(); return(Moves.NO_ACTION); } } } } else { return(utils.randomAction(node, rnd, jumpBias)); } }
public Moves skillCatchDiamond(Node node, DiamondInfo dInfo) { //if the agent is below the diamond at a very low velocity then jump if (Math.Abs(dInfo.getX() - node.getState().getPosX()) <= skillXmargin && Math.Abs(node.getState().getVelX()) < skillVelMargin) { if (node.getRemainingMoves().Exists(x => x == Moves.JUMP)) { return(Moves.JUMP); } else { node.noRemainingSTPActions(); return(Moves.NO_ACTION); } } //if the diamond is at the agents left else if (dInfo.getX() < node.getState().getPosX())// && Math.Abs(dInfo.getX() - node.getState().getPosX()) > skillXmargin) { //if it is at the same level - go left if (Math.Abs(dInfo.getY() - node.getState().getPosY()) < skillYmargin) { if (node.getRemainingMoves().Exists(x => x == Moves.ROLL_LEFT)) { return(Moves.ROLL_LEFT); } else { node.noRemainingSTPActions(); return(Moves.NO_ACTION); } } //if not, then it will be necessary to jump at some point else { if ((rnd.NextDouble() > skillJumpBias || node.getState().getVelX() > 0) && node.getRemainingMoves().Exists(x => x == Moves.ROLL_LEFT)) { return(Moves.ROLL_LEFT); } else { //make sure that it wont try the action jump if moving right if (node.getRemainingMoves().Exists(x => x == Moves.JUMP) && node.getState().getVelX() < 0) { return(Moves.JUMP); } else { node.noRemainingSTPActions(); return(Moves.NO_ACTION); } } } } //if the diamond is at the agents right if (dInfo.getX() > node.getState().getPosX())// && Math.Abs(dInfo.getX() - node.getState().getPosX()) > skillXmargin) { //if it is at the same level - go right if (Math.Abs(dInfo.getY() - node.getState().getPosY()) < skillYmargin) { if (node.getRemainingMoves().Exists(x => x == Moves.ROLL_RIGHT)) { return(Moves.ROLL_RIGHT); } else { return(Moves.NO_ACTION); } } //if not, then it will be necessary to jump at some point else { if ((rnd.NextDouble() > skillJumpBias || node.getState().getVelX() < 0) && node.getRemainingMoves().Exists(x => x == Moves.ROLL_RIGHT)) { return(Moves.ROLL_RIGHT); } else { //make sure that it wont try the action jump if moving left if (node.getRemainingMoves().Exists(x => x == Moves.JUMP) && node.getState().getVelX() > 0) { return(Moves.JUMP); } else { node.noRemainingSTPActions(); return(Moves.NO_ACTION); } } } } node.noRemainingSTPActions(); return(Moves.NO_ACTION); }