feat: GeneralAI 디버그 상태 추가 및 예약 턴 핸들러에 AI 상태 전달 기능 구현
This commit is contained in:
@@ -141,6 +141,28 @@ export interface GeneralAIOptions {
|
||||
nationFallback: GeneralActionDefinition;
|
||||
}
|
||||
|
||||
export type GeneralAiDebugState = {
|
||||
generalId: number;
|
||||
nationId: number | null;
|
||||
cityId: number | null;
|
||||
yearMonth: number;
|
||||
startYear: number;
|
||||
startYearMonth: number;
|
||||
dipState: number;
|
||||
attackable: boolean;
|
||||
warTargetNation: Record<number, number>;
|
||||
genType: number;
|
||||
lastAttackable: number;
|
||||
frontCities: Array<{ id: number; frontState: number; supplyState: number }>;
|
||||
supplyCities: Array<{ id: number; frontState: number; supplyState: number }>;
|
||||
policy: {
|
||||
minAvailableRecruitPop: number;
|
||||
minNpcWarLeadership: number;
|
||||
minWarCrew: number;
|
||||
cureThreshold: number;
|
||||
};
|
||||
};
|
||||
|
||||
export class GeneralAI {
|
||||
public readonly general: TurnGeneral;
|
||||
public readonly city?: City;
|
||||
@@ -423,6 +445,45 @@ export class GeneralAI {
|
||||
return neutral ?? this.buildGeneralCandidate(ACTION_REST, {}, 'neutral');
|
||||
}
|
||||
|
||||
getDebugState(): GeneralAiDebugState {
|
||||
this.updateInstance();
|
||||
this.categorizeNationCities();
|
||||
const yearMonth = joinYearMonth(this.world.currentYear, this.world.currentMonth);
|
||||
const startYearMonth = joinYearMonth(this.startYear + 2, 5);
|
||||
const meta = asRecord(this.nation?.meta ?? {});
|
||||
const lastAttackable = readMetaNumber(meta, 'last_attackable', 0);
|
||||
|
||||
return {
|
||||
generalId: this.general.id,
|
||||
nationId: this.nation?.id ?? null,
|
||||
cityId: this.city?.id ?? null,
|
||||
yearMonth,
|
||||
startYear: this.startYear,
|
||||
startYearMonth,
|
||||
dipState: this.dipState,
|
||||
attackable: this.attackable,
|
||||
warTargetNation: { ...this.warTargetNation },
|
||||
genType: this.genType,
|
||||
lastAttackable,
|
||||
frontCities: Object.values(this.frontCities).map((city) => ({
|
||||
id: city.id,
|
||||
frontState: city.frontState,
|
||||
supplyState: city.supplyState,
|
||||
})),
|
||||
supplyCities: Object.values(this.supplyCities).map((city) => ({
|
||||
id: city.id,
|
||||
frontState: city.frontState,
|
||||
supplyState: city.supplyState,
|
||||
})),
|
||||
policy: {
|
||||
minAvailableRecruitPop: this.aiConst.minAvailableRecruitPop,
|
||||
minNpcWarLeadership: this.nationPolicy.minNpcWarLeadership,
|
||||
minWarCrew: this.nationPolicy.minWarCrew,
|
||||
cureThreshold: this.nationPolicy.cureThreshold,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
buildGeneralCandidate(action: string, args: Record<string, unknown>, reason: string): AiCommandCandidate | null {
|
||||
return this.buildCandidate(this.generalDefinitions, this.generalFallback, action, args, reason);
|
||||
}
|
||||
|
||||
@@ -394,6 +394,7 @@ export const createReservedTurnHandler = async (options: {
|
||||
actionKey: string;
|
||||
usedFallback: boolean;
|
||||
blockedReason?: string;
|
||||
aiState?: ReturnType<GeneralAI['getDebugState']>;
|
||||
}) => void;
|
||||
}): Promise<GeneralTurnHandler> => {
|
||||
const env = buildCommandEnv(options.scenarioConfig, options.unitSet);
|
||||
@@ -709,6 +710,7 @@ export const createReservedTurnHandler = async (options: {
|
||||
currentGeneral.officerLevel,
|
||||
0
|
||||
);
|
||||
let nationAiState: ReturnType<GeneralAI['getDebugState']> | undefined;
|
||||
if (worldView && shouldUseAi(currentGeneral, context.world)) {
|
||||
const ai = new GeneralAI({
|
||||
general: currentGeneral,
|
||||
@@ -731,6 +733,7 @@ export const createReservedTurnHandler = async (options: {
|
||||
if (candidate) {
|
||||
nationCommand = { action: candidate.action, args: candidate.args };
|
||||
}
|
||||
nationAiState = ai.getDebugState();
|
||||
}
|
||||
const nationResult = runAction(nationDefinitions, nationFallback, nationCommand, false);
|
||||
options.onActionResolved?.({
|
||||
@@ -741,11 +744,13 @@ export const createReservedTurnHandler = async (options: {
|
||||
actionKey: nationResult.actionKey,
|
||||
usedFallback: nationResult.usedFallback,
|
||||
...(nationResult.blockedReason ? { blockedReason: nationResult.blockedReason } : {}),
|
||||
...(nationAiState ? { aiState: nationAiState } : {}),
|
||||
});
|
||||
options.reservedTurns.shiftNationTurns(currentNation.id, currentGeneral.officerLevel, -1);
|
||||
}
|
||||
|
||||
let generalCommand = options.reservedTurns.getGeneralTurn(currentGeneral.id, 0);
|
||||
let generalAiState: ReturnType<GeneralAI['getDebugState']> | undefined;
|
||||
if (worldView && shouldUseAi(currentGeneral, context.world)) {
|
||||
const ai = new GeneralAI({
|
||||
general: currentGeneral,
|
||||
@@ -768,6 +773,7 @@ export const createReservedTurnHandler = async (options: {
|
||||
if (candidate) {
|
||||
generalCommand = { action: candidate.action, args: candidate.args };
|
||||
}
|
||||
generalAiState = ai.getDebugState();
|
||||
}
|
||||
const generalResult = runAction(generalDefinitions, generalFallback, generalCommand, true);
|
||||
options.onActionResolved?.({
|
||||
@@ -778,6 +784,7 @@ export const createReservedTurnHandler = async (options: {
|
||||
actionKey: generalResult.actionKey,
|
||||
usedFallback: generalResult.usedFallback,
|
||||
...(generalResult.blockedReason ? { blockedReason: generalResult.blockedReason } : {}),
|
||||
...(generalAiState ? { aiState: generalAiState } : {}),
|
||||
});
|
||||
const nextTurnAt = generalResult.nextTurnAt;
|
||||
options.reservedTurns.shiftGeneralTurns(currentGeneral.id, -1);
|
||||
|
||||
Reference in New Issue
Block a user