fix(kæde): højst 3 forslag pr. afgrøde og ét samlet kædepunkt i Kræver handling
This commit is contained in:
@@ -6,6 +6,8 @@ ADCropPlan = {}
|
||||
ADCropPlan.HORIZON_MONTHS = 12
|
||||
ADCropPlan.MIN_SHARE = 0.10
|
||||
ADCropPlan.MIN_HA = 0.5
|
||||
-- højst så mange forslag (ikke auto-skift) pr. afgrøde, så listen ikke vokser til snesevis af rækker
|
||||
ADCropPlan.MAX_SUGGEST_PER_FRUIT = 3
|
||||
|
||||
function ADCropPlan.plannedFruit(field)
|
||||
if field.targetFruit ~= nil and field.targetFruit ~= "" then return field.targetFruit end
|
||||
@@ -43,16 +45,24 @@ local function isCandidate(field, used, dismissedFruit, fruit)
|
||||
return dismissedFruit ~= fruit
|
||||
end
|
||||
|
||||
-- prices: {[afgrøde] = pris} eller en funktion afgrøde -> pris (slås kun op for kandidaternes afgrøder).
|
||||
function ADCropPlan.choose(shortages, fields, usedFruits, yields, prices, dismissed)
|
||||
local actions, taken = {}, {}
|
||||
local used = usedFruits or {}
|
||||
local priceOf = type(prices) == "function" and prices or function(fruit) return (prices or {})[fruit] or 0 end
|
||||
local priceCache = {}
|
||||
local function valueOf(fruit)
|
||||
if fruit == "" then return 0 end
|
||||
if priceCache[fruit] == nil then priceCache[fruit] = ((yields or {})[fruit] or 0) * (priceOf(fruit) or 0) end
|
||||
return priceCache[fruit]
|
||||
end
|
||||
for _, shortage in ipairs(shortages or {}) do
|
||||
local remaining = shortage.missingHa
|
||||
local candidates = {}
|
||||
for _, field in ipairs(fields or {}) do
|
||||
if not taken[field.id] and isCandidate(field, used, (dismissed or {})[field.id], shortage.fruit) then
|
||||
local planned = ADCropPlan.plannedFruit(field) or ""
|
||||
local value = ((yields or {})[planned] or 0) * ((prices or {})[planned] or 0)
|
||||
local value = valueOf(planned)
|
||||
table.insert(candidates, {field = field, value = value})
|
||||
end
|
||||
end
|
||||
@@ -62,14 +72,18 @@ function ADCropPlan.choose(shortages, fields, usedFruits, yields, prices, dismis
|
||||
if da ~= db then return da < db end
|
||||
return a.field.id < b.field.id
|
||||
end)
|
||||
local suggested = 0
|
||||
for _, candidate in ipairs(candidates) do
|
||||
if remaining <= 0 then break end
|
||||
local field = candidate.field
|
||||
local auto = field.chainFree == true and field.targetSource ~= "user"
|
||||
if auto or suggested < ADCropPlan.MAX_SUGGEST_PER_FRUIT then
|
||||
table.insert(actions, {fieldId = field.id, from = ADCropPlan.plannedFruit(field) or "", to = shortage.fruit,
|
||||
hectares = field.areaHa or 0, reason = shortage.fruit, mode = auto and "auto" or "suggest"})
|
||||
taken[field.id] = true
|
||||
remaining = remaining - (field.areaHa or 0)
|
||||
if not auto then suggested = suggested + 1 end
|
||||
end
|
||||
end
|
||||
end
|
||||
return actions
|
||||
|
||||
@@ -276,23 +276,18 @@ function ADStorageStats.rankAttention(list, max)
|
||||
return result
|
||||
end
|
||||
|
||||
-- "Kræver handling" fra kæden (ADChain.last): ét gult punkt pr. afgrødeforslag spilleren skal tage stilling til.
|
||||
-- Rangeres over "sælg nu" (score < 1000) og under røde punkter (>= 3000).
|
||||
ADStorageStats.CHAIN_SCORE = 1000
|
||||
-- "Kræver handling" fra kæden (ADChain.last): ÉT gult punkt "Kæde: N forslag" (klik -> fanen Kæder), så
|
||||
-- forslagene ikke fylder listen. Rangeres under alle røde punkter (>= 3000), øverst blandt de gule, over "sælg nu".
|
||||
ADStorageStats.CHAIN_SCORE = 2000
|
||||
|
||||
function ADStorageStats.chainEntries(last)
|
||||
local entries = {}
|
||||
local titles = last ~= nil and last.titles or {}
|
||||
local function title(name) return tostring((titles or {})[name] or name) end
|
||||
local count = 0
|
||||
for _, action in ipairs(last ~= nil and last.actions or {}) do
|
||||
if action.mode == "suggest" then
|
||||
local from = (action.from ~= nil and action.from ~= "") and title(action.from) or "-"
|
||||
table.insert(entries, {kind = "chainSuggest", level = "yellow", score = ADStorageStats.CHAIN_SCORE, fieldId = action.fieldId,
|
||||
from = from, to = title(action.to), hectares = action.hectares,
|
||||
text = string.format("F%s %s → %s", tostring(action.fieldId), from, title(action.to))})
|
||||
if action.mode == "suggest" then count = count + 1 end
|
||||
end
|
||||
end
|
||||
return entries
|
||||
if count == 0 then return {} end
|
||||
return {{kind = "chainSuggest", level = "yellow", score = ADStorageStats.CHAIN_SCORE, count = count,
|
||||
text = string.format("Kæde: %d", count)}}
|
||||
end
|
||||
|
||||
-- Varepunkterne (allerede rangeret) + kædens punkter, samme loft.
|
||||
|
||||
@@ -183,7 +183,7 @@ function SmartPickupFrame:addKpiRow(stats)
|
||||
return row
|
||||
end
|
||||
|
||||
-- Varepunkterne + kædens afgrødeforslag (ADChain.last; ingen evaluering her), samme loft MAX_ATTENTION.
|
||||
-- Varepunkterne + ét samlet punkt for kædens afgrødeforslag (ADChain.last; ingen evaluering her), samme loft MAX_ATTENTION.
|
||||
function SmartPickupFrame:attentionFor(stats)
|
||||
local attention = ADStorageStats.attentionList(stats, SmartPickupFrame.MAX_ATTENTION)
|
||||
if ADChain == nil or ADChain.last == nil then return attention end
|
||||
@@ -193,7 +193,7 @@ end
|
||||
function SmartPickupFrame:alertText(entry)
|
||||
local stat, fc, i18n = entry.stat, SmartPickupFrame.formatCompact, self.i18n
|
||||
if entry.kind == "chainSuggest" then
|
||||
return string.format(i18n:getText("spu_attention_chainSuggest"), entry.fieldId or 0, tostring(entry.from), tostring(entry.to))
|
||||
return string.format(i18n:getText("spu_attention_chainSuggests"), entry.count or 0)
|
||||
end
|
||||
if entry.kind == "empty" then
|
||||
return string.format(i18n:getText("spu_alert_empty"), stat.title, self:formatDays(stat.days), fc(stat.farmLevel or 0), fc(math.abs(stat.net or 0)))
|
||||
|
||||
@@ -607,7 +607,7 @@
|
||||
<text name="spu_chain_free" text="Marker fri til kæden: %s"/>
|
||||
<text name="spu_chain_switches" text="Automatiske skift siden indlæsning: %d"/>
|
||||
<text name="spu_chain_scanning" text="Marker scannes endnu – kæden skifter ingen marker før alle er set"/>
|
||||
<text name="spu_attention_chainSuggest" text="Kæde: F%d %s → %s"/>
|
||||
<text name="spu_attention_chainSuggests" text="Kæde: %d forslag"/>
|
||||
<text name="spu_attention_hintChain" text=" → klik: se Kæder"/>
|
||||
</texts>
|
||||
</l10n>
|
||||
|
||||
@@ -607,7 +607,7 @@
|
||||
<text name="spu_chain_free" text="Fields free for the chain: %s"/>
|
||||
<text name="spu_chain_switches" text="Automatic switches since load: %d"/>
|
||||
<text name="spu_chain_scanning" text="Fields still being scanned – no field changes until all are seen"/>
|
||||
<text name="spu_attention_chainSuggest" text="Chain: F%d %s → %s"/>
|
||||
<text name="spu_attention_chainSuggests" text="Chain: %d suggestions"/>
|
||||
<text name="spu_attention_hintChain" text=" → click: see Chains"/>
|
||||
</texts>
|
||||
</l10n>
|
||||
|
||||
Reference in New Issue
Block a user