bug修复
This commit is contained in:
parent
b1f436c113
commit
be0b509e24
@ -27,7 +27,7 @@ MonoBehaviour:
|
||||
_version: 3.33
|
||||
_category:
|
||||
_comments:
|
||||
_translation: {x: 215.61038, y: 443.87662}
|
||||
_translation: {x: 443, y: 169}
|
||||
_zoomFactor: 1
|
||||
_haltSerialization: 0
|
||||
_externalSerializationFile: {fileID: 0}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -19,6 +19,38 @@ using Vector2 = System.Numerics.Vector2;
|
||||
|
||||
namespace Logic.AI
|
||||
{
|
||||
public enum CountryAttackType
|
||||
{
|
||||
CounterattackInvasions,
|
||||
BullyWeak,
|
||||
ForcedExpansion,
|
||||
None,
|
||||
}
|
||||
|
||||
|
||||
public enum LegionStrategyType
|
||||
{
|
||||
SelfDefend,
|
||||
SelfAttack,
|
||||
CountryDefendMatch,
|
||||
CountryDefendMax,
|
||||
CountryAttackMatch,
|
||||
CountryAttackMax,
|
||||
None,
|
||||
}
|
||||
|
||||
|
||||
public enum FreeUnitStrategyType
|
||||
{
|
||||
EmergencyAvoidance1,
|
||||
EmergencyAvoidance2,
|
||||
FreeDevelopment1,
|
||||
Retreat,
|
||||
FreeDevelopment2,
|
||||
None,
|
||||
}
|
||||
|
||||
|
||||
public enum Strategy
|
||||
{
|
||||
Attack,
|
||||
@ -89,11 +121,15 @@ namespace Logic.AI
|
||||
public PlayerData Player;
|
||||
public Strategy CountryStrategy;
|
||||
public PlayerData AttackPlayer;
|
||||
public CountryAttackType AttackType;
|
||||
public PlayerData DefendTarget;
|
||||
|
||||
// 策略集合
|
||||
public Dictionary<CityData, Strategy> CityStrategy;
|
||||
public Dictionary<UnitData, Strategy> FreeUnitStrategy;
|
||||
public Dictionary<uint, Strategy> LegionStrategy;
|
||||
public Dictionary<uint, LegionStrategyType> LegionStrategyTypes;
|
||||
public Dictionary<uint, FreeUnitStrategyType> FreeUnitStrategyTypes;
|
||||
|
||||
// 玩家的军事分
|
||||
public Dictionary<uint, float> MilitaryScore;
|
||||
@ -172,6 +208,8 @@ namespace Logic.AI
|
||||
CityStrategy = new Dictionary<CityData, Strategy>();
|
||||
FreeUnitStrategy = new Dictionary<UnitData, Strategy>();
|
||||
LegionStrategy = new Dictionary<uint, Strategy>();
|
||||
LegionStrategyTypes = new Dictionary<uint, LegionStrategyType>();
|
||||
FreeUnitStrategyTypes = new Dictionary<uint, FreeUnitStrategyType>();
|
||||
AIActions = new List<AIActionBase>();
|
||||
TargetParam = new CommonActionParams();
|
||||
Marks = new HashSet<string>();
|
||||
@ -218,6 +256,10 @@ namespace Logic.AI
|
||||
{
|
||||
Map = map;
|
||||
Player = player;
|
||||
CountryStrategy = Strategy.None;
|
||||
AttackPlayer = null;
|
||||
AttackType = CountryAttackType.None;
|
||||
DefendTarget = null;
|
||||
IsFinish = false;
|
||||
|
||||
AIActions.Clear();
|
||||
@ -230,6 +272,9 @@ namespace Logic.AI
|
||||
CityStrategy.Clear();
|
||||
FreeUnitStrategy.Clear();
|
||||
LegionStrategy.Clear();
|
||||
LegionStrategyTypes.Clear();
|
||||
FreeUnitStrategyTypes.Clear();
|
||||
|
||||
MilitaryScore.Clear();
|
||||
DevelopmentScore.Clear();
|
||||
ThreatScore.Clear();
|
||||
@ -552,6 +597,8 @@ namespace Logic.AI
|
||||
public bool CalculateLegionStrategy()
|
||||
{
|
||||
LegionStrategy.Clear();
|
||||
LegionStrategyTypes.Clear();
|
||||
FreeUnitStrategyTypes.Clear();
|
||||
LegionUnits.Clear();
|
||||
FreeUnits.Clear();
|
||||
LegionScore.Clear();
|
||||
@ -652,6 +699,7 @@ namespace Logic.AI
|
||||
if (!LegionCanMoveCities[kv.Key].Contains(cityPair.Key.Id)) continue;
|
||||
LegionTargetCity[kv.Key] = cityPair.Key.Id;
|
||||
LegionStrategy[kv.Key] = Strategy.Defend;
|
||||
LegionStrategyTypes[kv.Key] = LegionStrategyType.SelfDefend;
|
||||
isFinish = true;
|
||||
break;
|
||||
}
|
||||
@ -677,6 +725,7 @@ namespace Logic.AI
|
||||
{
|
||||
LegionTargetCity[kv.Key] = targetCity.Id;
|
||||
LegionStrategy[kv.Key] = Strategy.Attack;
|
||||
LegionStrategyTypes[kv.Key] = LegionStrategyType.SelfAttack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -712,18 +761,13 @@ namespace Logic.AI
|
||||
if (LegionTargetCity.ContainsKey(result.LegionId)) continue;
|
||||
LegionTargetCity[result.LegionId] = result.CityId;
|
||||
LegionStrategy[result.LegionId] = Strategy.Defend;
|
||||
LegionStrategyTypes[result.LegionId] = LegionStrategyType.CountryDefendMatch;
|
||||
}
|
||||
|
||||
if (LegionTargetCity.Count == LegionUnits.Count) return true;
|
||||
uint targetId = 0;
|
||||
foreach (var city in selfCity)
|
||||
{
|
||||
if (targetId == 0 || CityDangerScore[city.Id] > CityDangerScore[targetId]) targetId = city.Id;
|
||||
}
|
||||
foreach (var legionId in waitLegions)
|
||||
{
|
||||
if (!LegionTargetCity.TryAdd(legionId, targetId)) continue;
|
||||
LegionStrategy[legionId] = Strategy.Defend;
|
||||
if (LegionTargetCity.ContainsKey(legionId)) continue;
|
||||
LogSystem.LogError($"军团防守存在未匹配到目标的军团 {legionId},请检查逻辑");
|
||||
}
|
||||
}
|
||||
// 国家进攻
|
||||
@ -733,12 +777,11 @@ namespace Logic.AI
|
||||
{
|
||||
foreach (var cityId in CityBorder)
|
||||
{
|
||||
if (!Map.CityMap.GetCityById(cityId, out var city)) continue;
|
||||
if (!LegionCanMoveCities[legionId].Contains(city.Id)) continue;
|
||||
if (!Map.GetGridDataByCityId(city.Id, out var cityGrid)) continue;
|
||||
var score = (2 * LegionScore[legionId] - CityDefendScore[city.Id] - CityRescueScore[city.Id]) /
|
||||
if (!LegionCanMoveCities[legionId].Contains(cityId)) continue;
|
||||
if (!Map.GetGridDataByCityId(cityId, out var cityGrid)) continue;
|
||||
var score = (2 * LegionScore[legionId] - CityDefendScore[cityId] - CityRescueScore[cityId]) /
|
||||
(Map.GridMap.CalcDistance(cityGrid, LegionGrid[legionId]) + 1);
|
||||
results.Add(new MatchResult(legionId, city.Id, score));
|
||||
results.Add(new MatchResult(legionId, cityId, score));
|
||||
}
|
||||
}
|
||||
results = results.OrderByDescending(r => r.Score).ToList();
|
||||
@ -747,20 +790,13 @@ namespace Logic.AI
|
||||
if (LegionTargetCity.ContainsKey(result.LegionId)) continue;
|
||||
LegionTargetCity[result.LegionId] = result.CityId;
|
||||
LegionStrategy[result.LegionId] = Strategy.Attack;
|
||||
LegionStrategyTypes[result.LegionId] = LegionStrategyType.CountryAttackMatch;
|
||||
}
|
||||
|
||||
if (LegionTargetCity.Count == LegionUnits.Count) return true;
|
||||
uint targetId = 0;
|
||||
foreach (var city in Map.CityMap.CityList)
|
||||
{
|
||||
if (selfCity.Contains(city)) continue;
|
||||
if (targetId == 0 || CityDefendScore[city.Id] + CityRescueScore[city.Id] <
|
||||
CityDefendScore[targetId] + CityRescueScore[targetId]) targetId = city.Id;
|
||||
}
|
||||
foreach (var legionId in waitLegions)
|
||||
{
|
||||
if (!LegionTargetCity.TryAdd(legionId, targetId)) continue;
|
||||
LegionStrategy[legionId] = Strategy.Attack;
|
||||
if (LegionTargetCity.ContainsKey(legionId)) continue;
|
||||
LogSystem.LogError($"军团进攻存在未匹配到目标的军团 {legionId},请检查逻辑");
|
||||
}
|
||||
}
|
||||
|
||||
@ -852,6 +888,7 @@ namespace Logic.AI
|
||||
if (action.CheckCan(param))
|
||||
{
|
||||
FreeUnitStrategy[unit] = Strategy.Defend;
|
||||
FreeUnitStrategyTypes[unit.Id] = FreeUnitStrategyType.EmergencyAvoidance1;
|
||||
isFinish = true;
|
||||
}
|
||||
}
|
||||
@ -868,6 +905,7 @@ namespace Logic.AI
|
||||
if (!Map.GetUnitDataByGid(aroundGrid.Id, out var cityUnit)) continue;
|
||||
if (selfUnit.Contains(cityUnit)) continue;
|
||||
FreeUnitStrategy[unit] = Strategy.Defend;
|
||||
FreeUnitStrategyTypes[unit.Id] = FreeUnitStrategyType.EmergencyAvoidance2;
|
||||
isFinish = true;
|
||||
break;
|
||||
}
|
||||
@ -876,7 +914,8 @@ namespace Logic.AI
|
||||
if (unitGrid.Resource == ResourceType.Treasure)
|
||||
{
|
||||
isFinish = true;
|
||||
FreeUnitStrategy[unit] = Strategy.Defend;
|
||||
FreeUnitStrategy[unit] = Strategy.Development;
|
||||
FreeUnitStrategyTypes[unit.Id] = FreeUnitStrategyType.FreeDevelopment1;
|
||||
}
|
||||
if (unitGrid.Resource == ResourceType.CityCenter)
|
||||
{
|
||||
@ -884,6 +923,7 @@ namespace Logic.AI
|
||||
{
|
||||
isFinish = true;
|
||||
FreeUnitStrategy[unit] = Strategy.Development;
|
||||
FreeUnitStrategyTypes[unit.Id] = FreeUnitStrategyType.FreeDevelopment1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -891,6 +931,7 @@ namespace Logic.AI
|
||||
{
|
||||
isFinish = true;
|
||||
FreeUnitStrategy[unit] = Strategy.Development;
|
||||
FreeUnitStrategyTypes[unit.Id] = FreeUnitStrategyType.FreeDevelopment1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -898,6 +939,7 @@ namespace Logic.AI
|
||||
{
|
||||
isFinish = true;
|
||||
FreeUnitStrategy[unit] = Strategy.Development;
|
||||
FreeUnitStrategyTypes[unit.Id] = FreeUnitStrategyType.FreeDevelopment1;
|
||||
}
|
||||
|
||||
if (isFinish) continue;
|
||||
@ -956,6 +998,7 @@ namespace Logic.AI
|
||||
{
|
||||
isFinish = true;
|
||||
FreeUnitStrategy[unit] = Strategy.Retreat;
|
||||
FreeUnitStrategyTypes[unit.Id] = FreeUnitStrategyType.Retreat;
|
||||
UnitTargetGrid[unit.Id] = targetGrid;
|
||||
UnitTargetCity[unit.Id] = target.Id;
|
||||
}
|
||||
@ -974,6 +1017,7 @@ namespace Logic.AI
|
||||
return false;
|
||||
}
|
||||
FreeUnitStrategy[unit] = Strategy.Development;
|
||||
FreeUnitStrategyTypes[unit.Id] = FreeUnitStrategyType.FreeDevelopment2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1294,6 +1338,7 @@ namespace Logic.AI
|
||||
if (ThreatScore[target.Id] < 10) continue;
|
||||
if (MilitaryGapScore[target.Id] > -5) continue;
|
||||
CountryStrategy = Strategy.Defend;
|
||||
DefendTarget = target;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1341,6 +1386,7 @@ namespace Logic.AI
|
||||
|
||||
CountryStrategy = Strategy.Attack;
|
||||
AttackPlayer = target;
|
||||
AttackType = CountryAttackType.CounterattackInvasions;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1351,6 +1397,7 @@ namespace Logic.AI
|
||||
if (AttackDistance[target.Id] > 5) continue;
|
||||
CountryStrategy = Strategy.Attack;
|
||||
AttackPlayer = target;
|
||||
AttackType = CountryAttackType.BullyWeak;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1381,6 +1428,7 @@ namespace Logic.AI
|
||||
if (!hasCityCenter) continue;
|
||||
CountryStrategy = Strategy.Attack;
|
||||
AttackPlayer = target;
|
||||
AttackType = CountryAttackType.ForcedExpansion;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -622,12 +622,22 @@ namespace Logic.AI
|
||||
if (type == CalculateType.UnitAttackSelfCityEnemy)
|
||||
{
|
||||
if (aiAction.Param.UnitData == null || aiAction.Param.TargetUnitData == null) return false;
|
||||
if (!aiAction.Param.MapData.GetGridDataByUnitId(aiAction.Param.UnitData.Id, out var unitGrid)) return false;
|
||||
if (!aiAction.Param.MapData.GetGridDataByUnitId(aiAction.Param.TargetUnitData.Id, out var unitGrid)) return false;
|
||||
if (!aiAction.Param.MapData.GetCityDataByGid(unitGrid.Id, out var city)) return false;
|
||||
if (!aiAction.Param.MapData.GetPlayerIdByCityId(city.Id, out var playerId)) return false;
|
||||
if (playerId != aiAction.Param.PlayerData.Id) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type == CalculateType.UnitAttackCityCenter)
|
||||
{
|
||||
if (aiAction.Param.UnitData == null || aiAction.Param.TargetUnitData == null) return false;
|
||||
if (!aiAction.Param.MapData.GetGridDataByUnitId(aiAction.Param.TargetUnitData.Id, out var unitGrid)) return false;
|
||||
if (!aiAction.Param.MapData.GetCityDataByGid(unitGrid.Id, out var city)) return false;
|
||||
if (!aiAction.Param.MapData.GetPlayerIdByCityId(city.Id, out var playerId)) return false;
|
||||
if (playerId == aiAction.Param.PlayerData.Id) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type == CalculateType.UnitAuto)
|
||||
{
|
||||
@ -706,7 +716,6 @@ namespace Logic.AI
|
||||
if (type == CalculateType.UnitMoveForTrain) CalculateLegionDefendMoveForTrain(data, param, result);
|
||||
|
||||
if (type == CalculateType.UnitRecovery) CalculateUnitRecovery(data, param, result);
|
||||
if (type == CalculateType.UnitAttackCityCenter) CalculateUnitAttackCityCenter(data, param, result);
|
||||
if (type == CalculateType.UnitExplore) CalculateExplore(data, param, result);
|
||||
if (type == CalculateType.UnitRetreat) CalculateUnitRetreat(data, param, result);
|
||||
if (type == CalculateType.UnitMoveToTargetGrid) CalculateUnitMoveToTargetGrid(data, param, result);
|
||||
@ -725,17 +734,6 @@ namespace Logic.AI
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void CalculateUnitAttackCityCenter(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData == null || param.TargetUnitData == null) return;
|
||||
if (!param.MapData.GetGridDataByUnitId(param.TargetUnitData.Id, out var unitGrid)) return;
|
||||
if (!param.MapData.GetCityDataByGid(unitGrid.Id, out var cityData)) return;
|
||||
var selfCities = param.MapData.GetCityDataSetByPlayerId(param.PlayerData.Id);
|
||||
if (!selfCities.Contains(cityData)) return;
|
||||
|
||||
result.Score[CalculateType.UnitAttackCityCenter] = 1f;
|
||||
}
|
||||
|
||||
private static void CalculateLegionDevelopmentMoveToOtherCity(AICalculatorData data, CommonActionParams param, CalculateResult result)
|
||||
{
|
||||
if (param.UnitData == null || param.TargetGridData == null) return;
|
||||
|
||||
@ -113,9 +113,15 @@ namespace Logic.Editor
|
||||
{
|
||||
if (_main?.MapData == null || _player == null) return;
|
||||
|
||||
MainEditor.Instance.GetPlayerStrategy(_player.Id, out var playerStrategy);
|
||||
MainEditor.Instance.GetPlayerStrategy(_player.Id, out var playerStrategy, out var targetId, out var attackType);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
InspectorUtils.InspectorTextWidthRich($"<b>玩家ID: {_player.Id}, 国家战略为: {playerStrategy}</b>");
|
||||
if (playerStrategy != Strategy.Attack)
|
||||
InspectorUtils.InspectorTextWidthRich($"<b>玩家ID: {_player.Id}, 国家战略为: {playerStrategy}</b>");
|
||||
else
|
||||
{
|
||||
InspectorUtils.InspectorTextWidthRich(
|
||||
$"<b>玩家ID: {_player.Id}, 国家战略为: {playerStrategy}, 目标:{targetId}, 类型:{attackType}</b>");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginVertical(_redBoxStyle);
|
||||
@ -139,10 +145,10 @@ namespace Logic.Editor
|
||||
_main.MapData.GetUnitDataListByPlayerId(_player.Id, selfUnits);
|
||||
foreach (var unit in selfUnits)
|
||||
{
|
||||
MainEditor.Instance.GetUnitStrategy(unit.Id, unit.LegionId, _player.Id, out var strategy, out var target);
|
||||
MainEditor.Instance.GetUnitStrategy(unit.Id, unit.LegionId, _player.Id, out var strategy, out var target, out var type);
|
||||
InspectorUtils.InspectorTextWidthRich(unit.LegionId == 0
|
||||
? $"<b>ID: {unit.Id}, 自由人, 策略: {strategy}, 目标城市: {target}</b>"
|
||||
: $"<b>ID: {unit.Id}, 军团ID:{unit.LegionId}, 策略: {strategy}, 目标城市: {target}</b>");
|
||||
: $"<b>ID: {unit.Id}, 军团ID:{unit.LegionId}, 策略: {strategy}, 类型:{type}, 目标城市: {target}</b>");
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
@ -17,20 +17,28 @@ namespace Logic
|
||||
public bool IsGo = false;
|
||||
public AICalculatorData Data;
|
||||
private Dictionary<uint, Strategy> _playerStrategy;
|
||||
private Dictionary<uint, CountryAttackType> _playerAttackType;
|
||||
private Dictionary<uint, uint> _playerAttackTarget;
|
||||
private Dictionary<uint, Strategy> _cityStrategy;
|
||||
private Dictionary<uint, Strategy> _unitStrategy;
|
||||
private Dictionary<uint, Strategy> _legionStrategy;
|
||||
private Dictionary<uint, LegionStrategyType> _legionStrategyTypes;
|
||||
private Dictionary<uint, FreeUnitStrategyType> _freeUnitStrategyTypes;
|
||||
private Dictionary<uint, uint> _unitTarget;
|
||||
private Dictionary<uint, List<AIActionBase>> _actionRecord;
|
||||
|
||||
|
||||
public static MainEditor Instance = new MainEditor();
|
||||
|
||||
public MainEditor()
|
||||
{
|
||||
_playerStrategy = new Dictionary<uint, Strategy>();
|
||||
_playerAttackType = new Dictionary<uint, CountryAttackType>();
|
||||
_playerAttackTarget = new Dictionary<uint, uint>();
|
||||
_cityStrategy = new Dictionary<uint, Strategy>();
|
||||
_unitStrategy = new Dictionary<uint, Strategy>();
|
||||
_legionStrategy = new Dictionary<uint, Strategy>();
|
||||
_legionStrategyTypes = new Dictionary<uint, LegionStrategyType>();
|
||||
_unitTarget = new Dictionary<uint, uint>();
|
||||
_actionRecord = new Dictionary<uint, List<AIActionBase>>();
|
||||
}
|
||||
@ -53,19 +61,28 @@ namespace Logic
|
||||
return _actionRecord.GetValueOrDefault(cid);
|
||||
}
|
||||
|
||||
public void GetPlayerStrategy(uint pid, out Strategy strategy)
|
||||
public void GetPlayerStrategy(uint pid, out Strategy strategy, out uint target, out CountryAttackType attackType)
|
||||
{
|
||||
strategy = Strategy.None;
|
||||
target = 0;
|
||||
attackType = CountryAttackType.None;
|
||||
_playerStrategy.TryGetValue(pid, out strategy);
|
||||
_playerAttackTarget.TryGetValue(pid, out target);
|
||||
_playerAttackType.TryGetValue(pid, out attackType);
|
||||
}
|
||||
|
||||
public void GetUnitStrategy(uint uid, uint legion, uint playerId, out Strategy strategy, out uint cityId)
|
||||
public void GetUnitStrategy(uint uid, uint legion, uint playerId, out Strategy strategy, out uint cityId, out LegionStrategyType type)
|
||||
{
|
||||
cityId = 0;
|
||||
strategy = Strategy.None;
|
||||
type = LegionStrategyType.None;
|
||||
_unitTarget.TryGetValue(uid, out cityId);
|
||||
if (legion == 0 && !_unitStrategy.TryGetValue(uid, out strategy))return;
|
||||
if (legion != 0 && !_legionStrategy.TryGetValue(legion * 10000 + playerId, out strategy))return;
|
||||
if (legion == 0) _unitStrategy.TryGetValue(uid, out strategy);
|
||||
else
|
||||
{
|
||||
_legionStrategy.TryGetValue(legion * 10000 + playerId, out strategy);
|
||||
_legionStrategyTypes.TryGetValue(legion * 10000 + playerId, out type);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetCityStrategy(uint cid, out Strategy strategy)
|
||||
@ -95,9 +112,13 @@ namespace Logic
|
||||
if (Data == null) return;
|
||||
if (Data.Player == null) return;
|
||||
_playerStrategy[Data.Player.Id] = Data.CountryStrategy;
|
||||
_playerAttackType[Data.Player.Id] = Data.AttackType;
|
||||
_playerAttackTarget[Data.Player.Id] = Data.AttackPlayer.Id;
|
||||
foreach (var kv in Data.CityStrategy) _cityStrategy[kv.Key.Id] = kv.Value;
|
||||
foreach (var kv in Data.FreeUnitStrategy) _unitStrategy[kv.Key.Id] = kv.Value;
|
||||
foreach (var kv in Data.LegionStrategy) _legionStrategy[kv.Key * 10000 + Data.Player.Id] = kv.Value;
|
||||
foreach (var kv in Data.LegionStrategyTypes) _legionStrategyTypes[kv.Key * 10000 + Data.Player.Id] = kv.Value;
|
||||
foreach (var kv in Data.FreeUnitStrategyTypes) _freeUnitStrategyTypes[kv.Key] = kv.Value;
|
||||
foreach (var kv in Data.UnitTargetCity) _unitTarget[kv.Key] = kv.Value;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user