Merge branch 'master' of github.com:wesnoth/wesnoth-old

This commit is contained in:
Alexander van Gessel 2013-10-28 01:11:48 +01:00
commit 87305c472b
5 changed files with 192 additions and 213 deletions

View File

@ -0,0 +1,179 @@
local H = wesnoth.require "lua/helper.lua"
local LS = wesnoth.require "lua/location_set.lua"
local ca_transport = {}
-- Move transport ships according to these rules:
-- 1. If transport can get to its designated landing site this move, find
-- close hex with the most unoccupied adjacent non-water hexes and move there
-- 2. If landing site is out of reach, move toward destination while
-- staying in deep water surrounded by deep water only
function ca_transport:evaluation(ai)
local units = wesnoth.get_units {
side = wesnoth.current.side,
formula = '$this_unit.moves > 0',
}
for i,u in ipairs(units) do
local vars = H.get_child(u.__cfg, "variables")
if vars.destination_x and vars.destination_y then
return 300000
end
end
return 0
end
function ca_transport:execution(ai)
local units = wesnoth.get_units {}
-- Need all transport units plus maps of all units, all transport units and
-- all other units (as those block hexes accessible to transport units)
local transports = {}
local unit_map, transport_map, blocked_hex_map = LS.create(), LS.create(), LS.create()
for i,u in ipairs(units) do
unit_map:insert(u.x, u.y)
if (u.side == wesnoth.current.side) and (u.moves > 0)
and u.variables.destination_x and u.variables.destination_x
then
transport_map:insert(u.x, u.y)
table.insert(transports, u)
--print("----> Inserting " .. u.id, u.x, u.y, u.variables.destination_x, u.variables.destination_y)
else
blocked_hex_map:insert(u.x, u.y)
end
end
-- First see if a transport is within landing distance
local landing_site_map = LS.of_pairs(
wesnoth.get_locations {
terrain = 'W*',
{ "filter_adjacent_location", { terrain = '!, W*' } }
}
)
local max_rating, best_unit, best_hex, best_adj_tiles = -9e99
for i,u in ipairs(transports) do
local dst = { u.variables.destination_x, u.variables.destination_y }
if (not u.variables.landed) and (H.distance_between(u.x, u.y, dst[1], dst[2]) <= u.moves) then
local reach = wesnoth.find_reach(u)
for i,r in ipairs(reach) do
if landing_site_map:get(r[1], r[2]) and (not unit_map:get(r[1], r[2]))
then
-- Distance from destination is minor rating
local rating = -H.distance_between(r[1], r[2], dst[1], dst[2]) / 100.
-- Main rating is number of unoccupied land hexes and
-- water hexes next to land hexes
-- But shouldn't be too far away (arb. set to 5 hexes here)
-- This is mostly to avoid it being across the bay in S6
local adj_tiles = {}
if (rating >= -0.05) then
for x,y in H.adjacent_tiles(r[1], r[2]) do
if (not unit_map:get(x, y)) then
if wesnoth.match_location(x, y, { terrain = "!, W*" }) then
rating = rating + 1
table.insert(adj_tiles, { x, y, 1. } )
end
if wesnoth.match_location(x, y,
{
terrain = "W*",
{ "filter_adjacent_location", { terrain = "!, W*" } }
}
)
then
rating = rating + 0.1
table.insert(adj_tiles, { x, y, 0.1 } )
end
end
end
end
if (rating > max_rating) then
max_rating = rating
best_unit = u
best_hex = r
best_adj_tiles = adj_tiles
end
end
end
end
end
if (max_rating > -9e99) then
-- Also find the best unloading hexes
-- TODO: this is currently not used as the AI functionality to make
-- it replay-safe does not exist; to be added later
--table.sort(best_adj_tiles, function(a, b) return a[3] > b[3] end)
--for i,tile in ipairs(best_adj_tiles) do
-- best_unit.variables['hex' .. i .. '_x'] = tile[1]
-- best_unit.variables['hex' .. i .. '_y'] = tile[2]
--end
-- For remaining hexes, simply use the center hex and let the engine decide itself
-- This also provides a safeguard against too many hexes being occupied
--for i = #best_adj_tiles + 1, 6 do
-- best_unit.variables['hex' .. i .. '_x'] = best_hex[1]
-- best_unit.variables['hex' .. i .. '_y'] = best_hex[2]
--end
ai.move_full(best_unit, best_hex[1], best_hex[2])
return
end
-- If we got here, no landing site was found. Do a deep-water move instead
local deep_water_map = LS.of_pairs(
wesnoth.get_locations {
terrain = 'Wo',
{ "not", { { "filter_adjacent_location", { terrain = '!, Wo' } } } }
}
)
local max_rating, best_unit, best_hex = -9e99, {}, {}
for i,u in ipairs(transports) do
local dst = { u.variables.destination_x, u.variables.destination_y }
local reach = wesnoth.find_reach(u)
local max_rating_unit, best_hex_unit = -9e99, {}
for i,r in ipairs(reach) do
if deep_water_map:get(r[1], r[2]) and (not blocked_hex_map:get(r[1], r[2])) then
local rating = -H.distance_between(r[1], r[2], dst[1], dst[2])
-- If possible, also move in a straight line
rating = rating - math.abs(r[1] - dst[1]) / 100.
rating = rating - math.abs(r[2] - dst[2]) / 100.
if (rating > max_rating_unit) then
max_rating_unit = rating
best_hex_unit = r
end
end
end
-- We give a penalty to hexes occupied by another transport that can still move away.
-- All ratings need to be set to the same value for this to work.
if (max_rating_unit > -9e99) then
max_rating_unit = 0
if transport_map:get(best_hex_unit[1], best_hex_unit[2]) then
max_rating_unit = -1
end
if (max_rating_unit > max_rating) then
max_rating = max_rating_unit
best_unit = u
best_hex = best_hex_unit
end
end
end
if best_unit.id then
ai.move_full(best_unit, best_hex[1], best_hex[2])
else -- still need to make sure gamestate gets changed
ai.stopunit_moves(transports[1])
end
end
return ca_transport

View File

@ -1,184 +0,0 @@
return {
init = function(ai)
local engine = {}
local H = wesnoth.require "lua/helper.lua"
local LS = wesnoth.require "lua/location_set.lua"
-- Move transport ships according to these rules:
-- 1. If transport can get to its designated landing site this move, find
-- close hex with the most unoccupied adjacent non-water hexes and move there
-- 2. If landing site is out of reach, move toward destination while
-- staying in deep water surrounded by deep water only
function engine:transport_eval()
local units = wesnoth.get_units {
side = wesnoth.current.side,
formula = '$this_unit.moves > 0',
}
for i,u in ipairs(units) do
local vars = H.get_child(u.__cfg, "variables")
if vars.destination_x and vars.destination_y then
return 300000
end
end
return 0
end
function engine:transport_exec(type)
local units = wesnoth.get_units {}
-- Need all transport units plus maps of all units, all transport units and
-- all other units (as those block hexes accessible to transport units)
local transports = {}
local unit_map, transport_map, blocked_hex_map = LS.create(), LS.create(), LS.create()
for i,u in ipairs(units) do
unit_map:insert(u.x, u.y)
if (u.side == wesnoth.current.side) and (u.moves > 0)
and u.variables.destination_x and u.variables.destination_x
then
transport_map:insert(u.x, u.y)
table.insert(transports, u)
--print("----> Inserting " .. u.id, u.x, u.y, u.variables.destination_x, u.variables.destination_y)
else
blocked_hex_map:insert(u.x, u.y)
end
end
-- First see if a transport is within landing distance
local landing_site_map = LS.of_pairs(
wesnoth.get_locations {
terrain = 'W*',
{ "filter_adjacent_location", { terrain = '!, W*' } }
}
)
local max_rating, best_unit, best_hex, best_adj_tiles = -9e99
for i,u in ipairs(transports) do
local dst = { u.variables.destination_x, u.variables.destination_y }
if (not u.variables.landed) and (H.distance_between(u.x, u.y, dst[1], dst[2]) <= u.moves) then
local reach = wesnoth.find_reach(u)
for i,r in ipairs(reach) do
if landing_site_map:get(r[1], r[2]) and (not unit_map:get(r[1], r[2]))
then
-- Distance from destination is minor rating
local rating = -H.distance_between(r[1], r[2], dst[1], dst[2]) / 100.
-- Main rating is number of unoccupied land hexes and
-- water hexes next to land hexes
-- But shouldn't be too far away (arb. set to 5 hexes here)
-- This is mostly to avoid it being across the bay in S6
local adj_tiles = {}
if (rating >= -0.05) then
for x,y in H.adjacent_tiles(r[1], r[2]) do
if (not unit_map:get(x, y)) then
if wesnoth.match_location(x, y, { terrain = "!, W*" }) then
rating = rating + 1
table.insert(adj_tiles, { x, y, 1. } )
end
if wesnoth.match_location(x, y,
{
terrain = "W*",
{ "filter_adjacent_location", { terrain = "!, W*" } }
}
)
then
rating = rating + 0.1
table.insert(adj_tiles, { x, y, 0.1 } )
end
end
end
end
if (rating > max_rating) then
max_rating = rating
best_unit = u
best_hex = r
best_adj_tiles = adj_tiles
end
end
end
end
end
if (max_rating > -9e99) then
-- Also find the best unloading hexes
-- TODO: this is currently not used as the AI functionality to make
-- it replay-safe does not exist; to be added later
--table.sort(best_adj_tiles, function(a, b) return a[3] > b[3] end)
--for i,tile in ipairs(best_adj_tiles) do
-- best_unit.variables['hex' .. i .. '_x'] = tile[1]
-- best_unit.variables['hex' .. i .. '_y'] = tile[2]
--end
-- For remaining hexes, simply use the center hex and let the engine decide itself
-- This also provides a safeguard against too many hexes being occupied
--for i = #best_adj_tiles + 1, 6 do
-- best_unit.variables['hex' .. i .. '_x'] = best_hex[1]
-- best_unit.variables['hex' .. i .. '_y'] = best_hex[2]
--end
ai.move_full(best_unit, best_hex[1], best_hex[2])
return
end
-- If we got here, no landing site was found. Do a deep-water move instead
local deep_water_map = LS.of_pairs(
wesnoth.get_locations {
terrain = 'Wo',
{ "not", { { "filter_adjacent_location", { terrain = '!, Wo' } } } }
}
)
local max_rating, best_unit, best_hex = -9e99, {}, {}
for i,u in ipairs(transports) do
local dst = { u.variables.destination_x, u.variables.destination_y }
local reach = wesnoth.find_reach(u)
local max_rating_unit, best_hex_unit = -9e99, {}
for i,r in ipairs(reach) do
if deep_water_map:get(r[1], r[2]) and (not blocked_hex_map:get(r[1], r[2])) then
local rating = -H.distance_between(r[1], r[2], dst[1], dst[2])
-- If possible, also move in a straight line
rating = rating - math.abs(r[1] - dst[1]) / 100.
rating = rating - math.abs(r[2] - dst[2]) / 100.
if (rating > max_rating_unit) then
max_rating_unit = rating
best_hex_unit = r
end
end
end
-- We give a penalty to hexes occupied by another transport that can still move away.
-- All ratings need to be set to the same value for this to work.
if (max_rating_unit > -9e99) then
max_rating_unit = 0
if transport_map:get(best_hex_unit[1], best_hex_unit[2]) then
max_rating_unit = -1
end
if (max_rating_unit > max_rating) then
max_rating = max_rating_unit
best_unit = u
best_hex = best_hex_unit
end
end
end
if best_unit.id then
ai.move_full(best_unit, best_hex[1], best_hex[2])
else -- still need to make sure gamestate gets changed
ai.stopunit_moves(transports[1])
end
end
return engine
end
}

View File

@ -54,23 +54,13 @@
user_team_name=_"Humans"
[ai]
version=10710
[engine]
name="lua"
code= <<
local ai = ...
return wesnoth.require("campaigns/Son_Of_The_Black_Eye/ai/transport_engine.lua").init(ai)
>>
[/engine]
{RCA_STAGE}
{MODIFY_AI_ADD_CANDIDATE_ACTION 3 main_loop (
[candidate_action]
engine=lua
name=transport
id=transport
max_score=300000
evaluation="return (...):transport_eval()"
execution="(...):transport_exec()"
location="campaigns/Son_Of_The_Black_Eye/ai/ca_transport.lua"
[/candidate_action]
)}
[/ai]

View File

@ -1,23 +1,5 @@
#textdomain wesnoth-ai
#define RCA_STAGE
# The standard RCA stage with its candidate actions; same for all Micro AIs
[stage]
id=main_loop
name=ai_default_rca::candidate_action_evaluation_loop
{AI_CA_GOTO}
{AI_CA_RECRUITMENT}
{AI_CA_MOVE_LEADER_TO_GOALS}
{AI_CA_MOVE_LEADER_TO_KEEP}
{AI_CA_COMBAT}
{AI_CA_HEALING}
{AI_CA_VILLAGES}
{AI_CA_RETREAT}
{AI_CA_MOVE_TO_TARGETS}
{AI_CA_LEADER_SHARES_KEEP}
[/stage]
#enddef
#define MAI_MACRO_DEPRECATION MACRO_NAME
# Somewhat hacky way to get a deprecation message displayed
# This macro goes into the [side] tag, so ActionWML tags cannot be used

View File

@ -898,6 +898,8 @@
B5FCE9371104C2A50081F1DF /* toggle_panel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5FCE9091104C2A50081F1DF /* toggle_panel.cpp */; };
B5FCE9391104C2A50081F1DF /* vertical_scrollbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5FCE90D1104C2A50081F1DF /* vertical_scrollbar.cpp */; };
B5FCE93A1104C2A50081F1DF /* window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5FCE90F1104C2A50081F1DF /* window.cpp */; };
EC44E382181DDAF90037A62F /* menu_item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC44E37E181DDAF90037A62F /* menu_item.cpp */; };
EC44E383181DDAF90037A62F /* wmi_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC44E380181DDAF90037A62F /* wmi_container.cpp */; };
EC48D74D17F3148300DE80BF /* recruitment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC48D74B17F3148300DE80BF /* recruitment.cpp */; };
EC48D75817F318DA00DE80BF /* flg_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC48D74E17F318DA00DE80BF /* flg_manager.cpp */; };
EC48D75917F318DA00DE80BF /* mp_game_utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC48D75017F318DA00DE80BF /* mp_game_utils.cpp */; };
@ -2011,6 +2013,10 @@
B5FCE90E1104C2A50081F1DF /* vertical_scrollbar.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = vertical_scrollbar.hpp; sourceTree = "<group>"; };
B5FCE90F1104C2A50081F1DF /* window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = window.cpp; sourceTree = "<group>"; };
B5FCE9101104C2A50081F1DF /* window.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = window.hpp; sourceTree = "<group>"; };
EC44E37E181DDAF90037A62F /* menu_item.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = menu_item.cpp; path = game_events/menu_item.cpp; sourceTree = "<group>"; };
EC44E37F181DDAF90037A62F /* menu_item.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = menu_item.hpp; path = game_events/menu_item.hpp; sourceTree = "<group>"; };
EC44E380181DDAF90037A62F /* wmi_container.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = wmi_container.cpp; path = game_events/wmi_container.cpp; sourceTree = "<group>"; };
EC44E381181DDAF90037A62F /* wmi_container.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = wmi_container.hpp; path = game_events/wmi_container.hpp; sourceTree = "<group>"; };
EC48D74B17F3148300DE80BF /* recruitment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = recruitment.cpp; path = recruitment/recruitment.cpp; sourceTree = "<group>"; };
EC48D74C17F3148300DE80BF /* recruitment.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = recruitment.hpp; path = recruitment/recruitment.hpp; sourceTree = "<group>"; };
EC48D74E17F318DA00DE80BF /* flg_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = flg_manager.cpp; sourceTree = "<group>"; };
@ -2273,6 +2279,10 @@
children = (
EC4D40AD17FCCF14002E7C81 /* strftime.cpp */,
EC4D40AE17FCCF14002E7C81 /* strftime.hpp */,
EC44E37E181DDAF90037A62F /* menu_item.cpp */,
EC44E37F181DDAF90037A62F /* menu_item.hpp */,
EC44E380181DDAF90037A62F /* wmi_container.cpp */,
EC44E381181DDAF90037A62F /* wmi_container.hpp */,
ECA9E67917F478B600F5DDC4 /* desktop_util.cpp */,
ECA9E67A17F478B600F5DDC4 /* desktop_util.hpp */,
62CC8E7917B9064B00C16B75 /* generators */,
@ -4149,6 +4159,7 @@
B552D92410869477002D8F86 /* distributor.cpp in Sources */,
B552D92D108694BB002D8F86 /* ca_testing_move_to_targets.cpp in Sources */,
B5CF7BBC10D55F5A00A8BEB5 /* timer.cpp in Sources */,
EC44E383181DDAF90037A62F /* wmi_container.cpp in Sources */,
B59271F710E956D600A13911 /* repeating_button.cpp in Sources */,
B59271FB10E9577800A13911 /* repeating_button.cpp in Sources */,
B5FCE9111104C2A50081F1DF /* button.cpp in Sources */,
@ -4316,6 +4327,7 @@
62D24F351519995200350848 /* palette_manager.cpp in Sources */,
62E48250154D865E001DD4FC /* pane.cpp in Sources */,
6216A91D1551CCF700E13C2D /* viewport.cpp in Sources */,
EC44E382181DDAF90037A62F /* menu_item.cpp in Sources */,
F4D5AFEC1571208B0062EAFC /* placer.cpp in Sources */,
F4D5AFF4157120B30062EAFC /* horizontal_list.cpp in Sources */,
F4D5AFF5157120B30062EAFC /* vertical_list.cpp in Sources */,