//Update the policy if it was improved. public void OnEndPhase() { // update state... UnitAircraft myplane = commandersToControl[0].unitsOwned[0]; gameState = stateSpace.GetStateIndex(myplane); if (rewardFunc.Invoke(gameState) == 1.0f) { Destroy(Instantiate(successParticles, myplane.hexPos.getPosition(), Quaternion.identity), 0.5f); Debug.Log("Reached goal state!"); if (!isTraining) { sendCommands = false; } } if (isTraining) { // improve policy every iteration UpdateValueEstimatesInPolicy(lastState, lastActionIndex, gameState, discountFactor, learningRate); ImprovePolicyAt(lastState); } }
public void OnCommandPrompt() // should happen when it is time to make a decision { if (sendCommands) { UnitAircraft myplane = commandersToControl[0].unitsCommanded[0]; gameState = stateSpace.GetStateIndex(myplane); // if exceeded time limit... then just end it if (isTraining && roundCountThisEpisode > maximumRoundsPerEpisode) { EndEpisode(); } else { // for each agent... // Find state // Choose action // Queue action // Tell Game to submit actions // Use resulting state-action choice for (int i = 0; i < commandersToControl.Length; i++) { SelectMove(ref commandersToControl[i], randomnessFactor, difficultyLevel); } } } }
public AircraftState(UnitAircraft aircraft) { u = aircraft.hexPos.U; v = aircraft.hexPos.V; speed = aircraft.speed; heading = aircraft.heading; altitude = aircraft.altitude; hp = aircraft.hitPoints; }
public bool CanPerformManeuver(UnitAircraft unit, ref Maneuver man) { UnitAircraft copy = unit.Clone(); // try the maneuver ahead of time on a copy copy.PerformManeuver(man); copy.StallCheck(); copy.CrashCheck(); bool canDo = board.isTraversibleAir(copy.ProjectAhead()); return(canDo); // unit would move outside range! }
public List <Maneuver> GetAvailableManeuvers(UnitAircraft unit) { List <Maneuver> availableManeuvers = new List <Maneuver>(); if (CanPerformManeuver(unit, ref Maneuver.Straight)) { availableManeuvers.Add(Maneuver.Straight); } if (CanPerformManeuver(unit, ref Maneuver.Accelerate)) { availableManeuvers.Add(Maneuver.Accelerate); } if (CanPerformManeuver(unit, ref Maneuver.Climb)) { availableManeuvers.Add(Maneuver.Climb); } if (CanPerformManeuver(unit, ref Maneuver.Dive)) { availableManeuvers.Add(Maneuver.Dive); } if (CanPerformManeuver(unit, ref Maneuver.Left60)) { availableManeuvers.Add(Maneuver.Left60); } if (CanPerformManeuver(unit, ref Maneuver.Right60)) { availableManeuvers.Add(Maneuver.Right60); } if (CanPerformManeuver(unit, ref Maneuver.Left120)) { availableManeuvers.Add(Maneuver.Left120); } if (CanPerformManeuver(unit, ref Maneuver.Right120)) { availableManeuvers.Add(Maneuver.Right120); } if (CanPerformManeuver(unit, ref Maneuver.UTurn)) { availableManeuvers.Add(Maneuver.UTurn); } return(availableManeuvers); }
IEnumerator PerformManeuvers(float delayPerAction) { for (int i = 0; i < allUnits.Count; i++) { // do each plane's maneuver var unit = allUnits[i]; var m = allCommands[unit]; if (unit.hitPoints > 0) { Debug.Log("Executing: " + m.id.ToString() + " on " + unit.callsign); //m.Execute(ref unit); unit.PerformManeuver(m); unit.Move(); unit.StallCheck(); unit.CrashCheck(); //ManeuverManager.CrashCheck(ref unit); //m.aircraft.Move(); unit.TriggerAnimation(); // if plane is in range of another plane... attack! bool attacked = false; for (int range = 1; range <= 2; range++) { HexPosition attackPoint = unit.LookAhead(range); if (attackPoint.containsKey(GameBoard.KEY_UNIT_AIR)) { UnitAircraft target = (UnitAircraft)attackPoint.getValue(GameBoard.KEY_UNIT_AIR); Debug.Log(unit.callsign + " fires on " + target.callsign); attacked = true; unit.Attack(target); target.TriggerAnimation(); } } if (attacked) { unit.AttackAnimation(); } } yield return(new WaitForSeconds(delayPerAction)); } if (phase == GamePhase.MANEUVER) { AdvancePhase(); } }
public int GetStateIndex(UnitAircraft aircraft) { AircraftState state = new AircraftState(aircraft); int idx; if (aircraftToStateSpaceIndex.TryGetValue(state, out idx)) { return(idx); } else { throw new System.Exception("StateSpace couldn't find: " + ToString(state)); } }
//Forms the statespace by appending every possible state to the states list. public StateSpace(UnitAircraft unit, int boardSize_u, int boardSize_v) { states = new List <AircraftState>(); aircraftToStateSpaceIndex = new Dictionary <AircraftState, int>(); for (int u = 0; u < boardSize_u; u++) { for (int v = 0; v < boardSize_v; v++) { for (int speed = 0; speed <= unit.speedMax; speed++) { for (int heading = 0; heading < Heading.NUM_DIRECTIONS; heading++) { for (int altitude = 0; altitude <= UnitAircraft.ALTITUDE_MAX; altitude++) { for (int hitPoints = 0; hitPoints <= unit.hitPointsMax; hitPoints++) { // skip states that should not happen if (altitude == 0 && hitPoints > 0) { continue; // if altitude is 0 you should be dead my dude } if (speed == 0 && hitPoints > 0) { continue; // if speed is 0 you should be dead my dude } AircraftState aircraftState = new AircraftState( u, v, speed, heading, altitude, hitPoints ); // add the index of this plane state to the mapping so we can look it up aircraftToStateSpaceIndex.Add(aircraftState, states.Count); // store this plane state states.Add(aircraftState); } } } } } } }
/// <summary> /// move the plane ahead /// </summary> public void Move() { HexPosition newPos = ProjectAhead(); // crash? if (newPos.containsKey(GameBoard.KEY_UNIT_AIR)) { UnitAircraft other = (UnitAircraft)newPos.getValue(GameBoard.KEY_UNIT_AIR); if (other != this) { other.Die("Mid-air collision with " + callsign); UpdatePositionTo(newPos); Die("Mid-air collision with " + other.callsign); } } else { UpdatePositionTo(newPos); } }
public UnitAircraft GetAircraftAtState(int index) { UnitAircraft unit = new UnitAircraft(); AircraftState state = states[index]; unit.hexPos.U = state.u; unit.hexPos.V = state.v; unit.speed = state.speed; unit.heading = state.heading; unit.altitude = state.altitude; unit.hitPoints = state.hp; //int[] state = states[index]; //aircraft.hexPos.U, aircraft.hexPos.V, aircraft.speed, aircraft.heading, aircraft.altitude, aircraft.hitPoints //unit.hexPos.U = state[0]; //unit.hexPos.V = state[1]; //unit.speed = state[2]; //unit.heading = state[3]; //unit.altitude = state[4]; //unit.hitPoints = state[5]; return(unit); }
public void Attack(UnitAircraft other) { other.TakeDamage(3, callsign); }
//Order: u,v,speed,heading,altitude,HP public static int[] AircraftToArray(UnitAircraft aircraft) { return(new int[] { aircraft.hexPos.U, aircraft.hexPos.V, aircraft.speed, aircraft.heading, aircraft.altitude, aircraft.hitPoints }); }
void OnUnitDeath(UnitAircraft unit, string killer) { }
void OnUnitDeath(UnitAircraft unit, string killer) { unitsCommanded.Remove(unit); }
public void OnUnitDeath(UnitAircraft unit, string killer) { Debug.Log(unit.callsign + " killed by: " + killer); Destroy(Instantiate(deathExplosionPrefab, unit.hexPos.getPosition(), Quaternion.identity), deathExplosionPrefab.GetComponent <ParticleSystem>().main.duration + 0.1f); //unit.GetComponent<Renderer>().material = dead; }