Initial cleanup of fuzzy logic.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
#region Copyright & License Information
|
#region Copyright & License Information
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
|
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||||
* This file is part of OpenRA, which is free software. It is made
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
* available to you under the terms of the GNU General Public License
|
* available to you under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation. For more information,
|
* as published by the Free Software Foundation. For more information,
|
||||||
@@ -10,64 +10,65 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using AI.Fuzzy.Library;
|
||||||
using System.Text;
|
|
||||||
using OpenRA.Mods.RA.Move;
|
using OpenRA.Mods.RA.Move;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
using AI.Fuzzy.Library;
|
|
||||||
|
|
||||||
namespace OpenRA.Mods.RA.AI
|
namespace OpenRA.Mods.RA.AI
|
||||||
{
|
{
|
||||||
class AttackOrFleeFuzzy
|
class AttackOrFleeFuzzy
|
||||||
{
|
{
|
||||||
protected MamdaniFuzzySystem fuzzyEngine;
|
MamdaniFuzzySystem fuzzyEngine;
|
||||||
protected Dictionary<FuzzyVariable, double> result;
|
Dictionary<FuzzyVariable, double> result;
|
||||||
|
|
||||||
public bool CanAttack
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
//not sure that this will happen (NaN), it's for the safety of
|
|
||||||
if (result[fuzzyEngine.OutputByName("AttackOrFlee")].ToString() != "NaN")
|
|
||||||
return result[fuzzyEngine.OutputByName("AttackOrFlee")] < 30.0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
|
{
|
||||||
|
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule(rule));
|
||||||
|
}
|
||||||
|
|
||||||
protected void InitializateFuzzyVariables()
|
protected void InitializateFuzzyVariables()
|
||||||
{
|
{
|
||||||
fuzzyEngine = new MamdaniFuzzySystem();
|
fuzzyEngine = new MamdaniFuzzySystem();
|
||||||
|
|
||||||
FuzzyVariable playerHealthFuzzy = new FuzzyVariable("OwnHealth", 0.0, 100.0);
|
var playerHealthFuzzy = new FuzzyVariable("OwnHealth", 0.0, 100.0);
|
||||||
playerHealthFuzzy.Terms.Add(new FuzzyTerm("NearDead", new TrapezoidMembershipFunction(0, 0, 20, 40)));
|
playerHealthFuzzy.Terms.Add(new FuzzyTerm("NearDead", new TrapezoidMembershipFunction(0, 0, 20, 40)));
|
||||||
playerHealthFuzzy.Terms.Add(new FuzzyTerm("Injured", new TrapezoidMembershipFunction(30, 50, 50, 70)));
|
playerHealthFuzzy.Terms.Add(new FuzzyTerm("Injured", new TrapezoidMembershipFunction(30, 50, 50, 70)));
|
||||||
playerHealthFuzzy.Terms.Add(new FuzzyTerm("Normal", new TrapezoidMembershipFunction(50, 80, 100, 100)));
|
playerHealthFuzzy.Terms.Add(new FuzzyTerm("Normal", new TrapezoidMembershipFunction(50, 80, 100, 100)));
|
||||||
fuzzyEngine.Input.Add(playerHealthFuzzy);
|
fuzzyEngine.Input.Add(playerHealthFuzzy);
|
||||||
|
|
||||||
FuzzyVariable enemyHealthFuzzy = new FuzzyVariable("EnemyHealth", 0.0, 100.0);
|
var enemyHealthFuzzy = new FuzzyVariable("EnemyHealth", 0.0, 100.0);
|
||||||
enemyHealthFuzzy.Terms.Add(new FuzzyTerm("NearDead", new TrapezoidMembershipFunction(0, 0, 20, 40)));
|
enemyHealthFuzzy.Terms.Add(new FuzzyTerm("NearDead", new TrapezoidMembershipFunction(0, 0, 20, 40)));
|
||||||
enemyHealthFuzzy.Terms.Add(new FuzzyTerm("Injured", new TrapezoidMembershipFunction(30, 50, 50, 70)));
|
enemyHealthFuzzy.Terms.Add(new FuzzyTerm("Injured", new TrapezoidMembershipFunction(30, 50, 50, 70)));
|
||||||
enemyHealthFuzzy.Terms.Add(new FuzzyTerm("Normal", new TrapezoidMembershipFunction(50, 80, 100, 100)));
|
enemyHealthFuzzy.Terms.Add(new FuzzyTerm("Normal", new TrapezoidMembershipFunction(50, 80, 100, 100)));
|
||||||
fuzzyEngine.Input.Add(enemyHealthFuzzy);
|
fuzzyEngine.Input.Add(enemyHealthFuzzy);
|
||||||
|
|
||||||
FuzzyVariable relativeAttackPowerFuzzy = new FuzzyVariable("RelativeAttackPower", 0.0, 1000.0);
|
var relativeAttackPowerFuzzy = new FuzzyVariable("RelativeAttackPower", 0.0, 1000.0);
|
||||||
relativeAttackPowerFuzzy.Terms.Add(new FuzzyTerm("Weak", new TrapezoidMembershipFunction(0, 0, 70, 90)));
|
relativeAttackPowerFuzzy.Terms.Add(new FuzzyTerm("Weak", new TrapezoidMembershipFunction(0, 0, 70, 90)));
|
||||||
relativeAttackPowerFuzzy.Terms.Add(new FuzzyTerm("Equal", new TrapezoidMembershipFunction(85, 100, 100, 115)));
|
relativeAttackPowerFuzzy.Terms.Add(new FuzzyTerm("Equal", new TrapezoidMembershipFunction(85, 100, 100, 115)));
|
||||||
relativeAttackPowerFuzzy.Terms.Add(new FuzzyTerm("Strong", new TrapezoidMembershipFunction(110, 150, 150, 1000)));
|
relativeAttackPowerFuzzy.Terms.Add(new FuzzyTerm("Strong", new TrapezoidMembershipFunction(110, 150, 150, 1000)));
|
||||||
fuzzyEngine.Input.Add(relativeAttackPowerFuzzy);
|
fuzzyEngine.Input.Add(relativeAttackPowerFuzzy);
|
||||||
|
|
||||||
FuzzyVariable relativeSpeedFuzzy = new FuzzyVariable("RelativeSpeed", 0.0, 1000.0);
|
var relativeSpeedFuzzy = new FuzzyVariable("RelativeSpeed", 0.0, 1000.0);
|
||||||
relativeSpeedFuzzy.Terms.Add(new FuzzyTerm("Slow", new TrapezoidMembershipFunction(0, 0, 70, 90)));
|
relativeSpeedFuzzy.Terms.Add(new FuzzyTerm("Slow", new TrapezoidMembershipFunction(0, 0, 70, 90)));
|
||||||
relativeSpeedFuzzy.Terms.Add(new FuzzyTerm("Equal", new TrapezoidMembershipFunction(85, 100, 100, 115)));
|
relativeSpeedFuzzy.Terms.Add(new FuzzyTerm("Equal", new TrapezoidMembershipFunction(85, 100, 100, 115)));
|
||||||
relativeSpeedFuzzy.Terms.Add(new FuzzyTerm("Fast", new TrapezoidMembershipFunction(110, 150, 150, 1000)));
|
relativeSpeedFuzzy.Terms.Add(new FuzzyTerm("Fast", new TrapezoidMembershipFunction(110, 150, 150, 1000)));
|
||||||
fuzzyEngine.Input.Add(relativeSpeedFuzzy);
|
fuzzyEngine.Input.Add(relativeSpeedFuzzy);
|
||||||
|
|
||||||
FuzzyVariable attackOrFleeFuzzy = new FuzzyVariable("AttackOrFlee", 0.0, 50.0);
|
var attackOrFleeFuzzy = new FuzzyVariable("AttackOrFlee", 0.0, 50.0);
|
||||||
attackOrFleeFuzzy.Terms.Add(new FuzzyTerm("Attack", new TrapezoidMembershipFunction(0, 15, 15, 30)));
|
attackOrFleeFuzzy.Terms.Add(new FuzzyTerm("Attack", new TrapezoidMembershipFunction(0, 15, 15, 30)));
|
||||||
attackOrFleeFuzzy.Terms.Add(new FuzzyTerm("Flee", new TrapezoidMembershipFunction(25, 35, 35, 50)));
|
attackOrFleeFuzzy.Terms.Add(new FuzzyTerm("Flee", new TrapezoidMembershipFunction(25, 35, 35, 50)));
|
||||||
fuzzyEngine.Output.Add(attackOrFleeFuzzy);
|
fuzzyEngine.Output.Add(attackOrFleeFuzzy);
|
||||||
@@ -79,100 +80,94 @@ namespace OpenRA.Mods.RA.AI
|
|||||||
|
|
||||||
protected virtual void AddingRulesForNormalOwnHealth()
|
protected virtual void AddingRulesForNormalOwnHealth()
|
||||||
{
|
{
|
||||||
//1 OwnHealth is Normal
|
AddFuzzyRule("if ((OwnHealth is Normal) " +
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Normal) " +
|
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
||||||
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
|
||||||
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
|
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
||||||
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
"then AttackOrFlee is Attack");
|
||||||
"then AttackOrFlee is Attack"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AddingRulesForInjuredOwnHealth()
|
protected virtual void AddingRulesForInjuredOwnHealth()
|
||||||
{
|
{
|
||||||
//OwnHealth is Injured
|
AddFuzzyRule("if ((OwnHealth is Injured) " +
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Injured) " +
|
"and (EnemyHealth is NearDead) " +
|
||||||
"and (EnemyHealth is NearDead) " +
|
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
|
||||||
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
|
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
||||||
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
"then AttackOrFlee is Attack");
|
||||||
"then AttackOrFlee is Attack"));
|
|
||||||
|
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Injured) " +
|
AddFuzzyRule("if ((OwnHealth is Injured) " +
|
||||||
"and ((EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
"and ((EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
||||||
"and ((RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
|
"and ((RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
|
||||||
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
||||||
"then AttackOrFlee is Attack"));
|
"then AttackOrFlee is Attack");
|
||||||
|
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Injured) " +
|
AddFuzzyRule("if ((OwnHealth is Injured) " +
|
||||||
"and ((EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
"and ((EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
||||||
"and (RelativeAttackPower is Weak) " +
|
"and (RelativeAttackPower is Weak) " +
|
||||||
"and (RelativeSpeed is Slow)) " +
|
"and (RelativeSpeed is Slow)) " +
|
||||||
"then AttackOrFlee is Attack"));
|
"then AttackOrFlee is Attack");
|
||||||
|
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Injured) " +
|
AddFuzzyRule("if ((OwnHealth is Injured) " +
|
||||||
"and ((EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
"and ((EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
||||||
"and (RelativeAttackPower is Weak) " +
|
"and (RelativeAttackPower is Weak) " +
|
||||||
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
||||||
"then AttackOrFlee is Flee"));
|
"then AttackOrFlee is Flee");
|
||||||
|
|
||||||
//2
|
AddFuzzyRule("if ((OwnHealth is Injured) " +
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Injured) " +
|
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
||||||
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
|
||||||
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal) or (RelativeAttackPower is Strong)) " +
|
"and (RelativeSpeed is Slow)) " +
|
||||||
"and (RelativeSpeed is Slow)) " +
|
"then AttackOrFlee is Attack");
|
||||||
"then AttackOrFlee is Attack"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AddingRulesForNearDeadOwnHealth()
|
protected virtual void AddingRulesForNearDeadOwnHealth()
|
||||||
{
|
{
|
||||||
//3 OwnHealth is NearDead
|
AddFuzzyRule("if ((OwnHealth is NearDead) " +
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is NearDead) " +
|
"and (EnemyHealth is Injured) " +
|
||||||
"and (EnemyHealth is Injured) " +
|
"and (RelativeAttackPower is Equal) " +
|
||||||
"and (RelativeAttackPower is Equal) " +
|
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal))) " +
|
||||||
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal))) " +
|
"then AttackOrFlee is Attack");
|
||||||
"then AttackOrFlee is Attack"));
|
|
||||||
//4
|
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is NearDead) " +
|
|
||||||
"and (EnemyHealth is NearDead) " +
|
|
||||||
"and (RelativeAttackPower is Weak) " +
|
|
||||||
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
|
||||||
"then AttackOrFlee is Flee"));
|
|
||||||
//5
|
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is NearDead) " +
|
|
||||||
"and (EnemyHealth is Injured) " +
|
|
||||||
"and (RelativeAttackPower is Weak) " +
|
|
||||||
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
|
||||||
"then AttackOrFlee is Flee"));
|
|
||||||
|
|
||||||
//6
|
AddFuzzyRule("if ((OwnHealth is NearDead) " +
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is NearDead) " +
|
"and (EnemyHealth is NearDead) " +
|
||||||
"and (EnemyHealth is Normal) " +
|
"and (RelativeAttackPower is Weak) " +
|
||||||
"and (RelativeAttackPower is Weak) " +
|
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
||||||
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
"then AttackOrFlee is Flee");
|
||||||
"then AttackOrFlee is Flee"));
|
|
||||||
|
|
||||||
//7
|
AddFuzzyRule("if ((OwnHealth is NearDead) " +
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if (OwnHealth is NearDead) " +
|
"and (EnemyHealth is Injured) " +
|
||||||
"and (EnemyHealth is Normal) " +
|
"and (RelativeAttackPower is Weak) " +
|
||||||
"and (RelativeAttackPower is Equal) " +
|
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
||||||
"and (RelativeSpeed is Fast) " +
|
"then AttackOrFlee is Flee");
|
||||||
"then AttackOrFlee is Flee"));
|
|
||||||
//8
|
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if (OwnHealth is NearDead) " +
|
|
||||||
"and (EnemyHealth is Normal) " +
|
|
||||||
"and (RelativeAttackPower is Strong) " +
|
|
||||||
"and (RelativeSpeed is Fast) " +
|
|
||||||
"then AttackOrFlee is Flee"));
|
|
||||||
|
|
||||||
//9
|
AddFuzzyRule("if ((OwnHealth is NearDead) " +
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if (OwnHealth is NearDead) " +
|
"and (EnemyHealth is Normal) " +
|
||||||
"and (EnemyHealth is Injured) " +
|
"and (RelativeAttackPower is Weak) " +
|
||||||
"and (RelativeAttackPower is Equal) " +
|
"and ((RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
||||||
"and (RelativeSpeed is Fast) " +
|
"then AttackOrFlee is Flee");
|
||||||
"then AttackOrFlee is Flee"));
|
|
||||||
|
AddFuzzyRule("if (OwnHealth is NearDead) " +
|
||||||
|
"and (EnemyHealth is Normal) " +
|
||||||
|
"and (RelativeAttackPower is Equal) " +
|
||||||
|
"and (RelativeSpeed is Fast) " +
|
||||||
|
"then AttackOrFlee is Flee");
|
||||||
|
|
||||||
|
AddFuzzyRule("if (OwnHealth is NearDead) " +
|
||||||
|
"and (EnemyHealth is Normal) " +
|
||||||
|
"and (RelativeAttackPower is Strong) " +
|
||||||
|
"and (RelativeSpeed is Fast) " +
|
||||||
|
"then AttackOrFlee is Flee");
|
||||||
|
|
||||||
|
AddFuzzyRule("if (OwnHealth is NearDead) " +
|
||||||
|
"and (EnemyHealth is Injured) " +
|
||||||
|
"and (RelativeAttackPower is Equal) " +
|
||||||
|
"and (RelativeSpeed is Fast) " +
|
||||||
|
"then AttackOrFlee is Flee");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalculateFuzzy(List<Actor> ownUnits, List<Actor> enemyUnits)
|
public void CalculateFuzzy(List<Actor> ownUnits, List<Actor> enemyUnits)
|
||||||
{
|
{
|
||||||
Dictionary<FuzzyVariable, double> 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));
|
||||||
inputValues.Add(fuzzyEngine.InputByName("EnemyHealth"), (double)NormalizedHealth(enemyUnits, 100));
|
inputValues.Add(fuzzyEngine.InputByName("EnemyHealth"), (double)NormalizedHealth(enemyUnits, 100));
|
||||||
inputValues.Add(fuzzyEngine.InputByName("RelativeAttackPower"), (double)RelativePower(ownUnits, enemyUnits));
|
inputValues.Add(fuzzyEngine.InputByName("RelativeAttackPower"), (double)RelativePower(ownUnits, enemyUnits));
|
||||||
@@ -183,15 +178,20 @@ namespace OpenRA.Mods.RA.AI
|
|||||||
|
|
||||||
protected float NormalizedHealth(List<Actor> actors, float normalizeByValue)
|
protected float NormalizedHealth(List<Actor> actors, float normalizeByValue)
|
||||||
{
|
{
|
||||||
int sumOfMaxHp = 0;
|
var sumOfMaxHp = 0;
|
||||||
int sumOfHp = 0;
|
var sumOfHp = 0;
|
||||||
foreach (var a in actors)
|
foreach (var a in actors)
|
||||||
|
{
|
||||||
if (a.HasTrait<Health>())
|
if (a.HasTrait<Health>())
|
||||||
{
|
{
|
||||||
sumOfMaxHp += a.Trait<Health>().MaxHP;
|
sumOfMaxHp += a.Trait<Health>().MaxHP;
|
||||||
sumOfHp += a.Trait<Health>().HP;
|
sumOfHp += a.Trait<Health>().HP;
|
||||||
}
|
}
|
||||||
if (sumOfMaxHp == 0) return 0.0f;
|
}
|
||||||
|
|
||||||
|
if (sumOfMaxHp == 0)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
return (sumOfHp * normalizeByValue) / sumOfMaxHp;
|
return (sumOfHp * normalizeByValue) / sumOfMaxHp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,33 +218,40 @@ namespace OpenRA.Mods.RA.AI
|
|||||||
{
|
{
|
||||||
if (enemy.Count == 0)
|
if (enemy.Count == 0)
|
||||||
return 999.0f;
|
return 999.0f;
|
||||||
|
|
||||||
if (own.Count == 0)
|
if (own.Count == 0)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
float relative = (relativeFunc(own, getValue) / relativeFunc(enemy, getValue)) * normalizeByValue;
|
var relative = (relativeFunc(own, getValue) / relativeFunc(enemy, getValue)) * normalizeByValue;
|
||||||
return relative.Clamp(0.0f, 999.0f);
|
return relative.Clamp(0.0f, 999.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float SumOfValues<Trait>(List<Actor> actors, Func<Actor, int> getValue)
|
protected float SumOfValues<Trait>(List<Actor> actors, Func<Actor, int> getValue)
|
||||||
{
|
{
|
||||||
int sum = 0;
|
var sum = 0;
|
||||||
foreach (var a in actors)
|
foreach (var a in actors)
|
||||||
if (a.HasTrait<Trait>())
|
if (a.HasTrait<Trait>())
|
||||||
sum += getValue(a);
|
sum += getValue(a);
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float Average<Trait>(List<Actor> actors, Func<Actor, int> getValue)
|
protected float Average<Trait>(List<Actor> actors, Func<Actor, int> getValue)
|
||||||
{
|
{
|
||||||
int sum = 0;
|
var sum = 0;
|
||||||
int countActors = 0;
|
var countActors = 0;
|
||||||
foreach (var a in actors)
|
foreach (var a in actors)
|
||||||
|
{
|
||||||
if (a.HasTrait<Trait>())
|
if (a.HasTrait<Trait>())
|
||||||
{
|
{
|
||||||
sum += getValue(a);
|
sum += getValue(a);
|
||||||
countActors++;
|
countActors++;
|
||||||
}
|
}
|
||||||
if (countActors == 0) return 0.0f;
|
}
|
||||||
|
|
||||||
|
if (countActors == 0)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
return sum / countActors;
|
return sum / countActors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#region Copyright & License Information
|
#region Copyright & License Information
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||||
* This file is part of OpenRA, which is free software. It is made
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
* available to you under the terms of the GNU General Public License
|
* available to you under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation. For more information,
|
* as published by the Free Software Foundation. For more information,
|
||||||
@@ -8,12 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using AI.Fuzzy.Library;
|
|
||||||
|
|
||||||
namespace OpenRA.Mods.RA.AI
|
namespace OpenRA.Mods.RA.AI
|
||||||
{
|
{
|
||||||
class RushFuzzy : AttackOrFleeFuzzy
|
class RushFuzzy : AttackOrFleeFuzzy
|
||||||
@@ -22,18 +16,17 @@ namespace OpenRA.Mods.RA.AI
|
|||||||
|
|
||||||
protected override void AddingRulesForNormalOwnHealth()
|
protected override void AddingRulesForNormalOwnHealth()
|
||||||
{
|
{
|
||||||
//1 OwnHealth is Normal
|
AddFuzzyRule("if ((OwnHealth is Normal) " +
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Normal) " +
|
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
||||||
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
"and (RelativeAttackPower is Strong) " +
|
||||||
"and (RelativeAttackPower is Strong) " +
|
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
||||||
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
"then AttackOrFlee is Attack");
|
||||||
"then AttackOrFlee is Attack"));
|
|
||||||
|
|
||||||
fuzzyEngine.Rules.Add(fuzzyEngine.ParseRule("if ((OwnHealth is Normal) " +
|
AddFuzzyRule("if ((OwnHealth is Normal) " +
|
||||||
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
"and ((EnemyHealth is NearDead) or (EnemyHealth is Injured) or (EnemyHealth is Normal)) " +
|
||||||
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal)) " +
|
"and ((RelativeAttackPower is Weak) or (RelativeAttackPower is Equal)) " +
|
||||||
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
"and ((RelativeSpeed is Slow) or (RelativeSpeed is Equal) or (RelativeSpeed is Fast))) " +
|
||||||
"then AttackOrFlee is Flee"));
|
"then AttackOrFlee is Flee");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user