wesnoth/data/core/macros/ai.cfg
mattsc 450e3d1a48 Experimental AI: do not use village hunt CA
The algorithm used in this CA is too simple to work reliably in a general setting, it tends to send whole groups of units toward small numbers of villages, or even individual ones. In its current version, it should not be used at all, not even in the Experimental AI. The recommended way to emphasize village hunting is to set the village_value aspect to a larger-than-default value and let the move-to-targets CA take care of it.

An updated version of this CA's code is, however, left in place for potential future work as an external CA in Wesnoth 1.15.
2020-01-01 19:22:11 -08:00

620 lines
17 KiB
INI

#textdomain wesnoth
############################################################
# MODIFY_AI - ADD
############################################################
#define MODIFY_AI_ADD_ASPECT SIDE ASPECT_ID FACET_WML
# modify ai, add facet to an aspect
#
# example: {MODIFY_AI_ADD_ASPECT 1 aggression ([facet] id=always value=0.5 [/facet])}
# example: {MODIFY_AI_ADD_ASPECT 1 leader_goal ([facet] id=always [value]x=1 y=2[/value] [/facet])}
[modify_ai]
side={SIDE}
action=add
path=aspect[{ASPECT_ID}].facet
{FACET_WML}
[/modify_ai]
#enddef
#define MODIFY_AI_ADD_STAGE SIDE STAGE_WML
# modify ai, add stage
[modify_ai]
side={SIDE}
action=add
path=stage
{STAGE_WML}
[/modify_ai]
#enddef
#define MODIFY_AI_ADD_GOAL SIDE GOAL_WML
# modify ai, add goal
[modify_ai]
side={SIDE}
action=add
path=goal
{GOAL_WML}
[/modify_ai]
#enddef
#define MODIFY_AI_ADD_CANDIDATE_ACTION SIDE STAGE_ID CANDIDATE_ACTION_WML
# modify ai, add candidate action to a stage
[modify_ai]
side={SIDE}
action=add
path=stage[{STAGE_ID}].candidate_action
{CANDIDATE_ACTION_WML}
[/modify_ai]
#enddef
############################################################
# MODIFY_AI - DELETE
############################################################
#define MODIFY_AI_DELETE_ASPECT SIDE ASPECT_ID FACET_ID
# modify ai, delete facet from aspect
#
# example: {MODIFY_AI_DELETE_ASPECT 1 aggression night}
[modify_ai]
side={SIDE}
action=delete
path=aspect[{ASPECT_ID}].facet[{FACET_ID}]
[/modify_ai]
#enddef
#define MODIFY_AI_DELETE_STAGE SIDE STAGE_ID
# modify ai, delete a stage
#
# example: {MODIFY_AI_DELETE_STAGE 1 fallback}
# example: {MODIFY_AI_DELETE_STAGE 1 3}
[modify_ai]
side={SIDE}
action=delete
path=stage[{STAGE_ID}]
[/modify_ai]
#enddef
#define MODIFY_AI_DELETE_GOAL SIDE GOAL_ID
# modify ai, delete a goal
#
# example: {MODIFY_AI_DELETE_GOAL 1 kill_undead}
# example: {MODIFY_AI_DELETE_GOAL 1 0}
[modify_ai]
side={SIDE}
action=delete
path=goal[{GOAL_ID}]
[/modify_ai]
#enddef
#define MODIFY_AI_DELETE_CANDIDATE_ACTION SIDE STAGE_ID CANDIDATE_ACTION_ID
# modify ai, delete candidate action from a stage
#
# example: {MODIFY_AI_DELETE_CANDIDATE_ACTION 1 main_loop special_poisoning_formula}
# example: {MODIFY_AI_DELETE_CANDIDATE_ACTION 1 main_loop 0}
[modify_ai]
side={SIDE}
action=delete
path=stage[{STAGE_ID}].candidate_action[{CANDIDATE_ACTION_ID}]
[/modify_ai]
#enddef
############################################################
# MODIFY_AI - TRY_DELETE
############################################################
#define MODIFY_AI_TRY_DELETE_ASPECT SIDE ASPECT_ID FACET_ID
# modify ai, delete facet from aspect
#
# example: {MODIFY_AI_TRY_DELETE_ASPECT 1 aggression night}
[modify_ai]
side={SIDE}
action=try_delete
path=aspect[{ASPECT_ID}].facet[{FACET_ID}]
[/modify_ai]
#enddef
#define MODIFY_AI_TRY_DELETE_STAGE SIDE STAGE_ID
# modify ai, delete a stage
#
# example: {MODIFY_AI_TRY_DELETE_STAGE 1 fallback}
# example: {MODIFY_AI_TRY_DELETE_STAGE 1 3}
[modify_ai]
side={SIDE}
action=try_delete
path=stage[{STAGE_ID}]
[/modify_ai]
#enddef
#define MODIFY_AI_TRY_DELETE_GOAL SIDE GOAL_ID
# modify ai, delete a goal
#
# example: {MODIFY_AI_TRY_DELETE_GOAL 1 kill_undead}
# example: {MODIFY_AI_TRY_DELETE_GOAL 2 *}
# example: {MODIFY_AI_TRY_DELETE_GOAL 3 0}
[modify_ai]
side={SIDE}
action=try_delete
path=goal[{GOAL_ID}]
[/modify_ai]
#enddef
#define MODIFY_AI_TRY_DELETE_CANDIDATE_ACTION SIDE STAGE_ID CANDIDATE_ACTION_ID
# modify ai, delete candidate action from a stage
#
# example: {MODIFY_AI_TRY_DELETE_CANDIDATE_ACTION 1 main_loop special_poisoning_formula}
# example: {MODIFY_AI_TRY_DELETE_CANDIDATE_ACTION 1 main_loop 0}
[modify_ai]
side={SIDE}
action=try_delete
path=stage[{STAGE_ID}].candidate_action[{CANDIDATE_ACTION_ID}]
[/modify_ai]
#enddef
############################################################
# ASPECTS - DECLARATION
############################################################
#define AI_ASPECT ASPECT_ID FACET_WML
#macro to define a named facet of ai aspect
[aspect]
id={ASPECT_ID}
{FACET_WML}
[/aspect]
#enddef
############################################################
# ASPECTS - SIMPLE - DECLARATION (NO PREAMBLE NEEDED)
############################################################
# note: simple aspects are supposed to be used without a preamble
#define AI_SIMPLE_ASPECT ASPECT_ID FACET_ID VALUE
# simple aspect with value=VALUE
{AI_ASPECT {ASPECT_ID}
(
[facet]
id={FACET_ID}
value={VALUE}
[/facet]
)}
#enddef
#define AI_SIMPLE_ALWAYS_ASPECT ASPECT_ID VALUE
# simple aspect which is always active
{AI_SIMPLE_ASPECT {ASPECT_ID} "always" {VALUE}}
#enddef
#define AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY ASPECT_ID FACET_ID TIMEOFDAY_VALUE VALUE
# simple aspect which is active during a specified time of day
{AI_ASPECT {ASPECT_ID}
(
[facet]
id={FACET_ID}
value={VALUE}
time_of_day={TIMEOFDAY_VALUE}
[/facet]
)}
#enddef
#define AI_SIMPLE_NIGHT_ASPECT ASPECT_ID VALUE
# simple aspect which is active during the night
{AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY {ASPECT_ID} "night" "dusk,first_watch,second_watch" {VALUE} }
#enddef
#define AI_SIMPLE_DAY_ASPECT ASPECT_ID VALUE
# simple aspect which is active during the day
{AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY {ASPECT_ID} "day" "dawn,morning,afternoon" {VALUE} }
#enddef
#define AI_SIMPLE_ASPECT_VALUE ASPECT_ID FACET_ID VALUE
# simple aspect
{AI_ASPECT {ASPECT_ID}
(
[facet]
id={FACET_ID}
[value]
{VALUE}
[/value]
[/facet]
)}
#enddef
#define AI_SIMPLE_ALWAYS_ASPECT_VALUE ASPECT_ID VALUE
# simple aspect which is always active
{AI_SIMPLE_ASPECT_VALUE {ASPECT_ID} "always" {VALUE}}
#enddef
#define AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE ASPECT_ID FACET_ID TIMEOFDAY_VALUE VALUE
# simple aspect which is active during a specified time of day
{AI_ASPECT {ASPECT_ID}
(
[facet]
id={FACET_ID}
[value]
{VALUE}
[/value]
time_of_day={TIMEOFDAY_VALUE}
[/facet]
)}
#enddef
#define AI_SIMPLE_NIGHT_ASPECT_VALUE ASPECT_ID VALUE
# simple aspect which is active during the night
{AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE {ASPECT_ID} "night" "dusk,first_watch,second_watch" {VALUE} }
#enddef
#define AI_SIMPLE_DAY_ASPECT_VALUE ASPECT_ID VALUE
# simple aspect which is active during the day
{AI_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE {ASPECT_ID} "day" "dawn,morning,afternoon" {VALUE} }
#enddef
############################################################
# ASPECTS - SIMPLE - ADD (NO PREAMBLE NEEDED)
############################################################
#define MODIFY_AI_ADD_SIMPLE_ASPECT SIDE ASPECT_ID FACET_ID VALUE
# modify ai, add simple facet to an aspect
{MODIFY_AI_ADD_ASPECT {SIDE} {ASPECT_ID}
(
[facet]
id={FACET_ID}
value={VALUE}
[/facet]
)}
#enddef
#define MODIFY_AI_ADD_SIMPLE_ALWAYS_ASPECT SIDE ASPECT_ID VALUE
# modify ai, add simple aspect which is always active
{MODIFY_AI_ADD_SIMPLE_ASPECT {SIDE} {ASPECT_ID} "always" {VALUE}}
#enddef
#define MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY SIDE ASPECT_ID FACET_ID TIMEOFDAY_VALUE VALUE
# modify ai, add simple aspect which is active during a specified time of day
{MODIFY_AI_ADD_ASPECT {SIDE} {ASPECT_ID}
(
[facet]
id={FACET_ID}
value={VALUE}
time_of_day={TIMEOFDAY_VALUE}
[/facet]
)}
#enddef
#define MODIFY_AI_ADD_SIMPLE_NIGHT_ASPECT SIDE ASPECT_ID VALUE
# modify ai, add simple aspect which is active during the night
{MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY {SIDE} {ASPECT_ID} "night" "dusk,first_watch,second_watch" {VALUE} }
#enddef
#define MODIFY_AI_ADD_SIMPLE_DAY_ASPECT SIDE ASPECT_ID VALUE
# modify ai, add simple aspect which is active during the day
{MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY {SIDE} {ASPECT_ID} "day" "dawn,morning,afternoon" {VALUE} }
#enddef
#define MODIFY_AI_ADD_SIMPLE_ASPECT_VALUE SIDE ASPECT_ID FACET_ID VALUE
# modify ai, add simple facet to an aspect
{MODIFY_AI_ADD_ASPECT {SIDE} {ASPECT_ID}
(
[facet]
id={FACET_ID}
[value]
{VALUE}
[/value]
[/facet]
)}
#enddef
#define MODIFY_AI_ADD_SIMPLE_ALWAYS_ASPECT_VALUE SIDE ASPECT_ID VALUE
# modify ai, add simple aspect which is always active
{MODIFY_AI_ADD_SIMPLE_ASPECT_VALUE {SIDE} {ASPECT_ID} "always" {VALUE}}
#enddef
#define MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE SIDE ASPECT_ID FACET_ID TIMEOFDAY_VALUE VALUE
# modify ai, add simple aspect which is active during a specified time of day
{MODIFY_AI_ADD_ASPECT {SIDE} {ASPECT_ID}
(
[facet]
id={FACET_ID}
[value]
{VALUE}
[/value]
time_of_day={TIMEOFDAY_VALUE}
[/facet]
)}
#enddef
#define MODIFY_AI_ADD_SIMPLE_NIGHT_ASPECT_VALUE SIDE ASPECT_ID VALUE
# modify ai, add simple aspect which is active during the night
{MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE {SIDE} {ASPECT_ID} "night" "dusk,first_watch,second_watch" {VALUE} }
#enddef
#define MODIFY_AI_ADD_SIMPLE_DAY_ASPECT_VALUE SIDE ASPECT_ID VALUE
# modify ai, add simple aspect which is active during the day
{MODIFY_AI_ADD_SIMPLE_ASPECT_FOR_TIME_OF_DAY_VALUE {SIDE} {ASPECT_ID} "day" "dawn,morning,afternoon" {VALUE} }
#enddef
#define AI_NO_SCOUTS
# make the AI team not recruit scouts.
{AI_SIMPLE_ALWAYS_ASPECT villages_per_scout 0}
#enddef
#define AI_NEW_SYNTAX
# use stable 1.8 ai syntax
# Deprecated; no longer does anything
#enddef
#define AI_SCALE_ATTACK_DEPTH_BY_DIFFICULTY
# change attack depth depending on difficulty
#ifdef EASY
{AI_SIMPLE_ALWAYS_ASPECT attack_depth 3}
#endif
#ifdef NORMAL
{AI_SIMPLE_ALWAYS_ASPECT attack_depth 4}
#endif
#ifdef HARD
{AI_SIMPLE_ALWAYS_ASPECT attack_depth 5}
#endif
#enddef
############################################################
# RECRUITMENT ASPECTS
############################################################
#define AI_DEACTIVATE_SAVE_GOLD
# disable aspect recruitment_save_gold
[facet]
id="always"
[value]
active=0
[/value]
[/facet]
#enddef
#define AI_NO_RECRUITMENT
# disable recruitment
[facet]
id="always"
[value]
[recruit]
importance=1
number=0
[/recruit]
[/value]
[/facet]
#enddef
#define AI_SAVE_GOLD ACTIVE BEGIN END
# Enable AI recruitment gold saving.
# ACTIVE: turn from which on gold saving will be active
# BEGIN: begin gold saving when unit cost ratio rises above this value
# END: end gold saving when unit cost ratio drops below this value
# This goes directly into the [ai] tag.
[aspect]
id=recruitment_save_gold
[facet]
[value]
active={ACTIVE}
begin={BEGIN}
end={END}
[/value]
[/facet]
[/aspect]
#enddef
#define AI_SAVE_GOLD_DEFAULT
# Enable AI recruitment gold saving with values set
# to what was the default in Wesnoth 1.11.7 and 1.11.8.
# This goes directly into the [ai] tag.
{AI_SAVE_GOLD 2 1.5 1.1}
#enddef
############################################################
# NEW FORMULA_AI RECRUITMENT BY Dragonking (experimental!)
############################################################
#define AI_FORMULA_AI_EXPERIMENTAL_RECRUITMENT
[stage]
engine=fai
name=side_formulas
move="{ai/formula/new_recruitment.fai}"
[/stage]
#enddef
############################################################
# CANDIDATE_ACTIONS
############################################################
############################################################
# LEADER GOALS ( aspect[leader_goal] )
############################################################
####
# internal macro
#
#define _AI_ASPECT_LEADER_GOAL_MOVE_TO X Y AUTOREMOVE_VALUE
[facet]
id="always"
[value]
id="always"
x={X}
y={Y}
auto_remove={AUTOREMOVE_VALUE}
[/value]
[/facet]
#enddef
####
# internal macro
#
#define _AI_ASPECT_LEADER_GOAL_RISKY_MOVE_TO X Y AUTOREMOVE_VALUE
[facet]
id="always"
[value]
id="always"
x={X}
y={Y}
max_risk=10000
auto_remove={AUTOREMOVE_VALUE}
[/value]
[/facet]
#enddef
#define AI_ASPECT_LEADER_GOAL_MOVE_TO X Y
# leader goal: move to X Y and be free
{_AI_ASPECT_LEADER_GOAL_MOVE_TO {X} {Y} "yes"}
#enddef
#define AI_ASPECT_LEADER_GOAL_MOVE_TO_AND_STAY_THERE X Y
# leader goal: move to X Y and stay there
{_AI_ASPECT_LEADER_GOAL_MOVE_TO {X} {Y} "no"}
#enddef
#define CLEAR_AI_ALWAYS_ASPECT_LEADER_GOAL SIDE
# clear AI leader goal "always"
{MODIFY_AI_DELETE_ASPECT {SIDE} leader_goal always}
#enddef
#define AI_ASPECT_LEADER_GOAL_RISKY_MOVE_TO X Y
# leader goal: move to X Y and be free
{_AI_ASPECT_LEADER_GOAL_RISKY_MOVE_TO {X} {Y} "yes"}
#enddef
#define AI_ASPECT_LEADER_GOAL_RISKY_MOVE_TO_AND_STAY_THERE X Y
# leader goal: move to X Y and stay there
{_AI_ASPECT_LEADER_GOAL_RISKY_MOVE_TO {X} {Y} "no"}
#enddef
############################################################
# EXPERIMENTAL AI
############################################################
#define EXPERIMENTAL_AI
# Experimental AI with alternative recruitment, castle switching, alternative retreating,
# village grabbing, poison spreading, healer placement, village hunting and
# move-to-enemy candidate actions.
# Put this into the [side][ai] tag.
# Does not work in [modify_side][ai] or [modify_ai] at the moment.
[engine]
name="lua"
code= <<
local _,data = ...
local exp_ai = wesnoth.require("ai/lua/generic_rush_engine.lua").init(ai)
exp_ai.data = data
return exp_ai
>>
[/engine]
[stage]
id=main_loop
name=ai_default_rca::candidate_action_evaluation_loop
{AI_CA_GOTO}
#{AI_CA_RECRUITMENT}
{AI_CA_MOVE_LEADER_TO_GOALS}
{AI_CA_MOVE_LEADER_TO_KEEP}
{AI_CA_HIGH_XP_ATTACK}
{AI_CA_COMBAT}
{AI_CA_HEALING}
{AI_CA_VILLAGES}
{AI_CA_RETREAT}
{AI_CA_MOVE_TO_TARGETS}
{AI_CA_LEADER_SHARES_KEEP}
[candidate_action]
engine=lua
id=recruit_rushers
name=recruit_rushers
max_score=300000
evaluation="return (...):recruit_rushers_eval()"
execution="(...):recruit_rushers_exec()"
[/candidate_action]
[candidate_action]
engine=lua
id=castle_switch
name=castle_switch
max_score=290000
evaluation="return (...):castle_switch_eval()"
execution="(...):castle_switch_exec()"
[/candidate_action]
[candidate_action]
engine=lua
id=retreat_injured
name=retreat_injured
max_score=205000
evaluation="return (...):retreat_injured_units_eval()"
execution="(...):retreat_injured_units_exec()"
[/candidate_action]
[candidate_action]
engine=lua
id=grab_villages
name=grab_villages
max_score=200000
evaluation="return (...):grab_villages_eval()"
execution="(...):grab_villages_exec()"
[/candidate_action]
[candidate_action]
engine=lua
id=spread_poison
name=spread_poison
max_score=190000
evaluation="return (...):spread_poison_eval()"
execution="(...):spread_poison_exec()"
[/candidate_action]
[candidate_action]
engine=lua
id=place_healers
name=place_healers
max_score=95000
evaluation="return (...):place_healers_eval()"
execution="(...):place_healers_exec()"
[/candidate_action]
[candidate_action]
engine=lua
id=move_to_enemy
name=move_to_enemy
max_score=1
evaluation="return (...):move_to_enemy_eval()"
execution="(...):move_to_enemy_exec()"
[/candidate_action]
[/stage]
#enddef