Wolves Micro AI: take default AI [avoid] tag into account
This commit is contained in:
parent
abaa2dcc84
commit
d7418ab8e2
2 changed files with 39 additions and 20 deletions
|
@ -22,7 +22,18 @@ 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
|
||||
|
||||
|
@ -30,18 +41,23 @@ 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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue