Fast Micro AI: add a dungeon mode

This commit is contained in:
mattsc 2014-05-04 13:27:03 -07:00
parent 6cfbe69784
commit 1dd6f7494e
2 changed files with 47 additions and 5 deletions

View file

@ -161,10 +161,13 @@ function ca_fast_move:execution(ai, cfg, self)
-- Finally find the best move for this unit
local reach = wesnoth.find_reach(unit)
local pre_ratings = {}
local max_rating, best_hex = -9e99
for _,loc in ipairs(reach) do
local rating = - H.distance_between(loc[1], loc[2], next_hop[1], next_hop[2])
rating = rating - H.distance_between(loc[1], loc[2], goal.x, goal.y) / 2.
local other_rating = - H.distance_between(loc[1], loc[2], goal.x, goal.y) / 10.
rating = rating + other_rating
local unit_in_way
if (rating > max_rating) then
@ -176,17 +179,56 @@ function ca_fast_move:execution(ai, cfg, self)
if (reach:size() > 1) then
unit_in_way = nil
rating = rating - 0.01
other_rating = other_rating - 0.01
end
end
end
if (rating > max_rating) and (not unit_in_way) then
max_rating, best_hex = rating, { loc[1], loc[2] }
if (not unit_in_way) then
if cfg.dungeon_mode then
table.insert(pre_ratings, {
rating = rating,
other_rating = other_rating,
x = loc[1], y = loc[2]
})
else
if (rating > max_rating) then
max_rating, best_hex = rating, { loc[1], loc[2] }
end
end
end
end
if best_hex then
-- If this is dungeon mode, we need another level of analysis, calculating
-- the move cost from the target hex to the next hop hex, not just the distance
if cfg.dungeon_mode then
table.sort(pre_ratings, function(a,b) return (a.rating > b.rating) end)
wesnoth.extract_unit(unit)
local old_x, old_y = unit.x, unit.y
local max_rating = -9e99
for _,pre_rating in ipairs(pre_ratings) do
-- If pre_rating is worse than the full rating, we are done because the
-- move cost can never be less than the distance, so we cannot possibly do
-- better than the pre-rating
if (pre_rating.rating <= max_rating) then break end
unit.x, unit.y = pre_rating.x, pre_rating.y
local _,cost = wesnoth.find_path(unit, next_hop[1], next_hop[2])
local rating = - cost + pre_rating.other_rating
if (rating > max_rating) then
max_rating, best_hex = rating, { pre_rating.x, pre_rating.y }
end
end
unit.x, unit.y = old_x, old_y
wesnoth.put_unit(unit)
end
if best_hex then
local dx, dy = goal.x - best_hex[1], goal.y - best_hex[2]
local r = math.sqrt(dx * dx + dy * dy)
dx, dy = dx / r, dy / r

View file

@ -455,7 +455,7 @@ function wesnoth.wml_actions.micro_ai(cfg)
elseif (cfg.ai_type == 'fast_ai') then
optional_keys = {
"include_occupied_attack_hexes", "move_cost_factor",
"dungeon_mode", "include_occupied_attack_hexes", "move_cost_factor",
"weak_units_first", "skip_combat_ca", "skip_move_ca"
}
CA_parms = {