Commit bcd7b2ae authored by Vury Leo's avatar Vury Leo

fix index

parent 8698e712
...@@ -3417,7 +3417,7 @@ function Synchro.FindValidSelection(candidates,target_level, ...@@ -3417,7 +3417,7 @@ function Synchro.FindValidSelection(candidates,target_level,
Synchro.SortMaterials(candidates,tc,tuner_filter) Synchro.SortMaterials(candidates,tc,tuner_filter)
-- Find the index of the last level card -- Find the index of the last level card
local level_prune_index=-1 local level_prune_index=0
for i, c in ipairs(candidates) do for i, c in ipairs(candidates) do
if Synchro.IsLevelAlter(c) then if Synchro.IsLevelAlter(c) then
level_prune_index=i level_prune_index=i
...@@ -3425,7 +3425,7 @@ function Synchro.FindValidSelection(candidates,target_level, ...@@ -3425,7 +3425,7 @@ function Synchro.FindValidSelection(candidates,target_level,
end end
-- Find the index of the last hand card -- Find the index of the last hand card
local hand_prune_index=-1 local hand_prune_index=0
for i, c in ipairs(candidates) do for i, c in ipairs(candidates) do
if Synchro.IsHandAlter(c) then if Synchro.IsHandAlter(c) then
hand_prune_index=i hand_prune_index=i
...@@ -3433,7 +3433,7 @@ function Synchro.FindValidSelection(candidates,target_level, ...@@ -3433,7 +3433,7 @@ function Synchro.FindValidSelection(candidates,target_level,
end end
-- Find the index of the last race card -- Find the index of the last race card
local race_prune_index=-1 local race_prune_index=0
for i, c in ipairs(candidates) do for i, c in ipairs(candidates) do
if Synchro.IsRaceAlter(c) then if Synchro.IsRaceAlter(c) then
race_prune_index=i race_prune_index=i
...@@ -3500,16 +3500,17 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f ...@@ -3500,16 +3500,17 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f
if state.tuner_count>tuner_max then return false end if state.tuner_count>tuner_max then return false end
if state.non_tuner_count>non_tuner_max then return false end if state.non_tuner_count>non_tuner_max then return false end
if (index>prune_indexes.hand_prune_index and state.hand_count>state.hand_count_limit) then return false end
if index>#candidates then local prune_tuner_filter=tuner_filter
-- check if target_level achievable exactly local prune_non_tuner_filter=non_tuner_filter
if state.possible_sums[target_level] and if index>prune_indexes.race_prune_index then
state.tuner_count>=tuner_min and if state.genomix_race~=nil then
state.non_tuner_count>=non_tuner_min then prune_tuner_filter=aux.AND(function() return state.genomix_race&tuner_race~=0 end,tuner_filter)
return true prune_non_tuner_filter=aux.AND(function() return state.genomix_race&non_tuner_race~=0 end,non_tuner_filter)
else
prune_tuner_filter=aux.AND(function(c) return c:IsRace(tuner_race) end,tuner_filter)
prune_non_tuner_filter=aux.AND(function(c) return c:IsRace(non_tuner_race) end,non_tuner_filter)
end end
return false
end end
local prune_level=target_level local prune_level=target_level
...@@ -3518,50 +3519,41 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f ...@@ -3518,50 +3519,41 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f
prune_level=math.huge -- infinity prune_level=math.huge -- infinity
end end
local prune_tuner_filter=tuner_filter --- prune on hand count
local prune_non_tuner_filter=non_tuner_filter if index==prune_indexes.hand_prune_index+1 then
if index>prune_indexes.race_prune_index then if state.hand_count>state.hand_count_limit then
if state.genomix_race~=nil then return false
prune_tuner_filter=aux.AND(function() return state.genomix_race&tuner_race~=0 end,tuner_filter)
prune_non_tuner_filter=aux.AND(function() return state.genomix_race&tuner_race~=0 end,non_tuner_filter)
else
prune_tuner_filter=aux.AND(function(c) return c:IsRace(tuner_race) end,tuner_filter)
prune_non_tuner_filter=aux.AND(function(c) return c:IsRace(tuner_race) end,non_tuner_filter)
end end
end end
--- one time prune on selected materials considering race
if index==prune_indexes.race_prune_index+1 then if index==prune_indexes.race_prune_index+1 then
--- one time prune on selected materials for _,sc in ipairs(selected) do
for _,selected in ipairs(selected) do if not (prune_tuner_filter(sc) or prune_non_tuner_filter(sc)) then
if not (prune_tuner_filter(selected) or prune_non_tuner_filter(selected)) then
return false return false
end end
end end
end end
local mc=candidates[index] if index>#candidates then
local can_include=true -- check if target_level achievable exactly
if state.possible_sums[target_level] and
--- to include one material it must fit all applied filter state.tuner_count>=tuner_min and
if not state.material_limit_filter(nil,mc) then state.non_tuner_count>=non_tuner_min then
can_include=false return true
end
local append_material_limit_filter=nil
if can_include==true then
--- to include one material, all selected ones must fit its material limit
local material_limit_effect=mc:IsHasEffect(EFFECT_TUNER_MATERIAL_LIMIT)
if material_limit_effect~=nil then
append_material_limit_filter=material_limit_effect:GetTarget()
assert(append_material_limit_filter~=nil,"we have a material limit effect but it does not have target function")
for _,selected_mat in ipairs(selected) do
if not append_material_limit_filter(material_limit_effect,selected_mat) then
can_include=false
break
end
end
end end
return false
end end
local mc=candidates[index]
local can_include,append_material_limit_filter =
Synchro.CanIncludeMaterial(
mc,state,selected,tc,
prune_tuner_filter,prune_non_tuner_filter,
prune_indexes,index
)
--- include branch --- include branch
if can_include then if can_include then
for _,diff in ipairs(Synchro.GenerateVariantForCard( for _,diff in ipairs(Synchro.GenerateVariantForCard(
...@@ -3654,27 +3646,10 @@ function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filt ...@@ -3654,27 +3646,10 @@ function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filt
end end
for _,state in ipairs(selected_states) do for _,state in ipairs(selected_states) do
for _,candidate in ipairs(cg_arr) do for _,candidate in ipairs(cg_arr) do
local can_include=true local can_include=Synchro.CanIncludeMaterial(
candidate,state,sg_arr,tc,
--- to include one material it must fit all applied filter tuner_filter,non_tuner_filter
if not state.material_limit_filter(nil,candidate) then )
can_include=false
end
local append_material_limit_filter=nil
if can_include==true then
--- to include one material, all selected ones must fit its material limit
local material_limit_effect=candidate:IsHasEffect(EFFECT_TUNER_MATERIAL_LIMIT)
if material_limit_effect~=nil then
append_material_limit_filter=material_limit_effect:GetTarget()
for _,selected_mat in ipairs(sg_arr) do
if not append_material_limit_filter(material_limit_effect,selected_mat) then
can_include=false
break
end
end
end
end
if can_include then if can_include then
-- simulate adding candidate to sg_arr -- simulate adding candidate to sg_arr
...@@ -4021,3 +3996,59 @@ function Synchro.ApplyVariantState(st,card,diff,tuner_race,tuner_filter,non_tune ...@@ -4021,3 +3996,59 @@ function Synchro.ApplyVariantState(st,card,diff,tuner_race,tuner_filter,non_tune
material_limit_filter=new_material_limit_filter, material_limit_filter=new_material_limit_filter,
} }
end end
--- Determine whether a candidate card can be included as a material
--- @param mc Card -- the material candidate
--- @param state table -- current DFS state
--- @param selected Card[] -- already-selected materials
--- @param tc Card -- the Synchro monster being summoned
--- @param prune_tuner_filter function -- tuner filter (with pruning applied)
--- @param prune_non_tuner_filter function -- non-tuner filter (with pruning applied)
--- @param prune_indexes? table -- index thresholds for pruning
--- @param index? integer -- current position in candidates
--- @return boolean can_include
--- @return function|nil append_material_limit_filter
function Synchro.CanIncludeMaterial(mc,state,selected,tc,
prune_tuner_filter,prune_non_tuner_filter,
prune_indexes,index)
prune_indexes=prune_indexes or {
hand_prune_index=math.huge,
race_prune_index=math.huge,
level_prune_index=math.huge,
}
index=index or -1
-- 1) global material‐limit check
if not state.material_limit_filter(nil,mc) then
return false,nil
end
local append_material_limit_filter
-- 2) per-card EFFECT_TUNER_MATERIAL_LIMIT check against already‐selected
local eff=mc:IsHasEffect(EFFECT_TUNER_MATERIAL_LIMIT)
if eff then
assert(eff:GetTarget(),"EFFECT_TUNER_MATERIAL_LIMIT has no target function")
append_material_limit_filter=function(c) return eff:GetTarget()(eff,c) end
for _, sel in ipairs(selected) do
if not append_material_limit_filter(sel) then
return false,nil
end
end
end
-- 3) must satisfy at least one of the tuner/non-tuner filters
if not (prune_tuner_filter(mc,tc) or prune_non_tuner_filter(mc,tc)) then
return false,nil
end
-- 4) hand‐location count limit
if mc:IsLocation(LOCATION_HAND)
and index>prune_indexes.hand_prune_index
and state.hand_count>state.hand_count_limit then
return false,nil
end
return true,append_material_limit_filter
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