Commit 2c59c8b6 authored by Vury Leo's avatar Vury Leo

fix mono

parent 0b1e497d
......@@ -3475,6 +3475,62 @@ function Synchro.AddSynchroProcedure(c,params)
c:RegisterEffect(e1)
end
-- Entry point: prepares and invokes the DFS
function Synchro.FindValidSelection(candidates,target_level,
tuner_filter,non_tuner_filter,tc,
tuner_min,tuner_max,
non_tuner_min,non_tuner_max,
base_mapper,pre_select,state)
-- 1) Sort candidates: Mono first, then Flower, then normals
local function is_mono(c)
return c:IsCode(56897896)
end
local function is_flower(c)
return c:IsCode(57261568, 33541430, 89818984)
end
table.sort(candidates,function(a,b)
if is_mono(a)~=is_mono(b) then
return is_mono(a) -- monos first
end
if is_flower(a)~=is_flower(b) then
return is_flower(a) -- then flowers
end
-- otherwise normals: sort descending by level
return a:GetLevel()>b:GetLevel()
end)
-- 2) Find the index of the last dynamic card
local level_prune_index=0
for i, c in ipairs(candidates) do
if is_mono(c) or is_flower(c) then
level_prune_index=i
end
end
-- 3) Invoke the core DFS, passing last_dyn along
return Synchro.CanCompleteSelection(
candidates,target_level,
tuner_filter,non_tuner_filter,tc,
tuner_min,tuner_max,
non_tuner_min,non_tuner_max,
base_mapper,
pre_select or {},
1,
state or { -- initial state
possible_sums={[0]=true},
tuner_count=0,
non_tuner_count=0,
level_mapper=base_mapper,
level_mapper_priority=0,
},
{
level_prune_index=level_prune_index
}
)
end
--- Check if there exists a valid Synchro material selection from candidates (including current selected),
--- satisfying tuner/non-tuner counts and total level, supporting multiple possible levels per card.
---
......@@ -3491,24 +3547,16 @@ end
--- @param non_tuner_max integer|table -- Maximum number of non-tuner materials allowed.
--- @param base_mapper fun(card:Card,tc:Card):integer[]
--- -- Function returning possible levels for a card.
--- @param selected? Card[] -- Currently selected material cards.
--- @param index? integer -- Current index in candidates for DFS (default 1).
--- @param state? table -- DFS state table containing:
--- @param selected Card[] -- Currently selected material cards.
--- @param index integer -- Current index in candidates for DFS (default 1).
--- @param state table -- DFS state table containing:
--- -- sum (integer): current total level sum,
--- -- tuner_count (integer): current tuner count,
--- -- non_tuner_count (integer): current non-tuner count.
--- @param prune_indexes table
--- @return boolean -- True if a valid selection exists, false otherwise.
function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,selected,index,state)
index=index or 1
selected=selected or {}
state=state or {
possible_sums={[0]=true},
tuner_count=0,
non_tuner_count=0,
priority=0,
level_mapper=base_mapper,
}
tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,selected,index,state,prune_indexes)
--- Mono Synchron (priority=2) > Flower Cardian (1) > normal (0)
local mapper = state.level_mapper
......@@ -3525,6 +3573,12 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t
return false
end
local prune_level=target_level
-- prune after all level dynamic cards consumed
if index<prune_indexes.level_prune_index then
prune_level=0xff -- infinity
end
local mc=candidates[index]
local tuner_inc=tuner_filter(mc,tc) and 1 or 0
local non_tuner_inc=non_tuner_filter(mc,tc) and 1 or 0
......@@ -3534,7 +3588,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t
-- 1) MonoSynchron branch (priority<2 → first Mono; priority==2 → full Mono)
if mc:IsCode(56897896) then
if state.priority<2 then
if state.level_mapper_priority<2 then
-- first Mono: that one keeps its real level, others=1
local firstMono=mc
local mono_mapper=function(c,tc_arg)
......@@ -3544,51 +3598,58 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t
return {1}
end
end
local sums1=Synchro.Updatepossible_sums(
state.possible_sums,
mono_mapper(mc,tc),
target_level
)
if next(sums1) then
-- reset your sums_so_far into a single bucket of (#selected)*1+self
local sums1={[#selected+mc:GetLevel()]=true}
if next(sums1)~=nil then
table.insert(variants,{
sums=sums1,
mapper=mono_mapper,
priority=2,
possible_sums=sums1,
level_mapper=mono_mapper,
level_mapper_priority=2,
})
end
elseif state.priority==2 then
elseif state.level_mapper_priority==2 then
-- second (or later) Mono: full override—all cards=Level 1
local full_mapper=function() return {1} end
-- reset your sums_so_far into a single bucket of (#selected+1)*1
local cnt=#selected+1
local sums2={[cnt]=true}
table.insert(variants,{
sums=sums2,
mapper=full_mapper,
priority=2, -- stays in Mono mode
possible_sums=sums2,
level_mapper=full_mapper,
level_mapper_priority=2, -- stays in Mono mode
})
end
end
-- 1) Normal include branch
local lvls=mapper(mc,tc)
local sums_norm=Synchro.UpdatepossibleSums(state.possible_sums,lvls,target_level)
if next(sums_norm)then
table.insert(variants,{sums=sums_norm,mapper=mapper})
if not mc:IsCode(56897896) then
-- 1) Normal include branch
local lvls=mapper(mc,tc)
local sums_norm=Synchro.UpdatepossibleSums(state.possible_sums,lvls,prune_level)
if next(sums_norm) then
table.insert(variants,{possible_sums=sums_norm,level_mapper=mapper})
end
end
-- 2) override if Flower Cardian
if mc:IsCode(57261568,33541430,89818984) then
local cnt=#selected+1
local sums_ovr={[2*cnt]=true}
table.insert(variants,{sums=sums_ovr,mapper=function() return{2} end})
if state.level_mapper_priority<1 then
local cnt=#selected+1
local sums_ovr={[2*cnt]=true}
table.insert(variants,{
possible_sums=sums_ovr,
level_mapper=function() return{2} end,
level_mapper_priority=1
})
end
end
for _,var in ipairs(variants) do
local new_state={
possible_sums=var.sums,
possible_sums=var.possible_sums,
tuner_count=state.tuner_count+tuner_inc,
non_tuner_count=state.non_tuner_count+non_tuner_inc,
level_mapper=var.mapper,
level_mapper=var.level_mapper,
level_mapper_priority=var.level_mapper_priority,
}
table.insert(selected,mc)
......@@ -3596,7 +3657,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t
candidates,target_level,
tuner_filter,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,
base_mapper,selected,index+1,new_state
base_mapper,selected,index+1,new_state,prune_indexes
)
then
table.remove(selected)
......@@ -3607,7 +3668,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t
-- exclude branch
if Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,selected,index+1,state) then
tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,selected,index+1,state,prune_indexes) then
return true
end
......@@ -3627,7 +3688,7 @@ function Synchro.SynCondition(tuner_filter,non_tuner_filter,tuner_min,tuner_max,
table.insert(candidates,mc)
end
return Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_tuner_filter,c,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper)
return Synchro.FindValidSelection(candidates,target_level,tuner_filter,non_tuner_filter,c,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper)
end
end
......@@ -3647,17 +3708,17 @@ function Synchro.SynTarget(tuner_filter,non_tuner_filter,tuner_min,tuner_max,non
local sg_arr=GroupToArray(sg)
local cg_arr=GroupToArray(mg-sg)
local target_level=tc:GetLevel()
for _, candidate in ipairs(cg_arr) do
for _,candidate in ipairs(cg_arr) do
-- simulate adding candidate to sg_arr
local test_selection = {}
for _, card in ipairs(sg_arr) do table.insert(test_selection, card) end
table.insert(test_selection, candidate)
local test_selection={}
for _, card in ipairs(sg_arr) do table.insert(test_selection,card) end
table.insert(test_selection,candidate)
-- build rest_candidates without candidate
local rest_candidates = {}
local rest_candidates={}
for _, other in ipairs(cg_arr) do
if other~=candidate then
table.insert(rest_candidates, other)
table.insert(rest_candidates,other)
end
end
......@@ -3665,16 +3726,15 @@ function Synchro.SynTarget(tuner_filter,non_tuner_filter,tuner_min,tuner_max,non
test_selection,
tuner_filter,non_tuner_filter,
base_mapper,
tc,target_level
tc,0xff
)
for _,init_state in ipairs(base_states)do
if Synchro.CanCompleteSelection(
for _,init_state in ipairs(base_states) do
if Synchro.FindValidSelection(
rest_candidates,target_level,
tuner_filter,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,
base_mapper,test_selection,1,init_state
)
base_mapper,test_selection,init_state)
then
addable:AddCard(candidate)
break
......@@ -3740,7 +3800,7 @@ function Synchro.IsSelectionValid(selection,target_level,tuner_filter,non_tuner_
selection,
tuner_filter,non_tuner_filter,
Synchro.LevelMapper,
tc,target_level
tc,0xff
)
for _,state in ipairs(states)do
if not Synchro.ExceedsMax(state.tuner_count,tuner_max) then
......@@ -3793,29 +3853,50 @@ function Synchro.LevelMapper(card,tc)
return levels
end
function Synchro.UpdatepossibleSums(possible_sums, card_levels, target_level)
function Synchro.UpdatepossibleSums(possible_sums,card_levels,prune_level)
local new_sums={}
for sum, _ in pairs(possible_sums) do
for _, lvl in ipairs(card_levels) do
local newSum=sum+lvl
if newSum<=target_level then
new_sums[newSum] = true
if newSum<=prune_level then
new_sums[newSum]=true
end
end
end
return new_sums
end
function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filter,base_mapper,tc,target_level)
function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filter,base_mapper,tc,prune_level)
local states={
{
possible_sums={[0]=true},
tuner_count=0,
non_tuner_count=0,
level_mapper=base_mapper
level_mapper=base_mapper,
level_mapper_priority=0,
}
}
-- 1) Sort candidates: Mono first, then Flower, then normals
local function is_mono(c)
return c:IsCode(56897896)
end
local function is_flower(c)
return c:IsCode(57261568, 33541430, 89818984)
end
table.sort(selection,function(a,b)
if is_mono(a)~=is_mono(b) then
return is_mono(a) -- monos first
end
if is_flower(a)~=is_flower(b) then
return is_flower(a) -- then flowers
end
-- otherwise normals: sort descending by level
return a:GetLevel()>b:GetLevel()
end)
for idx,card in ipairs(selection)do
local next_states={}
......@@ -3824,27 +3905,68 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte
local non_tuner_inc=non_tuner_filter(card,tc) and 1 or 0
local mapper=st.level_mapper
-- normal branch
local lvls=mapper(card,tc)
local sums_norm=Synchro.UpdatepossibleSums(st.possible_sums,lvls,target_level)
if next(sums_norm) then
table.insert(next_states,{
possible_sums=sums_norm,
tuner_count=st.tuner_count+tuner_inc,
non_tuner_count=st.non_tuner_count+non_tuner_inc,
level_mapper=mapper,
})
-- 1) MonoSynchron branch (priority<2 → first Mono; priority==2 → full Mono)
if card:IsCode(56897896) then
if st.level_mapper_priority<2 then
-- first Mono: that one keeps its real level, others=1
local firstMono=card
local mono_mapper=function(c,tc_arg)
if c==firstMono then
return {c:GetLevel()}
else
return {1}
end
end
local sums1={[idx-1+card:GetLevel()]=true}
table.insert(next_states,{
possible_sums=sums1,
tuner_count=st.tuner_count+tuner_inc,
non_tuner_count=st.non_tuner_count+non_tuner_inc,
level_mapper=mono_mapper,
level_mapper_priority=2,
})
elseif st.level_mapper_priority==2 then
-- second (or later) Mono: full override—all cards=Level 1
local full_mapper=function() return {1} end
-- reset your sums_so_far into a single bucket of idx*1
local sums2={[idx]=true}
table.insert(next_states,{
possible_sums=sums2,
tuner_count=st.tuner_count+tuner_inc,
non_tuner_count=st.non_tuner_count+non_tuner_inc,
level_mapper=full_mapper,
level_mapper_priority=2, -- stays in Mono mode
})
end
end
if not card:IsCode(56897896) then
-- normal branch
local lvls=mapper(card,tc)
local sums_norm=Synchro.UpdatepossibleSums(st.possible_sums,lvls,prune_level)
if next(sums_norm)~=nil then
table.insert(next_states,{
possible_sums=sums_norm,
tuner_count=st.tuner_count+tuner_inc,
non_tuner_count=st.non_tuner_count+non_tuner_inc,
level_mapper=mapper,
level_mapper_priority=st.level_mapper_priority,
})
end
end
-- override level mapper branch if Flower Cardian
if card:IsCode(57261568,33541430,89818984) then
local sums_ovr={[2*idx]=true}
table.insert(next_states,{
possible_sums=sums_ovr,
tuner_count=st.tuner_count+tuner_inc,
non_tuner_count=st.non_tuner_count+non_tuner_inc,
level_mapper=function() return {2} end,
})
if st.level_mapper_priority<1 then
local sums_ovr={[2*idx]=true}
table.insert(next_states,{
possible_sums=sums_ovr,
tuner_count=st.tuner_count+tuner_inc,
non_tuner_count=st.non_tuner_count+non_tuner_inc,
level_mapper=function() return {2} end,
level_mapper_priority=1,
})
end
end
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment