Skip to content

Commit

Permalink
Wolves Micro AI: take default AI [avoid] tag into account
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsc committed Nov 2, 2018
1 parent abaa2dc commit d7418ab
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 20 deletions.
44 changes: 30 additions & 14 deletions data/ai/micro_ais/cas/ca_wolves_move.lua
Expand Up @@ -22,26 +22,42 @@ local ca_wolves_move = {}

function ca_wolves_move:evaluation(cfg)
if (not get_wolves(cfg)[1]) then return 0 end
if (not get_prey(cfg)[1]) then return 0 end

local avoid_map = AH.get_avoid_map(ai, nil, true)
local prey = get_prey(cfg)
local prey_found = false
for _,prey_unit in ipairs(prey) do
if (not avoid_map:get(prey_unit.x, prey_unit.y)) then
prey_found = true
break
end
end
if (not prey_found) then return 0 end

return cfg.ca_score
end

function ca_wolves_move:execution(cfg)
local wolves = get_wolves(cfg)
local prey = get_prey(cfg)

-- Only default AI [avoid] tag makes sense for the wolves since attacks are done by RCA AI
local avoid_map = AH.get_avoid_map(ai, nil, true)

local avoid_units = AH.get_attackable_enemies({ type = cfg.avoid_type })
local avoid_map = BC.get_attack_map(avoid_units).units
local avoid_enemies_map = BC.get_attack_map(avoid_units).units

-- Find prey that is closest to the wolves
local min_dist, target = math.huge
for _,prey_unit in ipairs(prey) do
local dist = 0
for _,wolf in ipairs(wolves) do
dist = dist + M.distance_between(wolf.x, wolf.y, prey_unit.x, prey_unit.y)
end
if (dist < min_dist) then
min_dist, target = dist, prey_unit
if (not avoid_map:get(prey_unit.x, prey_unit.y)) then
local dist = 0
for _,wolf in ipairs(wolves) do
dist = dist + M.distance_between(wolf.x, wolf.y, prey_unit.x, prey_unit.y)
end
if (dist < min_dist) then
min_dist, target = dist, prey_unit
end
end
end

Expand All @@ -61,12 +77,12 @@ function ca_wolves_move:execution(cfg)
if (height - y <= 5) then rating = rating - (6 - (height - y)) / 1.4 end

-- Hexes that avoid_type units can reach get a massive penalty
if avoid_map:get(x, y) then rating = rating - 1000 end
if avoid_enemies_map:get(x, y) then rating = rating - 1000 end

return rating
end)
end, { avoid_map = avoid_map })

local move_result = AH.movefull_stopunit(ai, wolves[1], wolf1)
local move_result = AH.movefull_stopunit(ai, wolves[1], wolf1 or { wolf1.x, wolf1.y })
-- If the wolf was ambushed, return and reconsider; also if an event removed a wolf
if (AH.is_incomplete_move(move_result)) then return end
for _,check_wolf in ipairs(wolves) do
Expand All @@ -90,12 +106,12 @@ function ca_wolves_move:execution(cfg)
rating = rating - (dist_t - dist_1t)^2

-- Hexes that avoid_type units can reach get a massive penalty
if avoid_map:get(x, y) then rating = rating - 1000 end
if avoid_enemies_map:get(x, y) then rating = rating - 1000 end

return rating
end)
end, { avoid_map = avoid_map })

local move_result = AH.movefull_stopunit(ai, wolves[i], move)
local move_result = AH.movefull_stopunit(ai, wolves[i], move or { wolves[i].x, wolves[i].y })
-- If the wolf was ambushed, return and reconsider; also if an event removed a wolf
if (AH.is_incomplete_move(move_result)) then return end
for _,check_wolf in ipairs(wolves) do
Expand Down
15 changes: 9 additions & 6 deletions data/ai/micro_ais/cas/ca_wolves_wander.lua
Expand Up @@ -21,20 +21,23 @@ end
function ca_wolves_wander:execution(cfg)
local wolves = get_wolves(cfg)

-- Only default AI [avoid] tag makes sense for the wolves
local avoid_map = AH.get_avoid_map(ai, nil, true)

-- Number of wolves that can reach each hex
local reach_map = LS.create()
for _,wolf in ipairs(wolves) do
local r = AH.get_reachable_unocc(wolf)
local r = AH.get_reachable_unocc(wolf, { avoid_map = avoid_map })
reach_map:union_merge(r, function(x, y, v1, v2) return (v1 or 0) + (v2 or 0) end)
end

local avoid_units = AH.get_attackable_enemies({ type = cfg.avoid_type })
local avoid_map = BC.get_attack_map(avoid_units).units
local avoid_enemies_map = BC.get_attack_map(avoid_units).units

local max_rating, goal_hex = - math.huge
reach_map:iter( function (x, y, v)
local rating = v + math.random(99)/100.
if avoid_map:get(x, y) then rating = rating - 1000 end
if avoid_enemies_map:get(x, y) then rating = rating - 1000 end

if (rating > max_rating) then
max_rating, goal_hex = rating, { x, y }
Expand All @@ -47,11 +50,11 @@ function ca_wolves_wander:execution(cfg)
-- For each wolf, we need to check that goal hex is reachable, and out of harm's way
local best_hex = AH.find_best_move(wolf, function(x, y)
local rating = -wesnoth.map.distance_between(x, y, goal_hex[1], goal_hex[2])
if avoid_map:get(x, y) then rating = rating - 1000 end
if avoid_enemies_map:get(x, y) then rating = rating - 1000 end
return rating
end)
end, { avoid_map = avoid_map })

local move_result = AH.movefull_stopunit(ai, wolf, best_hex)
local move_result = AH.movefull_stopunit(ai, wolf, best_hex or { wolf.x, wolf.y })
-- If the wolf was ambushed, return and reconsider; also if an event removed a wolf
if (AH.is_incomplete_move(move_result)) then return end
for _,check_wolf in ipairs(wolves) do
Expand Down

0 comments on commit d7418ab

Please sign in to comment.