private ActionScore DecideAction() { List <ActionScore> actionScores = new List <ActionScore>(); ActionScore attack; // Get weight of each healing if current unity is a medic if (ActiveHuman.CharData.type == UnitType.Medic) { ActionScore heal = GetGeneralScore(TeamAi, SkillCategory.Heal, medicSelfAffector, medicHealingAffector); heal.action = AIState.Heal; actionScores.Add(heal); attack = GetGeneralScore(TeamPlayers, SkillCategory.Attack, medicAttackingAffector); } else { // Get weight of attacking action attack = GetGeneralScore(TeamPlayers); } attack.action = AIState.Offensive; actionScores.Add(attack); // Get weight of defensive action ActionScore defensive = GetDefensiveScore(); defensive.action = AIState.Defensive; actionScores.Add(defensive); // TODO:- Add Defensive weight return(GetHighest(actionScores)); }
public override void NewTurn(Humanoid activeCharacter) { base.NewTurn(activeCharacter); // TODO:- Need this? winningAction = DecideAction(); Debug.Log("AI winning state: " + winningAction.action.ToString()); NewDelay(); // To Slow stuff Down }
private void AssertAreEqual(ActionScore[] expected, ActionScore[] actual) { Assert.AreEqual(expected.Length, actual.Length); for (int i = 0; i < expected.Length; i++) { Assert.AreEqual(expected[i].Action, actual[i].Action); Assert.AreEqual(expected[i].Score, actual[i].Score, 0.0001); } CollectionAssert.AreEqual( expected: Enumerable.Range(0, expected.Length).Select(i => (uint)i).ToList(), actual: actual.Select(a => a.Action).OrderBy(a => a).ToList()); }
private ActionScore GetHighest(List <ActionScore> targetScores) { ActionScore highest = new ActionScore(); foreach (ActionScore ts in targetScores) { if (ts.Score >= highest.Score) { highest = ts; } } return(highest); }
private ActionScore GetGeneralScore(List <Humanoid> targets, SkillCategory category = SkillCategory.Attack, float selfEffector = 1, float targetEffector = 1) { List <ActionScore> Targets = new List <ActionScore>(); // Calculate healing weight for all alive team members foreach (Humanoid h in targets) { if (h.IsDead) { continue; } ActionScore newTarget = new ActionScore(); newTarget.Target = h; // Get chance of hitting target float distanceFrom = Vector2.Distance(h.transform.position, ActiveHuman.transform.position); float distanceScore = GetDistanceScore(distanceFrom); // Get health score applying self effector if active player if (h.GetHashCode() == ActiveHuman.GetHashCode()) { float generalScore = GetHealthScore(h.CharData.health, h.MaxHealth, category, selfEffector, targetEffector); newTarget.Score = distanceScore * (generalScore / 50); //Debug.Log("General state score: " + newTarget.Score); } else { newTarget.Score = distanceScore * (GetHealthScore(h.CharData.health, h.MaxHealth, category, targetEffector) / 50); //Debug.Log("General state score: " + newTarget.Score); } // Cap Score if (newTarget.Score > 50) { newTarget.Score = 50; } Targets.Add(newTarget); } return(GetHighest(Targets)); }
private void ActivateAction(ActionScore winningScore) { switch (winningScore.action) { case AIState.Offensive: UseAttack(winningScore.Target); break; case AIState.Heal: UseHeal(winningScore.Target); break; case AIState.Defensive: UseDefensive(winningScore.Target); break; case AIState.NotAssigned: Debug.Log("Ai State not assigned? Skip turn maybe?"); break; } }
private ActionScore GetDefensiveScore() { int enemyCount = MembersInRange(TeamPlayers, optimalDistance); Humanoid closestFriendly = Closest(TeamAi); float enemyCountScore = (enemyCount > 2) ? 50 : 0; // High if more than 2 enemies ActionScore defensiveScore = new ActionScore(); defensiveScore.Score = enemyCountScore * (GetHealthScore(ActiveHuman.CharData.health, ActiveHuman.MaxHealth) / 50); defensiveScore.Target = closestFriendly; if (closestFriendly == null) { defensiveScore.Score = 0; } Debug.Log("Enemy Count:" + enemyCount); Debug.Log("Defensive state score: " + defensiveScore.Score); return(defensiveScore); }
internal TrainerResult(ActionScore[] progressivePrediction, int[] observedActions, float[] observedProbabilities) { if (progressivePrediction == null) throw new ArgumentNullException(nameof(progressivePrediction)); if (observedActions == null) throw new ArgumentNullException(nameof(observedActions)); if (observedProbabilities == null) throw new ArgumentNullException(nameof(observedProbabilities)); if (observedActions.Length != observedProbabilities.Length) throw new ArgumentException($"Actions (length: {observedActions.Length}) and probabilities (length: {observedProbabilities.Length}) must be of equal length"); this.ProgressiveRanking = progressivePrediction.Select(a => (int)a.Action).ToArray(); var probabilitiesOrderedByRanking = progressivePrediction.Select(a => a.Score).ToArray(); this.ProgressiveProbabilities = new float[probabilitiesOrderedByRanking.Length]; for (int i = 0; i < probabilitiesOrderedByRanking.Length; i++) this.ProgressiveProbabilities[ProgressiveRanking[i]] = probabilitiesOrderedByRanking[i]; // Ranking is 0-based this.ObservedRanking = observedActions; this.ObservedProbabilities = new float[observedProbabilities.Length]; for (int i = 0; i < observedActions.Length; i++) this.ObservedProbabilities[observedActions[i] - 1] = observedProbabilities[i]; }