wesnoth/data/ai/lua/ca_village_hunt.lua
Pentarctagon 370d03ccb7 Fix luacheck warnings and add to CI.
Note the `exclude_files` in .luacheckrc should be deleted once the eventual Ubuntu 22.04 base image has an updated luacheck that supports lua 5.4.
2021-11-28 14:26:02 -06:00

100 lines
3.3 KiB
Lua

------- Village Hunt CA --------------
-- Give extra priority to seeking villages if we have less than our share.
-- Our share is defined as being slightly more than the total/the number of sides,
-- but only in the area not prohibited by an [avoid] directive.
local AH = wesnoth.require "ai/lua/ai_helper.lua"
local LS = wesnoth.require "location_set"
local VH_unit, VH_dst = {}, {}
local ca_village_hunt = {}
function ca_village_hunt:evaluation(cfg, data, filter_own)
local start_time, ca_name = wesnoth.ms_since_init() / 1000., 'village_hunt'
if AH.print_eval() then AH.print_ts(' - Evaluating village_hunt CA:') end
local avoid_map1 = LS.of_pairs(ai.aspects.avoid)
local all_villages, villages = wesnoth.map.find{gives_income = true}, {}
for _,village in ipairs(all_villages) do
if (not avoid_map1:get(village[1], village[2])) then
table.insert(villages, village)
end
end
if (not villages[1]) then
if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
return 0
end
local n_my_villages, n_allied_villages = 0, 0
for _,village in ipairs(villages) do
local owner = wesnoth.map.get_owner(village) or -1
if (owner == wesnoth.current.side) then
n_my_villages = n_my_villages + 1
end
if (owner ~= -1) and (not wesnoth.sides.is_enemy(owner, wesnoth.current.side)) then
n_allied_villages = n_allied_villages + 1
end
end
if (n_my_villages > #villages / #wesnoth.sides) then
if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
return 0
end
if (n_allied_villages == #villages) then
if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
return 0
end
local units = AH.get_units_with_moves({
side = wesnoth.current.side,
canrecruit = 'no',
{ "and", filter_own }
}, true)
if (not units[1]) then
if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
return 0
end
local avoid_map2 = AH.get_avoid_map(ai, nil, true)
VH_unit = nil
for _,unit in ipairs(units) do
local best_cost = AH.no_path
for i,v in ipairs(villages) do
if not wesnoth.map.matches(v, { {"filter_owner", { {"ally_of", { side = wesnoth.current.side }} }} }) then
local path, cost = AH.find_path_with_avoid(unit, v[1], v[2], avoid_map2)
if (cost < best_cost) then
local dst = AH.next_hop(unit, nil, nil, { path = path, avoid_map = avoid_map2 })
if (dst[1] ~= unit.x) or (dst[2] ~= unit.y) then
best_cost = cost
VH_unit = unit
VH_dst = dst
end
end
end
end
end
if (not VH_unit) then
if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
return 0
end
if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
return 30000
end
function ca_village_hunt:execution(cfg, data, filter_own)
if AH.print_exec() then AH.print_ts(' Executing village_hunt CA') end
AH.robust_move_and_attack(ai, VH_unit, VH_dst)
VH_unit, VH_dst = nil, nil
end
return ca_village_hunt