Random Recruiting Micro AI: code cleanup
This commit is contained in:
parent
6532fdbb4b
commit
85b36fd32f
1 changed files with 36 additions and 37 deletions
|
@ -1,6 +1,6 @@
|
|||
local AH = wesnoth.require("ai/lua/ai_helper.lua")
|
||||
|
||||
local recruit
|
||||
local recruit_type
|
||||
|
||||
local ca_recruit_random = {}
|
||||
|
||||
|
@ -21,12 +21,13 @@ function ca_recruit_random:evaluation(ai, cfg)
|
|||
{ "and", {
|
||||
x = leader.x, y = leader.y, radius = 200,
|
||||
{ "filter_radius", { terrain = 'C*,K*,C*^*,K*^*,*^K*,*^C*' } }
|
||||
}}
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
local no_space = true
|
||||
for i,c in ipairs(castle.locs) do
|
||||
local unit = wesnoth.get_unit(c[1], c[2])
|
||||
for _,loc in ipairs(castle.locs) do
|
||||
local unit = wesnoth.get_unit(loc[1], loc[2])
|
||||
if (not unit) then
|
||||
no_space = false
|
||||
break
|
||||
|
@ -35,17 +36,18 @@ function ca_recruit_random:evaluation(ai, cfg)
|
|||
if no_space then return 0 end
|
||||
|
||||
-- Set up the probability array
|
||||
local prob, prob_sum = {}, 0
|
||||
local probabilities, probability_sum = {}, 0
|
||||
|
||||
-- Go through all the types listed in [probability] tags (which can be comma-separated lists)
|
||||
for i,tmp in ipairs(cfg.type) do
|
||||
tmp = AH.split(tmp, ",")
|
||||
for j,t in ipairs(tmp) do
|
||||
-- Types and probabilities are put into cfg.type and cfg.prob arrays by micro_ai_wml_tag.lua
|
||||
for ind,types in ipairs(cfg.type) do
|
||||
types = AH.split(types, ",")
|
||||
for _,typ in ipairs(types) do -- 'type' is a reserved keyword in Lua
|
||||
-- If this type is in the recruit list, add it
|
||||
for k,r in ipairs(wesnoth.sides[wesnoth.current.side].recruit) do
|
||||
if (r == t) then
|
||||
prob[t] = { value = cfg.prob[i] }
|
||||
prob_sum = prob_sum + cfg.prob[i]
|
||||
for _,recruit in ipairs(wesnoth.sides[wesnoth.current.side].recruit) do
|
||||
if (recruit == typ) then
|
||||
probabilities[typ] = { value = cfg.prob[ind] }
|
||||
probability_sum = probability_sum + cfg.prob[ind]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
@ -53,48 +55,45 @@ function ca_recruit_random:evaluation(ai, cfg)
|
|||
end
|
||||
|
||||
-- Now we add in all the unit types not listed in [probability] tags
|
||||
for i,r in ipairs(wesnoth.sides[wesnoth.current.side].recruit) do
|
||||
if (not prob[r]) then
|
||||
prob[r] = { value = 1 }
|
||||
prob_sum =prob_sum + 1
|
||||
for _,recruit in ipairs(wesnoth.sides[wesnoth.current.side].recruit) do
|
||||
if (not probabilities[recruit]) then
|
||||
probabilities[recruit] = { value = 1 }
|
||||
probability_sum = probability_sum + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Now eliminate all those that are too expensive (unless cfg.skip_low_gold_recruiting is set)
|
||||
if cfg.skip_low_gold_recruiting then
|
||||
for typ,pr in pairs(prob) do
|
||||
for typ,probability in pairs(probabilities) do -- 'type' is a reserved keyword in Lua
|
||||
if (wesnoth.unit_types[typ].cost > wesnoth.sides[wesnoth.current.side].gold) then
|
||||
--print('Eliminating:', typ)
|
||||
prob_sum = prob_sum - pr.value
|
||||
prob[typ] = nil
|
||||
probability_sum = probability_sum - probability.value
|
||||
probabilities[typ] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Now set up the min/max values for each type
|
||||
-- This needs to be done manually as the order of pairs() is not guaranteed
|
||||
local cum_prob, n_recruits = 0, 0
|
||||
for typ,pr in pairs(prob) do
|
||||
prob[typ].p_i = cum_prob
|
||||
cum_prob = cum_prob + pr.value / prob_sum * 1e6
|
||||
prob[typ].p_f = cum_prob
|
||||
n_recruits = n_recruits + 1
|
||||
-- Now set up the cumulative probability values for each type
|
||||
-- Both min and max need to be set as the order of pairs() is not guaranteed
|
||||
local cum_prob = 0
|
||||
for typ,probability in pairs(probabilities) do
|
||||
probabilities[typ].p_i = cum_prob
|
||||
cum_prob = cum_prob + probability.value
|
||||
probabilities[typ].p_f = cum_prob
|
||||
end
|
||||
|
||||
-- Now we're ready to pick on of those
|
||||
-- We always call the exec function, no matter if the selected unit is affordable
|
||||
-- The point is that this will blacklist the CA if an unaffordable recruit was
|
||||
-- chosen -> no cheaper recruits will be selected in subsequent calls
|
||||
if (n_recruits > 0) then
|
||||
local rand_prob = math.random(1e6)
|
||||
for typ,pr in pairs(prob) do
|
||||
if (pr.p_i <= rand_prob) and (rand_prob < pr.p_f) then
|
||||
recruit = typ
|
||||
if (cum_prob > 0) then
|
||||
local rand_prob = math.random(cum_prob)
|
||||
for typ,probability in pairs(probabilities) do
|
||||
if (probability.p_i < rand_prob) and (rand_prob <= probability.p_f) then
|
||||
recruit_type = typ
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
recruit = wesnoth.sides[wesnoth.current.side].recruit[1]
|
||||
recruit_type = wesnoth.sides[wesnoth.current.side].recruit[1]
|
||||
end
|
||||
|
||||
return cfg.ca_score
|
||||
|
@ -102,8 +101,8 @@ end
|
|||
|
||||
function ca_recruit_random:execution(ai, cfg)
|
||||
-- Let this function blacklist itself if the chosen recruit is too expensive
|
||||
if wesnoth.unit_types[recruit].cost <= wesnoth.sides[wesnoth.current.side].gold then
|
||||
AH.checked_recruit(ai, recruit)
|
||||
if wesnoth.unit_types[recruit_type].cost <= wesnoth.sides[wesnoth.current.side].gold then
|
||||
AH.checked_recruit(ai, recruit_type)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue