Skip to content

Commit

Permalink
Random Recruiting Micro AI: code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsc committed Apr 15, 2014
1 parent ab1a4cd commit 1928836
Showing 1 changed file with 36 additions and 37 deletions.
73 changes: 36 additions & 37 deletions data/ai/micro_ais/cas/ca_recruit_random.lua
@@ -1,6 +1,6 @@
local AH = wesnoth.require("ai/lua/ai_helper.lua")

local recruit
local recruit_type

local ca_recruit_random = {}

Expand All @@ -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
Expand All @@ -35,75 +36,73 @@ 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
end
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
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

Expand Down

0 comments on commit 1928836

Please sign in to comment.