TRoW S15: add new attack and retreat AI candidate actions
The attack CA is very aggressive and almost exclusively tries to deal maximum damage, but will not execute an attack if therre's a chance of dying for the attacker. The retreat CA is the same as that used in the Experimental AI.
This commit is contained in:
parent
74929fb284
commit
99bd9dce7b
3 changed files with 162 additions and 13 deletions
|
@ -0,0 +1,67 @@
|
|||
local AH = wesnoth.require "ai/lua/ai_helper.lua"
|
||||
|
||||
local ca_aggressive_attack_no_suicide = {}
|
||||
|
||||
function ca_aggressive_attack_no_suicide:evaluation(ai, cfg, self)
|
||||
|
||||
local units = wesnoth.get_units {
|
||||
side = wesnoth.current.side,
|
||||
formula = '$this_unit.attacks_left > 0'
|
||||
}
|
||||
--print('#units', #units)
|
||||
if (not units[1]) then return 0 end
|
||||
|
||||
-- Get all possible attacks
|
||||
local attacks = AH.get_attacks(units, { include_occupied = true })
|
||||
--print('#attacks', #attacks)
|
||||
if (not attacks[1]) then return 0 end
|
||||
|
||||
-- Now find the best of the possible attacks
|
||||
local max_rating, best_attack = -9e99, {}
|
||||
for i, att in ipairs(attacks) do
|
||||
local attacker = wesnoth.get_unit(att.src.x, att.src.y)
|
||||
local defender = wesnoth.get_unit(att.target.x, att.target.y)
|
||||
|
||||
local attacker_dst = wesnoth.copy_unit(attacker)
|
||||
attacker_dst.x, attacker_dst.y = att.dst.x, att.dst.y
|
||||
|
||||
local att_stats, def_stats = wesnoth.simulate_combat(attacker_dst, defender)
|
||||
|
||||
if (att_stats.hp_chance[0] == 0) then
|
||||
local rating = def_stats.hp_chance[0] * 100
|
||||
|
||||
local attacker_damage = attacker.hitpoints - att_stats.average_hp
|
||||
local defender_damage = defender.hitpoints - def_stats.average_hp
|
||||
|
||||
rating = rating + defender_damage
|
||||
rating = rating - attacker_damage / 10.
|
||||
|
||||
-- Also, take strongest unit first
|
||||
rating = rating + attacker.hitpoints / 10.
|
||||
--print('rating:', rating, attacker.id, defender.id)
|
||||
|
||||
if (rating > max_rating) then
|
||||
max_rating = rating
|
||||
best_attack = att
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (max_rating > -9e99) then
|
||||
self.data.attack = best_attack
|
||||
return 100000
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function ca_aggressive_attack_no_suicide:execution(ai, cfg, self)
|
||||
local attacker = wesnoth.get_unit(self.data.attack.src.x, self.data.attack.src.y)
|
||||
local defender = wesnoth.get_unit(self.data.attack.target.x, self.data.attack.target.y)
|
||||
|
||||
AH.movefull_outofway_stopunit(ai, attacker, self.data.attack.dst.x, self.data.attack.dst.y)
|
||||
ai.attack(attacker, defender)
|
||||
self.data.attack = nil
|
||||
end
|
||||
|
||||
return ca_aggressive_attack_no_suicide
|
31
data/campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua
Normal file
31
data/campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua
Normal file
|
@ -0,0 +1,31 @@
|
|||
local R = wesnoth.require "ai/lua/retreat.lua"
|
||||
local AH = wesnoth.require "ai/lua/ai_helper.lua"
|
||||
|
||||
local retreat = {}
|
||||
|
||||
function retreat:evaluation(ai, cfg, self)
|
||||
|
||||
local units = wesnoth.get_units {
|
||||
side = wesnoth.current.side,
|
||||
formula = '$this_unit.moves > 0'
|
||||
}
|
||||
--print('#units', #units)
|
||||
if (not units[1]) then return 0 end
|
||||
|
||||
local unit, dst, enemy_threat = R.retreat_injured_units(units)
|
||||
|
||||
if unit then
|
||||
self.data.retreat_unit = unit
|
||||
self.data.retreat_dst = dst
|
||||
return 101000
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function retreat:execution(ai, cfg, self)
|
||||
AH.movefull_outofway_stopunit(ai, self.data.retreat_unit, self.data.retreat_dst[1], self.data.retreat_dst[2])
|
||||
self.data.retreat_unit, self.data.retreat_dst = nil, nil
|
||||
end
|
||||
|
||||
return retreat
|
|
@ -52,10 +52,27 @@
|
|||
recruit=Elvish Archer, Elvish Fighter, Elvish Scout, Elvish Shaman, Elvish Hero, Elvish Marksman, Elvish Druid
|
||||
[ai]
|
||||
{NO_SCOUTS}
|
||||
recruitment_ignore_bad_movement=yes
|
||||
recruitment_pattern=scout,fighter,archer,fighter, archer, healer
|
||||
aggression=1.0
|
||||
caution=0.0
|
||||
recruitment_pattern=fighter,archer,fighter,archer,healer
|
||||
|
||||
{MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop (
|
||||
[candidate_action]
|
||||
engine=lua
|
||||
name=retreat
|
||||
id=retreat
|
||||
max_score=101000
|
||||
location="campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua"
|
||||
[/candidate_action]
|
||||
)}
|
||||
{MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop (
|
||||
[candidate_action]
|
||||
engine=lua
|
||||
name=aggressive_attack_no_suicide
|
||||
id=aggressive_attack_no_suicide
|
||||
max_score=100000
|
||||
location="campaigns/The_Rise_Of_Wesnoth/ai/ca_aggressive_attack_no_suicide.lua"
|
||||
[/candidate_action]
|
||||
)}
|
||||
{MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop combat}
|
||||
[/ai]
|
||||
{FLAG_VARIANT wood-elvish}
|
||||
[/side]
|
||||
|
@ -79,10 +96,27 @@
|
|||
recruit=Dwarvish Fighter, Dwarvish Thunderer, Dwarvish Guardsman, Dwarvish Steelclad, Dwarvish Thunderguard
|
||||
[ai]
|
||||
{NO_SCOUTS}
|
||||
recruitment_ignore_bad_movement=yes
|
||||
recruitment_pattern=fighter,fighter,fighter,mixed fighter
|
||||
aggression=1.0
|
||||
caution=0.0
|
||||
recruitment_pattern=fighter,archer,fighter,archer,healer
|
||||
|
||||
{MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop (
|
||||
[candidate_action]
|
||||
engine=lua
|
||||
name=retreat
|
||||
id=retreat
|
||||
max_score=101000
|
||||
location="campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua"
|
||||
[/candidate_action]
|
||||
)}
|
||||
{MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop (
|
||||
[candidate_action]
|
||||
engine=lua
|
||||
name=aggressive_attack_no_suicide
|
||||
id=aggressive_attack_no_suicide
|
||||
max_score=100000
|
||||
location="campaigns/The_Rise_Of_Wesnoth/ai/ca_aggressive_attack_no_suicide.lua"
|
||||
[/candidate_action]
|
||||
)}
|
||||
{MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop combat}
|
||||
[/ai]
|
||||
{FLAG_VARIANT knalgan}
|
||||
[/side]
|
||||
|
@ -105,10 +139,27 @@
|
|||
recruit=Elvish Archer, Elvish Fighter, Elvish Scout, Elvish Shaman
|
||||
[ai]
|
||||
{NO_SCOUTS}
|
||||
recruitment_ignore_bad_movement=yes
|
||||
recruitment_pattern=scout,fighter,archer,fighter, archer, healer
|
||||
aggression=1.0
|
||||
caution=0.0
|
||||
recruitment_pattern=fighter,archer,fighter,archer,healer
|
||||
|
||||
{MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop (
|
||||
[candidate_action]
|
||||
engine=lua
|
||||
name=retreat
|
||||
id=retreat
|
||||
max_score=101000
|
||||
location="campaigns/The_Rise_Of_Wesnoth/ai/ca_retreat.lua"
|
||||
[/candidate_action]
|
||||
)}
|
||||
{MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop (
|
||||
[candidate_action]
|
||||
engine=lua
|
||||
name=aggressive_attack_no_suicide
|
||||
id=aggressive_attack_no_suicide
|
||||
max_score=100000
|
||||
location="campaigns/The_Rise_Of_Wesnoth/ai/ca_aggressive_attack_no_suicide.lua"
|
||||
[/candidate_action]
|
||||
)}
|
||||
{MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop combat}
|
||||
[/ai]
|
||||
{FLAG_VARIANT long}
|
||||
[/side]
|
||||
|
@ -465,7 +516,7 @@ _"Notes:"+"</big></span>"
|
|||
{NEW_GOLD_CARRYOVER $anl_carryover}
|
||||
next_scenario=16_The_Kalian
|
||||
[/endlevel]
|
||||
|
||||
|
||||
{CLEAR_VARIABLE anl_carryover}
|
||||
[/event]
|
||||
[/scenario]
|
||||
|
|
Loading…
Add table
Reference in a new issue