From de5b7500c248136eb183e39e982b1890b9fac65e Mon Sep 17 00:00:00 2001 From: mami Date: Sat, 24 Sep 2022 01:55:02 -0500 Subject: [PATCH] added priorities --- main.lua | 122 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 69 insertions(+), 53 deletions(-) diff --git a/main.lua b/main.lua index 5dd213b..72b3413 100644 --- a/main.lua +++ b/main.lua @@ -1,71 +1,87 @@ +local function get_item_amount(station, item_id) + return 0 +end +local function get_distance(stations, r_station_i, p_station_i) + return 0 +end local function send_train_between(stations, r_station_i, p_station_i) stations[r_station_i].last_p_station_i = p_station_i stations[p_station_i].last_r_station_i = r_station_i end +--[[ + station: + deliveries_total: int + train_limit: int + requester_limit: int + provider_limit: int + priority: int +]] -local function tick(stations) - --psuedocode +local function tick(stations, all_items) + for _, item_id in pairs(all_items) do + local r_stations = {} + local p_stations = {} - local r_stations = {} + for station_i, station in pairs(stations) do + if station.deliveries_total < station.train_limit then + local item_amount = get_item_amount(station, item_id) + local delivery_amount = station.delivery_amount - for station_i, station in ipairs(stations) do - local r_item = station.item - if -r_item.amount >= station.requester_limit then - r_stations[#r_stations + 1] = station_i - end - end - - local p_stations = {} - - for station_i, station in ipairs(stations) do - local p_item = station.item - if p_item.amount >= station.provider_limit then - p_stations[#p_stations + 1] = station_i - end - end - - --we do not dispatch more than one train per station per tick - if #r_stations > 0 and #p_stations > 0 then - if #r_stations <= #p_stations then - local last_p_station_i = stations[r_stations[1]].last_p_station_i - local i = 1 - while true do - if i > #p_stations then - i = 1 - break - elseif p_stations[i] > last_p_station_i then - break - else - i = i + 1 + if -(item_amount + delivery_amount) >= station.requester_limit then + table.insert(r_stations, station_i) + elseif item_amount + delivery_amount >= station.provider_limit then + table.insert(p_stations, station_i) end end - for j = 1, #r_stations do - send_train_between(stations, r_stations[j], p_stations[i]) + end - i = i%#p_stations + 1 - end - else - local last_r_station_i = stations[p_stations[1]].last_r_station_i - local i = 1 - while true do - if i > #r_stations then - i = 1 - break - elseif r_stations[i] > last_r_station_i then - break - else - i = i + 1 + --we do not dispatch more than one train per station per tick + + if #r_stations > 0 and #p_stations > 0 then + if #r_stations <= #p_stations then + --backpressure, prioritize locality + for i, r_station_i in ipairs(r_stations) do + local best = 1 + local best_dist = math.huge + local highest_prior = -math.huge + for j, p_station_i in ipairs(p_stations) do + local d = get_distance(stations, r_station_i, p_station_i) + local prior = stations[p_station_i].priority + if prior > highest_prior then + best = j + best_dist = d + highest_prior = prior + elseif prior == highest_prior and d < best_dist then + best = j + best_dist = d + end + end + send_train_between(stations, r_station_i, p_stations[best]) + table.remove(p_stations, best) + end + else + --prioritize round robin + for j, p_station_i in ipairs(p_stations) do + local best = 1 + local highest_prior = -math.huge + local last_r_station_i = stations[p_station_i].last_r_station_i + for i, r_station_i in ipairs(r_stations) do + local prior = stations[r_station_i].priority + if r_stations[i] > last_r_station_i then + prior = prior + .5 + end + if prior > highest_prior then + best = i + highest_prior = prior + end + end + send_train_between(stations, r_stations[best], p_station_i) + table.remove(r_stations, best) end end - for j = 1, #p_stations do - send_train_between(stations, r_stations[i], p_stations[j]) - - i = i%#p_stations + 1 - end - end end end