Skip to content

Commit

Permalink
Lua AIs: do not use engine's 'data' variable unless necessary
Browse files Browse the repository at this point in the history
Now that all the AIs use external CAs, there is no need to use the persistent 'data' variable any more, unless information is to be exchanged between different CAs or is supposed to be persistent across save/load cycles.
  • Loading branch information
mattsc committed Sep 2, 2018
1 parent 62625fd commit 3bfd59f
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 117 deletions.
11 changes: 7 additions & 4 deletions data/ai/lua/ca_castle_switch.lua
Expand Up @@ -3,6 +3,9 @@
local AH = wesnoth.require "ai/lua/ai_helper.lua"
local M = wesnoth.map

local CS_leader_score
-- Note that leader_target is also needed by the recruiting CA, so it must be stored in 'data'

local function get_reachable_enemy_leaders(unit)
-- 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
Expand Down Expand Up @@ -51,7 +54,7 @@ function ca_castle_switch:evaluation(cfg, data)
local next_hop = AH.next_hop(leader, data.leader_target[1], data.leader_target[2])
if next_hop and next_hop[1] == data.leader_target[1]
and next_hop[2] == data.leader_target[2] then
return data.leader_score
return CS_leader_score
end
end

Expand Down Expand Up @@ -158,7 +161,7 @@ function ca_castle_switch:evaluation(cfg, data)
data.leader_target = next_hop

-- if we're on a keep, wait until there are no movable units on the castle before moving off
data.leader_score = 290000
CS_leader_score = 290000
if wesnoth.get_terrain_info(wesnoth.get_terrain(leader.x, leader.y)).keep then
local castle = wesnoth.get_locations {
x = "1-"..width, y = "1-"..height,
Expand All @@ -178,12 +181,12 @@ function ca_castle_switch:evaluation(cfg, data)
end
end
if should_wait then
data.leader_score = 15000
CS_leader_score = 15000
end
end

if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
return data.leader_score
return CS_leader_score
end

if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
Expand Down
10 changes: 6 additions & 4 deletions data/ai/lua/ca_grab_villages.lua
Expand Up @@ -4,6 +4,8 @@ local AH = wesnoth.require "ai/lua/ai_helper.lua"
local BC = wesnoth.require "ai/lua/battle_calcs.lua"
local M = wesnoth.map

local GV_unit, GV_village

local ca_grab_villages = {}

function ca_grab_villages:evaluation(cfg, data)
Expand Down Expand Up @@ -116,7 +118,7 @@ function ca_grab_villages:evaluation(cfg, data)
end

if best_village then
data.unit, data.village = best_unit, best_village
GV_unit, GV_village = best_unit, best_village
if (max_rating >= 1000) then
if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
return return_value
Expand All @@ -131,10 +133,10 @@ end

function ca_grab_villages:execution(cfg, data)
if AH.print_exec() then AH.print_ts(' Executing grab_villages CA') end
if AH.show_messages() then wesnoth.wml_actions.message { speaker = data.unit.id, message = 'Grab villages' } end
if AH.show_messages() then wesnoth.wml_actions.message { speaker = GV_unit.id, message = 'Grab villages' } end

AH.movefull_stopunit(ai, data.unit, data.village)
data.unit, data.village = nil, nil
AH.movefull_stopunit(ai, GV_unit, GV_village)
GV_unit, GV_village = nil, nil
end

return ca_grab_villages
8 changes: 5 additions & 3 deletions data/ai/lua/ca_high_xp_attack.lua
Expand Up @@ -26,6 +26,8 @@ local M = wesnoth.map
-- so that we can follow up with stronger units. In addition, use of poison or
-- slow attacks is strongly discouraged. See code for exact equations.

local XP_attack

local ca_attack_highxp = {}

function ca_attack_highxp:evaluation(cfg, data)
Expand Down Expand Up @@ -284,15 +286,15 @@ function ca_attack_highxp:evaluation(cfg, data)
end

if best_attack then
data.XP_attack = best_attack
XP_attack = best_attack
end

return max_ca_score
end

function ca_attack_highxp:execution(cfg, data)
AH.robust_move_and_attack(ai, data.XP_attack.src, data.XP_attack.dst, data.XP_attack.target, { weapon = data.XP_attack.attack_num })
data.XP_attack = nil
AH.robust_move_and_attack(ai, XP_attack.src, XP_attack.dst, XP_attack.target, { weapon = XP_attack.attack_num })
XP_attack = nil
end

return ca_attack_highxp
9 changes: 6 additions & 3 deletions data/ai/lua/ca_move_to_any_enemy.lua
Expand Up @@ -5,6 +5,8 @@

local AH = wesnoth.require "ai/lua/ai_helper.lua"

local MTAE_unit, MTAE_destination

local ca_move_to_any_enemy = {}

function ca_move_to_any_enemy:evaluation(cfg, data)
Expand Down Expand Up @@ -45,16 +47,17 @@ function ca_move_to_any_enemy:evaluation(cfg, data)
return 0
end

data.destination = destination
data.unit = unit
MTAE_destination = destination
MTAE_unit = unit

if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
return 1
end

function ca_move_to_any_enemy:execution(cfg, data)
if AH.print_exec() then AH.print_ts(' Executing move_to_any_enemy CA') end
AH.checked_move(ai, data.unit, data.destination[1], data.destination[2])
AH.checked_move(ai, MTAE_unit, MTAE_destination[1], MTAE_destination[2])
MTAE_unit, MTAE_destination = nil,nil
end

return ca_move_to_any_enemy
12 changes: 7 additions & 5 deletions data/ai/lua/ca_retreat_injured.lua
Expand Up @@ -3,6 +3,8 @@
local AH = wesnoth.require "ai/lua/ai_helper.lua"
local R = wesnoth.require "ai/lua/retreat.lua"

local retreat_unit, retreat_loc

local ca_retreat_injured = {}

function ca_retreat_injured:evaluation(cfg, data)
Expand All @@ -15,8 +17,8 @@ function ca_retreat_injured:evaluation(cfg, data)
}
local unit, loc = R.retreat_injured_units(units)
if unit then
data.retreat_unit = unit
data.retreat_loc = loc
retreat_unit = unit
retreat_loc = loc

-- First check if attacks are possible for any unit
-- If one with > 50% chance of kill is possible, set return_value to lower than combat CA
Expand All @@ -36,9 +38,9 @@ end

function ca_retreat_injured:execution(cfg, data)
if AH.print_exec() then AH.print_ts(' Executing retreat_injured CA') end
AH.robust_move_and_attack(ai, data.retreat_unit, data.retreat_loc)
data.retreat_unit = nil
data.retreat_loc = nil
AH.robust_move_and_attack(ai, retreat_unit, retreat_loc)
retreat_unit = nil
retreat_loc = nil
end

return ca_retreat_injured
10 changes: 6 additions & 4 deletions data/ai/lua/ca_spread_poison.lua
Expand Up @@ -2,6 +2,8 @@

local AH = wesnoth.require "ai/lua/ai_helper.lua"

local SP_attack

local ca_spread_poison = {}

function ca_spread_poison:evaluation(cfg, data)
Expand Down Expand Up @@ -78,7 +80,7 @@ function ca_spread_poison:evaluation(cfg, data)
end

if best_attack then
data.attack = best_attack
SP_attack = best_attack
if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end
return 190000
end
Expand All @@ -87,16 +89,16 @@ function ca_spread_poison:evaluation(cfg, data)
end

function ca_spread_poison:execution(cfg, data)
local attacker = wesnoth.get_unit(data.attack.src.x, data.attack.src.y)
local attacker = wesnoth.get_unit(SP_attack.src.x, SP_attack.src.y)
-- If several attacks have poison, this will always find the last one
local is_poisoner, poison_weapon = AH.has_weapon_special(attacker, "poison")

if AH.print_exec() then AH.print_ts(' Executing spread_poison CA') end
if AH.show_messages() then wesnoth.wml_actions.message { speaker = attacker.id, message = 'Poison attack' } end

AH.robust_move_and_attack(ai, attacker, data.attack.dst, data.attack.target, { weapon = poison_weapon })
AH.robust_move_and_attack(ai, attacker, SP_attack.dst, SP_attack.target, { weapon = poison_weapon })

data.attack = nil
SP_attack = nil
end

return ca_spread_poison
20 changes: 11 additions & 9 deletions data/ai/micro_ais/cas/ca_bottleneck_attack.lua
@@ -1,5 +1,7 @@
local AH = wesnoth.require "ai/lua/ai_helper.lua"

local BD_attacker, BD_target, BD_weapon, BD_bottleneck_attacks_done

local ca_bottleneck_attack = {}

function ca_bottleneck_attack:evaluation(cfg, data)
Expand Down Expand Up @@ -48,29 +50,29 @@ function ca_bottleneck_attack:evaluation(cfg, data)

if (not best_attacker) then
-- In this case we take attacks away from all units
data.BD_bottleneck_attacks_done = true
BD_bottleneck_attacks_done = true
else
data.BD_bottleneck_attacks_done = false
data.BD_attacker = best_attacker
data.BD_target = best_target
data.BD_weapon = best_weapon
BD_bottleneck_attacks_done = false
BD_attacker = best_attacker
BD_target = best_target
BD_weapon = best_weapon
end

return cfg.ca_score
end

function ca_bottleneck_attack:execution(cfg, data)
if data.BD_bottleneck_attacks_done then
if BD_bottleneck_attacks_done then
local units = AH.get_units_with_attacks { side = wesnoth.current.side }
for _,unit in ipairs(units) do
AH.checked_stopunit_attacks(ai, unit)
end
else
AH.checked_attack(ai, data.BD_attacker, data.BD_target, data.BD_weapon)
AH.checked_attack(ai, BD_attacker, BD_target, BD_weapon)
end

data.BD_attacker, data.BD_target, data.BD_weapon = nil, nil, nil
data.BD_bottleneck_attacks_done = nil
BD_attacker, BD_target, BD_weapon = nil, nil, nil
BD_bottleneck_attacks_done = nil
end

return ca_bottleneck_attack

0 comments on commit 3bfd59f

Please sign in to comment.