AI castle_switch: reconsider CA score when using saved data
If the units previously on the keep moved off, we don't have to use the low score any more.
This commit is contained in:
parent
18b5d5159e
commit
917f7ef9a5
1 changed files with 35 additions and 23 deletions
|
@ -6,6 +6,9 @@ local M = wesnoth.map
|
|||
local CS_leader_score
|
||||
-- Note that CS_leader and CS_leader_target are also needed by the recruiting CA, so they must be stored in 'data'
|
||||
|
||||
local high_score = 195000
|
||||
local low_score = 15000
|
||||
|
||||
local function get_reachable_enemy_leaders(unit, avoid_map)
|
||||
-- We're cheating a little here and also find hidden enemy leaders. That's
|
||||
-- because a human player could make a pretty good educated guess as to where
|
||||
|
@ -27,6 +30,32 @@ local function get_reachable_enemy_leaders(unit, avoid_map)
|
|||
return enemy_leaders
|
||||
end
|
||||
|
||||
local function other_units_on_keep(leader)
|
||||
-- if we're on a keep, wait until there are no movable non-leader units on the castle before moving off
|
||||
local leader_score = high_score
|
||||
if wesnoth.get_terrain_info(wesnoth.get_terrain(leader.x, leader.y)).keep then
|
||||
local castle = AH.get_locations_no_borders {
|
||||
{ "and", {
|
||||
x = leader.x, y = leader.y, radius = 200,
|
||||
{ "filter_radius", { terrain = 'C*,K*,C*^*,K*^*,*^K*,*^C*' } }
|
||||
}}
|
||||
}
|
||||
local should_wait = false
|
||||
for i,loc in ipairs(castle) do
|
||||
local unit = wesnoth.units.get(loc[1], loc[2])
|
||||
if unit and (unit.side == wesnoth.current.side) and (not unit.canrecruit) and (unit.moves > 0) then
|
||||
should_wait = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if should_wait then
|
||||
leader_score = low_score
|
||||
end
|
||||
end
|
||||
|
||||
return leader_score
|
||||
end
|
||||
|
||||
local ca_castle_switch = {}
|
||||
|
||||
function ca_castle_switch:evaluation(cfg, data, filter_own)
|
||||
|
@ -57,6 +86,11 @@ function ca_castle_switch:evaluation(cfg, data, filter_own)
|
|||
local avoid_map = AH.get_avoid_map(ai, nil, true)
|
||||
|
||||
if data.CS_leader and wesnoth.sides[wesnoth.current.side].gold >= cheapest_unit_cost then
|
||||
-- If the saved score is the low score, check whether there are still other units on the keep
|
||||
if (CS_leader_score == low_score) then
|
||||
CS_leader_score = other_units_on_keep(data.CS_leader)
|
||||
end
|
||||
|
||||
-- make sure move is still valid
|
||||
local path, cost = AH.find_path_with_avoid(data.CS_leader, data.CS_leader_target[1], data.CS_leader_target[2], avoid_map)
|
||||
local next_hop = AH.next_hop(data.CS_leader, nil, nil, { path = path, avoid_map = avoid_map })
|
||||
|
@ -169,29 +203,7 @@ function ca_castle_switch:evaluation(cfg, data, filter_own)
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
-- if we're on a keep, wait until there are no movable non-leader units on the castle before moving off
|
||||
local leader_score = 195000
|
||||
if wesnoth.get_terrain_info(wesnoth.get_terrain(leader.x, leader.y)).keep then
|
||||
local castle = AH.get_locations_no_borders {
|
||||
{ "and", {
|
||||
x = leader.x, y = leader.y, radius = 200,
|
||||
{ "filter_radius", { terrain = 'C*,K*,C*^*,K*^*,*^K*,*^C*' } }
|
||||
}}
|
||||
}
|
||||
local should_wait = false
|
||||
for i,loc in ipairs(castle) do
|
||||
local unit = wesnoth.units.get(loc[1], loc[2])
|
||||
if unit and (unit.side == wesnoth.current.side) and (not unit.canrecruit) and (unit.moves > 0) then
|
||||
should_wait = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if should_wait then
|
||||
leader_score = 15000
|
||||
end
|
||||
end
|
||||
|
||||
local leader_score = other_units_on_keep(leader)
|
||||
best_score = best_score + leader_score
|
||||
|
||||
if (best_score > overall_best_score) then
|
||||
|
|
Loading…
Add table
Reference in a new issue