From fbe4c914d748369a0936b2fed634728560be08f8 Mon Sep 17 00:00:00 2001 From: Michal Cieslakiewicz Date: Fri, 7 Aug 2020 21:59:15 +0200 Subject: [PATCH] distributor: improve fairness by using random spread Distributor iterates through filter indices always in the same order, accidentally favouring certain ports. This is particularly noticeable for 3 outputs configured with the same item - lowest numbered port is receiving double quantity (TA2 distributor moves items in pack of 4). Fix provided in this patch adds an extra mapping for filter indexing, permutating randomly outputs with identical items so no ports are preferred anymore. Signed-off-by: Michal Cieslakiewicz --- basic_machines/distributor.lua | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/basic_machines/distributor.lua b/basic_machines/distributor.lua index fb23c52..e4f9e27 100644 --- a/basic_machines/distributor.lua +++ b/basic_machines/distributor.lua @@ -35,6 +35,19 @@ local SlotColors = {"red", "green", "blue", "yellow"} local Num2Ascii = {"B", "L", "F", "R"} local FilterCache = {} -- local cache for filter settings +-- Permutation table to improve distribution between ports (number of ports: 1-4) +-- Usage: permIdx[num_ports][math.random(1, #permIdx[num_ports])][idx] +local permIdx = { + { { 1 } }, + { { 1, 2 }, { 2, 1 } }, + { { 1, 2, 3 }, { 1, 3, 2 }, { 2, 1, 3 }, { 2, 3, 1 }, { 3, 1, 2 }, { 3, 2, 1 } }, + { { 1, 2, 3, 4 }, { 1, 2, 4, 3 }, { 1, 3, 2, 4 }, { 1, 3, 4, 2 }, { 1, 4, 2, 3 }, + { 1, 4, 3, 2 }, { 2, 1, 3, 4 }, { 2, 1, 4, 3 }, { 2, 3, 1, 4 }, { 2, 3, 4, 1 }, + { 2, 4, 1, 3 }, { 2, 4, 3, 1 }, { 3, 1, 2, 4 }, { 3, 1, 4, 2 }, { 3, 2, 1, 4 }, + { 3, 2, 4, 1 }, { 3, 4, 1, 2 }, { 3, 4, 2, 1 }, { 4, 1, 2, 3 }, { 4, 1, 3, 2 }, + { 4, 2, 1, 3 }, { 4, 2, 3, 1 }, { 4, 3, 1, 2 }, { 4, 3, 2, 1 }, } +} + local function filter_settings(pos) local meta = M(pos) local param2 = techage.get_node_lvm(pos).param2 @@ -206,11 +219,12 @@ local function push_item(pos, filter, item_name, num_items, nvm) local idx = 1 local num_pushed = 0 local num_ports = #filter + local randidx = permIdx[num_ports][math.random(1, #permIdx[num_ports])] local amount = math.floor(math.max((num_items + 1) / num_ports, 1)) local num_of_trials = 0 while num_pushed < num_items and num_of_trials <= 8 do num_of_trials = num_of_trials + 1 - local push_dir = filter[idx] + local push_dir = filter[randidx[idx]] local num_to_push = math.min(amount, num_items - num_pushed) if techage.push_items(pos, push_dir, ItemStack(item_name.." "..num_to_push)) then num_pushed = num_pushed + num_to_push