AI科技评分接入

This commit is contained in:
wuwenbo 2025-05-15 17:23:11 +08:00
parent e0da364341
commit 6e8d4560e7
7 changed files with 115 additions and 58 deletions

View File

@ -25,3 +25,64 @@ MonoBehaviour:
UnitExploreTreasureScore: 10
UnitExploreStarfishScore: 5
FutureScoreTransformValue: 0.5
TechInfoList:
- TechType: 1
Ratio: 1
- TechType: 2
Ratio: 1
- TechType: 3
Ratio: 1
- TechType: 4
Ratio: 1
- TechType: 5
Ratio: 1
- TechType: 6
Ratio: 1
- TechType: 7
Ratio: 1
- TechType: 8
Ratio: 1
- TechType: 9
Ratio: 1
- TechType: 10
Ratio: 1
- TechType: 11
Ratio: 1
- TechType: 12
Ratio: 1
- TechType: 13
Ratio: 1
- TechType: 14
Ratio: 1
- TechType: 15
Ratio: 1
- TechType: 16
Ratio: 1
- TechType: 17
Ratio: 1
- TechType: 18
Ratio: 1
- TechType: 19
Ratio: 1
- TechType: 20
Ratio: 1
- TechType: 21
Ratio: 1
- TechType: 22
Ratio: 1
- TechType: 23
Ratio: 1
- TechType: 24
Ratio: 1
- TechType: 25
Ratio: 1
- TechType: 26
Ratio: 1
- TechType: 27
Ratio: 1
- TechType: 28
Ratio: 1
- TechType: 29
Ratio: 1
- TechType: 30
Ratio: 1

View File

@ -59,6 +59,7 @@ namespace Logic.AI
if (actionType == AIActionType.Unit) GeneratorUnitActions(aiActions);
else if (actionType == AIActionType.Grid) GeneratorGridActions(aiActions);
else if (actionType == AIActionType.City) GeneratorCityActions(aiActions);
else if (actionType == AIActionType.Tech) GeneratorTechActions(aiActions);
if (aiActions.Count != 0) break;
}
}
@ -138,6 +139,23 @@ namespace Logic.AI
}
}
// 穷举科技树行动
private void GeneratorTechActions(List<AIActionBase> aiActions)
{
if (aiActions == null) aiActions = new List<AIActionBase>();
// 玩家行为
var param = new CommonActionParams(_mapData, playerData:_player, mainObjectType:MainObjectType.Player);
param.RefreshParams();
if (!ActionLogicFactory.PlayerHasAction(param, out var actions)) return;
foreach (var action in actions)
{
if (action.ActionId.ActionType != CommonActionType.LearnTech) continue;
if (param.PlayerData.PlayerWealth < action.GetCost()) continue;
aiActions.Add(new AIActionBase(param, action));
}
}
// 穷举式生成所有可能的行动
public void GeneratorActions(MapData map, PlayerData player, List<AIActionBase> aiActions = null)
{

View File

@ -41,8 +41,8 @@ namespace Logic.AI
UnitExploreTreasure,
// 小兵探索海星评分
UnitExploreStarfish,
// 未来预测收益评分
FutureScore,
// 科技评分
TechScore,
Max,
}
@ -79,7 +79,7 @@ namespace Logic.AI
private Dictionary<UnitData, float> _unitScore;
private Dictionary<CityData, float> _cityScore;
private Dictionary<CityData, float> _cityDefendScore;
public HashSet<UnitData> _unitOnCity;
private HashSet<UnitData> _unitOnCity;
private UnitTargetMap _unitTargetMap;
private List<CommonActionId> _actionList;
@ -110,22 +110,6 @@ namespace Logic.AI
var startResult = CalculateScore(mapData, player, cfg);
var maxScoreOffset = 0f;
var futureActions = new List<AIActionBase>();
// if (actionType == AIActionType.Tech)
// {
// AIActionGenerator.GeneratorFutureActions(mapData, player, futureActions);
// foreach (var aiAction in actions)
// {
// calMap.DeepCopy(mapData);
// aiAction.Param.MapData = calMap;
// aiAction.Param.RefreshParams();
// aiAction.ActionLogic.Execute(aiAction.Param);
// if (aiAction.ActionLogic.ActionId == null)continue;
// aiAction.Result = CalculateFutureScore(aiAction.Param.MapData, player);
// if (maxAction == null || aiAction.Result.GetAllScore() > 0) maxAction = aiAction;
// }
// }
foreach (var aiAction in actions)
{
calMap.DeepCopy(mapData);
@ -134,7 +118,13 @@ namespace Logic.AI
aiAction.ActionLogic.Execute(aiAction.Param);
aiAction.Result = CalculateScore(aiAction.Param.MapData, player, cfg);
// 科技类行为要计算下科技额外收益
if (IsTrueAction(aiAction)) return aiAction;
if (aiAction.ActionLogic.ActionId != null && aiAction.ActionLogic.ActionId.ActionType == CommonActionType.LearnTech)
{
CalculateTechScore(aiAction.Param.MapData, player, aiAction.Result, aiAction.ActionLogic.ActionId.TechType);
}
var scoreOffset = aiAction.Result.GetAllScore() - startResult.GetAllScore();
if (scoreOffset < 0) continue;
if (maxAction == null || scoreOffset > maxScoreOffset)
@ -541,28 +531,11 @@ namespace Logic.AI
result.ScoreDict[AICalculatorType.UnitCanMove] = score * _cfg.OneCanMoveGridMaxScore;
}
// 未来预期收益
public CalculateResult CalculateFutureScore(MapData mapData, PlayerData player)
public void CalculateTechScore(MapData mapData, PlayerData playerData, CalculateResult result, TechType techType)
{
var result = new CalculateResult();
var actions = new List<AIActionBase>();
AIActionGenerator.GeneratorFutureActions(mapData, player, actions);
if (actions.Count == 0) return result;
var calMap = mapData.GetDeepCopyMapData();
float score = 0;
foreach (var aiAction in actions)
{
calMap.DeepCopy(mapData);
aiAction.Param.MapData = calMap;
aiAction.Param.RefreshParams();
aiAction.ActionLogic.Execute(aiAction.Param);
aiAction.Result = CalculateScore(aiAction.Param.MapData, player, _cfg);
score += aiAction.Result.GetAllScore();
}
result.ScoreDict[AICalculatorType.FutureScore] = score / actions.Count * _cfg.FutureScoreTransformValue;
return result;
var ratio = _cfg.GetTechInfo(techType).Ratio;
result.ScoreDict[AICalculatorType.TechScore] = AITechScoreCalculator.CalculateTechScore(mapData, playerData, techType) * ratio;
}
}

View File

@ -44,14 +44,8 @@ namespace Logic.AI
if (techInfo.TechType != techType) continue;
return techInfo;
}
var newTechInfo = new AICalculatorTechInfo()
{
TechType = techType,
Ratio = 1
};
TechInfoList.Add(newTechInfo);
return newTechInfo;
return null;
}
}
@ -61,5 +55,11 @@ namespace Logic.AI
{
public TechType TechType;
public float Ratio;
public AICalculatorTechInfo(TechType techType, float ratio)
{
TechType = techType;
Ratio = ratio;
}
}
}

View File

@ -55,7 +55,7 @@ namespace Logic.AI
AILogicState = AILogicState.Prepare;
RecordActions = new List<AIActionBase>();
_scoreCalculator = new AIActionScoreCalculator();
_cfg = Resources.Load<AIConfigAsset>("DataAssets/AiConfig");
_cfg = Resources.Load<AIConfigAsset>("DataAssets/AIConfig");
_generator = new AIActionGenerator();
}

View File

@ -13,7 +13,7 @@ namespace Logic.AI
{
public class AITechScoreCalculator
{
public float CalculateTechScore(MapData map, PlayerData player, TechType tech)
public static float CalculateTechScore(MapData map, PlayerData player, TechType tech)
{
if (tech == TechType.Climbing)
{

View File

@ -6,6 +6,7 @@
*/
using System.Collections.Generic;
using Logic.AI;
using RuntimeData;
using UnityEditor;
@ -35,7 +36,6 @@ namespace Logic.Editor
private AIActionScoreCalculator _calculator;
private Main _main;
private CalculateResult _result;
private CalculateResult _futureResult;
private uint _curPlayerId;
private EditorType _editorType;
@ -122,12 +122,24 @@ namespace Logic.Editor
private void OnGUIEditorTechInfo()
{
EditorGUILayout.BeginHorizontal();
if (InspectorUtils.InspectorButtonWithTextWidth("初始化科技系数"))
{
_asset.TechInfoList.Clear();
for (int i = (int)TechType.Climbing; i <= (int)TechType.EgyptSakuya; i++)
{
_asset.TechInfoList.Add(new AICalculatorTechInfo((TechType)i, 1));
}
}
EditorGUILayout.EndHorizontal();
foreach (var techInfo in _asset.TechInfoList)
{
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"<b>{techInfo.TechType} 系数</b>");
techInfo.Ratio = EditorGUILayout.FloatField(techInfo.Ratio);
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
}
}
@ -220,7 +232,6 @@ namespace Logic.Editor
{
_curPlayerId = player.Id;
_result = _calculator.CalculateScore(_main.MapData, player, _asset);
_futureResult = _calculator.CalculateFutureScore(_main.MapData, player);
}
}
else
@ -229,14 +240,12 @@ namespace Logic.Editor
{
_curPlayerId = player.Id;
_result = _calculator.CalculateScore(_main.MapData, player, _asset);
_futureResult = _calculator.CalculateFutureScore(_main.MapData, player);
}
}
}
EditorGUILayout.EndHorizontal();
if (_result == null) return;
if (_futureResult == null) return;
foreach (var kv in _calculator.UnitScore)
{
if (!_main.MapData.GetPlayerIdByUnitId(kv.Key.Id, out var owner)) continue;
@ -279,10 +288,6 @@ namespace Logic.Editor
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"策略总评分: {_result.GetAllScore()}");
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
InspectorUtils.InspectorTextWidthRich($"预期总评分: {_futureResult.GetAllScore()}");
EditorGUILayout.EndHorizontal();
}
}
}