Merge CalculateFuzzy and CanAttack.

This commit is contained in:
Paul Chote
2013-08-24 11:19:47 +12:00
parent f6730a6740
commit 7bcdf7d74b
3 changed files with 11 additions and 26 deletions

View File

@@ -20,22 +20,12 @@ namespace OpenRA.Mods.RA.AI
class AttackOrFleeFuzzy class AttackOrFleeFuzzy
{ {
MamdaniFuzzySystem fuzzyEngine; MamdaniFuzzySystem fuzzyEngine;
Dictionary<FuzzyVariable, double> result;
public AttackOrFleeFuzzy() public AttackOrFleeFuzzy()
{ {
InitializateFuzzyVariables(); InitializateFuzzyVariables();
} }
public bool CanAttack
{
get
{
var attackChance = result[fuzzyEngine.OutputByName("AttackOrFlee")];
return !double.IsNaN(attackChance) && attackChance < 30.0;
}
}
protected void AddFuzzyRule(string rule) protected void AddFuzzyRule(string rule)
{ {
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule(rule)); fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule(rule));
@@ -166,7 +156,7 @@ namespace OpenRA.Mods.RA.AI
"then AttackOrFlee is Flee"); "then AttackOrFlee is Flee");
} }
public void CalculateFuzzy(IEnumerable<Actor> ownUnits, IEnumerable<Actor> enemyUnits) public bool CanAttack(IEnumerable<Actor> ownUnits, IEnumerable<Actor> enemyUnits)
{ {
var inputValues = new Dictionary<FuzzyVariable, double>(); var inputValues = new Dictionary<FuzzyVariable, double>();
inputValues.Add(fuzzyEngine.InputByName("OwnHealth"), (double)NormalizedHealth(ownUnits, 100)); inputValues.Add(fuzzyEngine.InputByName("OwnHealth"), (double)NormalizedHealth(ownUnits, 100));
@@ -174,7 +164,9 @@ namespace OpenRA.Mods.RA.AI
inputValues.Add(fuzzyEngine.InputByName("RelativeAttackPower"), (double)RelativePower(ownUnits, enemyUnits)); inputValues.Add(fuzzyEngine.InputByName("RelativeAttackPower"), (double)RelativePower(ownUnits, enemyUnits));
inputValues.Add(fuzzyEngine.InputByName("RelativeSpeed"), (double)RelativeSpeed(ownUnits, enemyUnits)); inputValues.Add(fuzzyEngine.InputByName("RelativeSpeed"), (double)RelativeSpeed(ownUnits, enemyUnits));
result = fuzzyEngine.Calculate(inputValues); var result = fuzzyEngine.Calculate(inputValues);
var attackChance = result[fuzzyEngine.OutputByName("AttackOrFlee")];
return !double.IsNaN(attackChance) && attackChance < 30.0;
} }
protected float NormalizedHealth(IEnumerable<Actor> actors, float normalizeByValue) protected float NormalizedHealth(IEnumerable<Actor> actors, float normalizeByValue)

View File

@@ -622,8 +622,7 @@ namespace OpenRA.Mods.RA.AI
var enemys = world.FindActorsInCircle(b.CenterPosition, WRange.FromCells(15)) var enemys = world.FindActorsInCircle(b.CenterPosition, WRange.FromCells(15))
.Where(unit => p.Stances[unit.Owner] == Stance.Enemy && unit.HasTrait<AttackBase>()).ToList(); .Where(unit => p.Stances[unit.Owner] == Stance.Enemy && unit.HasTrait<AttackBase>()).ToList();
rushFuzzy.CalculateFuzzy(ownUnits, enemys); if (rushFuzzy.CanAttack(ownUnits, enemys))
if (rushFuzzy.CanAttack)
{ {
var target = enemys.Any() ? enemys.Random(random) : b; var target = enemys.Any() ? enemys.Random(random) : b;
var rush = GetSquadOfType(SquadType.Rush); var rush = GetSquadOfType(SquadType.Rush);

View File

@@ -18,14 +18,8 @@ namespace OpenRA.Mods.RA.AI
{ {
protected virtual bool MayBeFlee(Squad owner) protected virtual bool MayBeFlee(Squad owner)
{ {
return base.MayBeFlee(owner, (enemyAroundUnit) => return base.MayBeFlee(owner, enemyAroundUnit =>
{ !owner.attackOrFleeFuzzy.CanAttack(owner.units, enemyAroundUnit));
owner.attackOrFleeFuzzy.CalculateFuzzy(owner.units, enemyAroundUnit);
if (!owner.attackOrFleeFuzzy.CanAttack)
return true;
return false;
});
} }
} }
@@ -47,14 +41,14 @@ namespace OpenRA.Mods.RA.AI
var enemyUnits = owner.world.FindActorsInCircle(owner.Target.CenterPosition, WRange.FromCells(10)) var enemyUnits = owner.world.FindActorsInCircle(owner.Target.CenterPosition, WRange.FromCells(10))
.Where(unit => owner.bot.p.Stances[unit.Owner] == Stance.Enemy).ToList(); .Where(unit => owner.bot.p.Stances[unit.Owner] == Stance.Enemy).ToList();
if (enemyUnits.Any())
if (enemyUnits.Any())
{ {
owner.attackOrFleeFuzzy.CalculateFuzzy(owner.units, enemyUnits); if (owner.attackOrFleeFuzzy.CanAttack(owner.units, enemyUnits))
if (owner.attackOrFleeFuzzy.CanAttack)
{ {
foreach(var u in owner.units) foreach (var u in owner.units)
owner.world.IssueOrder(new Order("AttackMove", u, false) { TargetLocation = owner.Target.CenterPosition.ToCPos() }); owner.world.IssueOrder(new Order("AttackMove", u, false) { TargetLocation = owner.Target.CenterPosition.ToCPos() });
// We have gathered sufficient units. Attack the nearest enemy unit. // We have gathered sufficient units. Attack the nearest enemy unit.
owner.fsm.ChangeState(owner, new GroundUnitsAttackMoveState(), true); owner.fsm.ChangeState(owner, new GroundUnitsAttackMoveState(), true);
return; return;