Recap the run's high-water mark: peak board synergy

JCA.board_synergy sums every owned pair once; the emplace hook that
already drives discovery keeps the maximum in G.GAME.jca_peak_synergy
(it can only rise when a joker arrives). The post-run recap shows it,
now also on runs that fielded no famous pair.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-07-14 13:48:47 -07:00
parent f73507f5c6
commit 2b43d24994
2 changed files with 68 additions and 14 deletions
+46 -14
View File
@@ -844,8 +844,31 @@ end
-- during the current run are also recorded in G.GAME.jca_run_combos (saved
-- with the run) for end-of-run display.
-- Total pairwise synergy across the current board: every owned pair scored
-- once. The run's high-water mark is kept in G.GAME.jca_peak_synergy for the
-- recap; it can only rise when a joker arrives, so the emplace hook that
-- already drives discovery is the one place that needs to look.
function JCA.board_synergy()
if not (G.jokers and G.jokers.cards) then return 0 end
local keys = {}
for _, c in ipairs(G.jokers.cards) do
if is_joker(c) then keys[#keys + 1] = c.config.center.key end
end
local sum = 0
for i = 1, #keys do
for j = i + 1, #keys do
sum = sum + JCA.score(keys[i], keys[j])
end
end
return sum
end
function JCA.check_discoveries()
if not (G.jokers and G.jokers.cards) then return end
if G.GAME then
local s = JCA.board_synergy()
if s > (G.GAME.jca_peak_synergy or 0) then G.GAME.jca_peak_synergy = s end
end
local keys = {}
for _, c in ipairs(G.jokers.cards) do
if is_joker(c) then keys[#keys + 1] = c.config.center.key end
@@ -943,28 +966,37 @@ end
local function recap_row()
local combos = G.GAME and G.GAME.jca_run_combos
if not combos or not next(combos) then return nil end
local peak = (G.GAME and G.GAME.jca_peak_synergy) or 0
local names = {}
for pk in pairs(combos) do
for pk in pairs(combos or {}) do
local a, b = pk:match('^(.-)|(.+)$')
if a then names[#names + 1] = name_of(a) .. ' + ' .. name_of(b) end
end
if #names == 0 then return nil end
if #names == 0 and peak <= 0 then return nil end
table.sort(names)
local rows = {{n = G.UIT.R, config = {align = 'cm', padding = 0.03}, nodes = {
{n = G.UIT.T, config = {text = 'Combos fielded this run',
colour = G.C.GOLD, scale = 0.35, shadow = true}},
}}}
for i = 1, math.min(#names, 6) do
rows[#rows + 1] = {n = G.UIT.R, config = {align = 'cm', padding = 0.02}, nodes = {
{n = G.UIT.T, config = {text = names[i],
colour = G.C.WHITE, scale = 0.3, shadow = true}},
local rows = {}
if #names > 0 then
rows[#rows + 1] = {n = G.UIT.R, config = {align = 'cm', padding = 0.03}, nodes = {
{n = G.UIT.T, config = {text = 'Combos fielded this run',
colour = G.C.GOLD, scale = 0.35, shadow = true}},
}}
for i = 1, math.min(#names, 6) do
rows[#rows + 1] = {n = G.UIT.R, config = {align = 'cm', padding = 0.02}, nodes = {
{n = G.UIT.T, config = {text = names[i],
colour = G.C.WHITE, scale = 0.3, shadow = true}},
}}
end
if #names > 6 then
rows[#rows + 1] = {n = G.UIT.R, config = {align = 'cm', padding = 0.02}, nodes = {
{n = G.UIT.T, config = {text = '+' .. (#names - 6) .. ' more',
colour = G.C.UI.TEXT_LIGHT, scale = 0.3}},
}}
end
end
if #names > 6 then
if peak > 0 then
rows[#rows + 1] = {n = G.UIT.R, config = {align = 'cm', padding = 0.02}, nodes = {
{n = G.UIT.T, config = {text = '+' .. (#names - 6) .. ' more',
colour = G.C.UI.TEXT_LIGHT, scale = 0.3}},
{n = G.UIT.T, config = {text = 'Peak board synergy: ' .. peak,
colour = G.C.GOLD, scale = 0.3, shadow = true}},
}}
end
return {n = G.UIT.R, config = {align = 'cm', padding = 0.06}, nodes = rows}
+22
View File
@@ -415,6 +415,28 @@ per[2].ability = {perishable = true, perish_tally = 0}
eq(JCA.weakest_link(), per[2],
'but a perished joker is the cut at any score - it will never work again')
--------------------------------------------------------------------------------
section('Engine: board synergy total and its run peak')
--------------------------------------------------------------------------------
-- Every owned pair scored once: Baron+Mime is the famous 6, the plain Joker
-- adds only its generic +1 against Baron's xMult.
field('j_baron', 'j_mime', 'j_joker')
eq(JCA.board_synergy(), 7, 'board synergy sums every owned pair once')
-- The peak rides the same emplace hook as discovery, and never goes down.
-- Discovery state is snapshotted so this cannot leak into the UI tests.
local saved_disc, saved_themes = JCA.config.discovered, JCA.config.themes_found
JCA.config.discovered, JCA.config.themes_found = {}, {}
G.GAME = {}
JCA.check_discoveries()
eq(G.GAME.jca_peak_synergy, 7, 'the emplace hook records the high-water mark')
field('j_joker')
JCA.check_discoveries()
eq(G.GAME.jca_peak_synergy, 7, 'selling down does not lower the recorded peak')
G.GAME = {}
JCA.config.discovered, JCA.config.themes_found = saved_disc, saved_themes
--------------------------------------------------------------------------------
section('Engine: deck context counts base suits')
--------------------------------------------------------------------------------