public override bool equals(Action action) { BuildHubAction buildHubAction = (BuildHubAction)action; return(equipt == buildHubAction.equipt && replace == buildHubAction.replace); }
private List <Action> generateBuildHubActions() { List <Action> actions = new List <Action>(); BuildHubAction action1 = new BuildHubAction(); BuildHubAction action2 = new BuildHubAction(); BuildHubAction action3 = new BuildHubAction(); action1.equipt = true; action2.replace = true; actions.Add(action1); actions.Add(action2); actions.Add(action3); return(actions); }
private List <Action> actionsDataToActions(ActionData[] actions) { List <Action> actionList = new List <Action>(); foreach (BuildHubActionData actionData in actions) { BuildHubAction action = new BuildHubAction(); action.equipt = actionData.equipt; action.replace = actionData.replace; action.qValue = actionData.qValue; actionList.Add(action); } return(actionList); }
public void applyBuildHubRewards() { foreach (AIAgent agent in AI_AGENTS) { bool won = agent.getBot().getRemainingDurability() > 0; List <BuildHubState> buildHubStates = agent.getBuildHubStates(); for (int stateIndex = 0; stateIndex < buildHubStates.Count; ++stateIndex) { int selectedActionIndex = buildHubStates[stateIndex].indexOfSelectedAction; if (selectedActionIndex >= 0) { double reward = 0; if (won) { reward = 20; } else { reward = -20; } double priorQValue = buildHubStates[stateIndex].actions[selectedActionIndex].qValue; BuildHubAction optimalAction = (BuildHubAction)buildHubStates[stateIndex].actions[0]; foreach (Action action in buildHubStates[stateIndex].actions) { if (action.qValue > optimalAction.qValue) { optimalAction = (BuildHubAction)action; } } buildHubStates[stateIndex].actions[selectedActionIndex].qValue += LEARNING_RATE * (reward + DISCOUNT_FACTOR * optimalAction.qValue - priorQValue); double growth = Math.Pow(Math.E, -Math.Abs(buildHubStates[stateIndex].actions[selectedActionIndex].qValue - priorQValue) / INVERSE_SENSITIVITY); buildHubStates[stateIndex].explorationRate = BUILD_HUB_EXPLORATION_RATE_ACTION_WEIGHT * (1.0 - growth) / (1.0 + growth) + (1.0 - BUILD_HUB_EXPLORATION_RATE_ACTION_WEIGHT) * buildHubStates[stateIndex].explorationRate; if (buildHubStates[stateIndex].explorationRate > 1) { buildHubStates[stateIndex].explorationRate = 1; } if (buildHubStates[stateIndex].explorationRate < 0) { buildHubStates[stateIndex].explorationRate = 0; } } } } }
private Robot generateRobot(int agentNumber) { List <Part> parts = new List <Part>(); int fastestCooling = int.MaxValue, fastestCharging = int.MaxValue, maxAttachments = 0; double highestClimbAngle = 0, durability = 0, weight = 0, highestSpeed = 0, highestDamage = 0, maxForce = 0, credits = CREDITS; bool invisible = false, hasEffect = false; BuildHubState priorBuildHubState = new BuildHubState(); BuildHubAction priorBuildHubAction = new BuildHubAction(); foreach (Part part in PARTS) { BuildHubState buildHubState = new BuildHubState(); buildHubState.effectOnObstacle = EFFECT_ON_OBSTACLE; buildHubState.canClimbObstacle = highestClimbAngle >= STEEPEST_OBSTACLE_ANGLE; buildHubState.canMoveOnObstacle = maxForce >= weight && highestSpeed >= HIGHEST_FRICTION * weight; buildHubState.durable = durability > 0 && durability >= highestDamage * 2; buildHubState.invisible = invisible; buildHubState.fast = maxForce >= weight && highestSpeed > 0 && highestSpeed >= weight * 2; buildHubState.hasEffect = hasEffect; buildHubState.heavyDamage = highestDamage > 0 && highestDamage >= durability / 4; buildHubState.quickCooling = fastestCooling <= 1000; buildHubState.quickCharging = fastestCharging <= 1000; if ((BUILD_HUB_STATES.Count == 0) || !BUILD_HUB_STATES.Exists(s => s.Compare(buildHubState) == 0)) { List <Action> buildHubActionsForState = default; if ((BUILD_HUB_STATES.Count == 0) || (RANDOM.NextDouble() < priorBuildHubState.explorationRate)) { buildHubActionsForState = generateBuildHubActions(); } else { buildHubActionsForState = getClosestBuildHubState(buildHubState).getActions(); } buildHubState.setActions(buildHubActionsForState); BUILD_HUB_STATES.Add(buildHubState); } else { buildHubState = BUILD_HUB_STATES.Find(s => s.Compare(buildHubState) == 0); } if ((buildHubState.explorationRate > 0) && (RANDOM.NextDouble() < buildHubState.explorationRate)) { buildHubState.indexOfSelectedAction = RANDOM.Next(buildHubState.getActions().Count); priorBuildHubAction = (BuildHubAction)buildHubState.getActions()[buildHubState.indexOfSelectedAction]; } else { BuildHubAction optimalAction = (BuildHubAction)buildHubState.getActions()[0]; for (int actionIndex = 1; actionIndex < buildHubState.getActions().Count; ++actionIndex) { Action action = buildHubState.getActions()[actionIndex]; if (action.qValue > optimalAction.qValue) { optimalAction = (BuildHubAction)action; buildHubState.indexOfSelectedAction = actionIndex; } } priorBuildHubAction = optimalAction; } if (priorBuildHubAction.equipt) { int costNewPart = PERFORMANCE_METRIC_CALCULATOR.calculateCost(part); if (!parts.Exists(p => p.GetType() == part.GetType())) { if ((!(part is Attachment) || ((part is Attachment) && (maxAttachments > 0))) && ((weight + part.getWeight()) < maxForce) && (credits >= costNewPart)) { credits -= costNewPart; --maxAttachments; weight += part.getWeight(); durability += part.getDurability(); if (part is Body && (maxAttachments < ((Body)part).getMaxAttachments())) { maxAttachments = ((Body)part).getMaxAttachments(); } if (part is Mobility) { highestClimbAngle = ((Mobility)part).getClimbAngle(); highestSpeed = ((Mobility)part).getMaxSpeed(); maxForce = ((Mobility)part).getMaxForce(); } parts.Add(part); if (part is Attachment) { if (fastestCooling > ((Attachment)part).getMinCoolingTime()) { fastestCooling = ((Attachment)part).getMinCoolingTime(); } if (fastestCharging > ((Attachment)part).getMinChargeTime()) { fastestCharging = ((Attachment)part).getMinChargeTime(); } if (highestDamage < ((Attachment)part).getMaxDamage()) { highestDamage = ((Attachment)part).getMaxDamage(); } if (!invisible && ((Attachment)part).isInvisible()) { invisible = true; } if (!hasEffect && ((Attachment)part).getEffect() != default) { hasEffect = true; } } } else { buildHubState.indexOfSelectedAction += 2; } } else { int partIndex = parts.FindIndex(p => p.GetType() == part.GetType()); int costOldPart = PERFORMANCE_METRIC_CALCULATOR.calculateCost(parts[partIndex]); if ((!(part is Attachment) || ((part is Attachment) && (maxAttachments > 0))) && ((weight + part.getWeight()) < maxForce) && ((credits + costOldPart) >= costNewPart)) { credits += costOldPart; credits -= costNewPart; --maxAttachments; weight -= parts[partIndex].getWeight(); weight += part.getWeight(); durability -= parts[partIndex].getDurability(); durability += part.getDurability(); if (part is Body && (maxAttachments < ((Body)part).getMaxAttachments())) { maxAttachments = ((Body)part).getMaxAttachments(); } if (part is Mobility) { highestClimbAngle = ((Mobility)part).getClimbAngle(); highestSpeed = ((Mobility)part).getMaxSpeed(); maxForce = ((Mobility)part).getMaxForce(); } parts[partIndex] = part; if (part is Attachment) { fastestCooling = int.MaxValue; fastestCharging = int.MaxValue; highestDamage = 0; invisible = false; hasEffect = false; foreach (Part currentPart in parts) { if (currentPart is Attachment) { if (fastestCooling > ((Attachment)currentPart).getMinCoolingTime()) { fastestCooling = ((Attachment)part).getMinCoolingTime(); } if (fastestCharging > ((Attachment)currentPart).getMinChargeTime()) { fastestCharging = ((Attachment)currentPart).getMinChargeTime(); } if (highestDamage < ((Attachment)currentPart).getMaxDamage()) { highestDamage = ((Attachment)currentPart).getMaxDamage(); } if (!invisible && ((Attachment)currentPart).isInvisible()) { invisible = true; } if (!hasEffect && ((Attachment)currentPart).getEffect() != default) { hasEffect = true; } } } } buildHubState.indexOfSelectedAction += 1; } else { buildHubState.indexOfSelectedAction += 2; } } } else if (priorBuildHubAction.replace) { int costNewPart = PERFORMANCE_METRIC_CALCULATOR.calculateCost(part); if (!parts.Exists(p => p.GetType() == part.GetType())) { if ((!(part is Attachment) || ((part is Attachment) && (maxAttachments > 0))) && ((weight + part.getWeight()) < maxForce) && (credits >= costNewPart)) { credits -= costNewPart; --maxAttachments; weight += part.getWeight(); durability += part.getDurability(); if (part is Body && (maxAttachments < ((Body)part).getMaxAttachments())) { maxAttachments = ((Body)part).getMaxAttachments(); } if (part is Mobility) { highestClimbAngle = ((Mobility)part).getClimbAngle(); highestSpeed = ((Mobility)part).getMaxSpeed(); maxForce = ((Mobility)part).getMaxForce(); } parts.Add(part); if (part is Attachment) { if (fastestCooling > ((Attachment)part).getMinCoolingTime()) { fastestCooling = ((Attachment)part).getMinCoolingTime(); } if (fastestCharging > ((Attachment)part).getMinChargeTime()) { fastestCharging = ((Attachment)part).getMinChargeTime(); } if (highestDamage < ((Attachment)part).getMaxDamage()) { highestDamage = ((Attachment)part).getMaxDamage(); } if (!invisible && ((Attachment)part).isInvisible()) { invisible = true; } if (!hasEffect && ((Attachment)part).getEffect() != default) { hasEffect = true; } } buildHubState.indexOfSelectedAction -= 1; } else { buildHubState.indexOfSelectedAction += 1; } } else { int partIndex = parts.FindIndex(p => p.GetType() == part.GetType()); int costOldPart = PERFORMANCE_METRIC_CALCULATOR.calculateCost(parts[partIndex]); if ((!(part is Attachment) || ((part is Attachment) && (maxAttachments > 0))) && ((weight + part.getWeight()) < maxForce) && ((credits + costOldPart) >= costNewPart)) { credits += costOldPart; credits -= costNewPart; --maxAttachments; weight -= parts[partIndex].getWeight(); weight += part.getWeight(); durability -= parts[partIndex].getDurability(); durability += part.getDurability(); if (part is Body && (maxAttachments < ((Body)part).getMaxAttachments())) { maxAttachments = ((Body)part).getMaxAttachments(); } if (part is Mobility) { highestClimbAngle = ((Mobility)part).getClimbAngle(); highestSpeed = ((Mobility)part).getMaxSpeed(); maxForce = ((Mobility)part).getMaxForce(); } parts[partIndex] = part; if (part is Attachment) { fastestCooling = int.MaxValue; fastestCharging = int.MaxValue; highestDamage = 0; invisible = false; hasEffect = false; foreach (Part currentPart in parts) { if (currentPart is Attachment) { if (fastestCooling > ((Attachment)currentPart).getMinCoolingTime()) { fastestCooling = ((Attachment)part).getMinCoolingTime(); } if (fastestCharging > ((Attachment)currentPart).getMinChargeTime()) { fastestCharging = ((Attachment)currentPart).getMinChargeTime(); } if (highestDamage < ((Attachment)currentPart).getMaxDamage()) { highestDamage = ((Attachment)currentPart).getMaxDamage(); } if (!invisible && ((Attachment)currentPart).isInvisible()) { invisible = true; } if (!hasEffect && ((Attachment)currentPart).getEffect() != default) { hasEffect = true; } } } } } else { buildHubState.indexOfSelectedAction += 1; } } } priorBuildHubState = buildHubState; } List <Part> baseParts = new List <Part>(); baseParts.AddRange(BASE_PARTS); if (!parts.Exists(p => p is Head)) { parts.Add(baseParts.Find(p => p is Head)); } if (!parts.Exists(p => p is Body)) { parts.Add(baseParts.Find(p => p is Body)); } if (!parts.Exists(p => p is Mobility)) { parts.Add(baseParts.Find(p => p is Mobility)); } if (!parts.Exists(p => (p is Attachment) && ((Attachment)p).isWeapon())) { parts.Add(baseParts.Find(p => p is Blaster)); } for (int partIndex = 0; partIndex < parts.Count; ++partIndex) { parts[partIndex] = parts[partIndex].clone(false); } return(new Robot(AGENT_PREFIX + agentNumber, false, parts.ToArray())); }