Commit d1180d96 authored by Vury Leo's avatar Vury Leo

add 熾天龍 ジャッジメント

parent 88ab5880
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
function c41659072.initial_effect(c) function c41659072.initial_effect(c)
--synchro summon --synchro summon
aux.AddSynchroMixProcedure(c,aux.Tuner(nil),nil,nil,aux.NonTuner(nil),1,99,c41659072.syncheck) aux.AddSynchroMixProcedure(c,aux.Tuner(nil),nil,nil,aux.NonTuner(nil),1,99,c41659072.syncheck)
Synchro.AddSynchroProcedure(c,{
scheck=c41659072.syncheck,
})
c:EnableReviveLimit() c:EnableReviveLimit()
--spsummon condition --spsummon condition
local e1=Effect.CreateEffect(c) local e1=Effect.CreateEffect(c)
......
...@@ -3396,7 +3396,8 @@ function Synchro.AddSynchroProcedure(c,params) ...@@ -3396,7 +3396,8 @@ function Synchro.AddSynchroProcedure(c,params)
local tuner_max=params.tuner_max or 1 local tuner_max=params.tuner_max or 1
local non_tuner_min=params.non_tuner_min or 1 local non_tuner_min=params.non_tuner_min or 1
local non_tuner_max=params.non_tuner_max or Synchro.Infinite local non_tuner_max=params.non_tuner_max or Synchro.Infinite
local base_mapper=params.base_mapper or Synchro.LevelMapper local base_mapper=params.base_mapper or Synchro.DefaultLevelMapper
local scheck=params.scheck or aux.TRUE
local e1=Effect.CreateEffect(c) local e1=Effect.CreateEffect(c)
-- e1:SetDescription(1164) -- e1:SetDescription(1164)
...@@ -3405,8 +3406,8 @@ function Synchro.AddSynchroProcedure(c,params) ...@@ -3405,8 +3406,8 @@ function Synchro.AddSynchroProcedure(c,params)
e1:SetCode(EFFECT_SPSUMMON_PROC) e1:SetCode(EFFECT_SPSUMMON_PROC)
e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE) e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e1:SetRange(LOCATION_EXTRA) e1:SetRange(LOCATION_EXTRA)
e1:SetCondition(Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper)) e1:SetCondition(Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,scheck))
e1:SetTarget(Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper)) e1:SetTarget(Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,scheck))
e1:SetOperation(Synchro.SynOperation()) e1:SetOperation(Synchro.SynOperation())
e1:SetValue(SUMMON_TYPE_SYNCHRO) e1:SetValue(SUMMON_TYPE_SYNCHRO)
c:RegisterEffect(e1) c:RegisterEffect(e1)
...@@ -3419,8 +3420,8 @@ function Synchro.AddSynchroProcedure(c,params) ...@@ -3419,8 +3420,8 @@ function Synchro.AddSynchroProcedure(c,params)
e2:SetCode(EFFECT_SPSUMMON_PROC) e2:SetCode(EFFECT_SPSUMMON_PROC)
e2:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE) e2:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e2:SetRange(LOCATION_EXTRA) e2:SetRange(LOCATION_EXTRA)
e2:SetCondition(Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper)) e2:SetCondition(Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,scheck))
e2:SetTarget(Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper)) e2:SetTarget(Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,scheck))
e2:SetOperation(Synchro.SynOperation()) e2:SetOperation(Synchro.SynOperation())
e2:SetValue(SUMMON_TYPE_SYNCHRO) e2:SetValue(SUMMON_TYPE_SYNCHRO)
c:RegisterEffect(e2) c:RegisterEffect(e2)
...@@ -3432,7 +3433,8 @@ function Synchro.FindValidSelection(candidates,target_level, ...@@ -3432,7 +3433,8 @@ function Synchro.FindValidSelection(candidates,target_level,
non_tuner_race,non_tuner_filter,tc, non_tuner_race,non_tuner_filter,tc,
tuner_min,tuner_max, tuner_min,tuner_max,
non_tuner_min,non_tuner_max, non_tuner_min,non_tuner_max,
base_mapper,pre_select,state) base_mapper,scheck,
pre_select,state)
Synchro.SortMaterials(candidates,tc,tuner_filter) Synchro.SortMaterials(candidates,tc,tuner_filter)
...@@ -3467,7 +3469,7 @@ function Synchro.FindValidSelection(candidates,target_level, ...@@ -3467,7 +3469,7 @@ function Synchro.FindValidSelection(candidates,target_level,
non_tuner_race,non_tuner_filter,tc, non_tuner_race,non_tuner_filter,tc,
tuner_min,tuner_max, tuner_min,tuner_max,
non_tuner_min,non_tuner_max, non_tuner_min,non_tuner_max,
base_mapper, base_mapper,scheck,
pre_select or {}, pre_select or {},
1, 1,
state or { -- initial state state or { -- initial state
...@@ -3490,34 +3492,43 @@ function Synchro.FindValidSelection(candidates,target_level, ...@@ -3490,34 +3492,43 @@ function Synchro.FindValidSelection(candidates,target_level,
) )
end end
--- Check if there exists a valid Synchro material selection from candidates (including current selected), --- Check if there exists a valid Synchro material selection via DFS,
--- satisfying tuner/non-tuner counts and total level, supporting multiple possible levels per card. --- pruning on tuner/non-tuner counts, total level sums, race constraints,
--- hand limits, dynamic level mappers, and optional synchro‐group checks.
--- ---
--- @param candidates Card[] -- Array of candidate material cards. --- @param candidates Card[] -- Candidate material cards.
--- @param target_level integer -- Required total level for Synchro Summon. --- @param target_level integer -- Required total level.
--- @param tuner_race integer -- race requirement for tuner --- @param tuner_race integer -- Bitmask of allowed tuner races.
--- @param tuner_filter fun(card:Card,tc:Card):boolean --- @param tuner_filter fun(mc:Card,tc:Card):boolean -- Tests if mc can be a Tuner.
--- -- Function to identify tuner materials. --- @param non_tuner_race integer -- Bitmask of allowed non-tuner races.
--- @param non_tuner_race integer -- race requirement for non tuner --- @param non_tuner_filter fun(mc:Card,tc:Card):boolean -- Tests if mc can be a non-Tuner.
--- @param non_tuner_filter fun(card:Card,tc:Card):boolean --- @param tc Card -- Synchro monster being summoned.
--- -- Function to identify non-tuner materials. --- @param tuner_min integer -- Minimum number of Tuners.
--- @param tc Card -- The Synchro monster being summoned. --- @param tuner_max integer|table -- Maximum number of Tuners.
--- @param tuner_min integer -- Minimum number of tuner materials required. --- @param non_tuner_min integer -- Minimum number of non-Tuners.
--- @param tuner_max integer|table -- Maximum number of tuner materials allowed. --- @param non_tuner_max integer|table -- Maximum number of non-Tuners.
--- @param non_tuner_min integer -- Minimum number of non-tuner materials required. --- @param base_mapper fun(mc:Card,tc:Card):integer[] -- Returns possible levels for mc.
--- @param non_tuner_max integer|table -- Maximum number of non-tuner materials allowed. --- @param scheck fun(selected:Card[]):boolean -- Optional card-group check (e.g. Judgment’s same-Attribute).
--- @param base_mapper fun(card:Card,tc:Card):integer[] --- @param selected Card[] -- Materials chosen so far.
--- -- Function returning possible levels for a card. --- @param index integer -- Next candidate index (1-based).
--- @param selected Card[] -- Currently selected material cards. --- @param state table -- DFS state:
--- @param index integer -- Current index in candidates for DFS (default 1). --- possible_sums table -- map[level_sum]=true of reachable sums.
--- @param state table -- DFS state table containing: --- tuner_count number -- how many Tuners so far.
--- -- sum (integer): current total level sum, --- non_tuner_count number-- how many non-Tuners so far.
--- -- tuner_count (integer): current tuner count, --- level_mapper fun -- current dynamic level mapping function.
--- -- non_tuner_count (integer): current non-tuner count. --- level_mapper_priority number
--- @param prune_indexes table --- hand_count_limit number
--- @return boolean -- True if a valid selection exists, false otherwise. --- hand_count number
--- genomix_race integer|nil
--- material_limit_filter fun
--- selected_roles table -- parallel array of Role.TUNER/NON_TUNER.
--- @param prune_indexes table -- Cutoff indices:
--- level_prune_index integer
--- hand_prune_index integer
--- race_prune_index integer
--- @return boolean True if a valid selection exists, false otherwise.
function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tc, function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,selected,index,state,prune_indexes) tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,scheck,selected,index,state,prune_indexes)
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
...@@ -3565,7 +3576,6 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f ...@@ -3565,7 +3576,6 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f
end end
end end
if index>#candidates then if index>#candidates then
-- check if target_level achievable exactly -- check if target_level achievable exactly
if state.possible_sums[target_level] and if state.possible_sums[target_level] and
...@@ -3581,7 +3591,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f ...@@ -3581,7 +3591,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f
local can_include,append_material_limit_filter = local can_include,append_material_limit_filter =
Synchro.CanIncludeMaterial( Synchro.CanIncludeMaterial(
mc,state,selected,tc, mc,state,selected,tc,
prune_tuner_filter,prune_non_tuner_filter, prune_tuner_filter,prune_non_tuner_filter,scheck,
prune_indexes,index prune_indexes,index
) )
...@@ -3600,7 +3610,8 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f ...@@ -3600,7 +3610,8 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f
tuner_race,tuner_filter, tuner_race,tuner_filter,
non_tuner_race,non_tuner_filter,tc, non_tuner_race,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max, tuner_min,tuner_max,non_tuner_min,non_tuner_max,
base_mapper,selected,index+1,branch_state,prune_indexes base_mapper,scheck,
selected,index+1,branch_state,prune_indexes
) then ) then
table.remove(selected) table.remove(selected)
return true return true
...@@ -3611,7 +3622,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f ...@@ -3611,7 +3622,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f
-- exclude branch -- exclude branch
if Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tc, if Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,selected,index+1,state,prune_indexes) then tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,scheck,selected,index+1,state,prune_indexes) then
return true return true
end end
...@@ -3619,7 +3630,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f ...@@ -3619,7 +3630,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_race,tuner_f
end end
--- Synchro condition generator using tuner/non-tuner min/max counts and filters --- Synchro condition generator using tuner/non-tuner min/max counts and filters
function Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper) function Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,scheck)
--- @param mg Group --- @param mg Group
return function(e,c,smat,mg,min,max) return function(e,c,smat,mg,min,max)
if c==nil then return true end if c==nil then return true end
...@@ -3647,19 +3658,19 @@ function Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_f ...@@ -3647,19 +3658,19 @@ function Synchro.SynCondition(tuner_race,tuner_filter,non_tuner_race,non_tuner_f
smat_states=Synchro.BuildStatesFromSelection(smat_arr,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,base_mapper,c,math.huge) smat_states=Synchro.BuildStatesFromSelection(smat_arr,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,base_mapper,c,math.huge)
for _,state in ipairs(smat_states) do for _,state in ipairs(smat_states) do
if Synchro.FindValidSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,c,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,smat_arr,state) then if Synchro.FindValidSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,c,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,scheck,smat_arr,state) then
return true return true
end end
end end
return false return false
else else
return Synchro.FindValidSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,c,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper) return Synchro.FindValidSelection(candidates,target_level,tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,c,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,scheck)
end end
end end
end end
function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper) function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max,base_mapper,scheck)
return function(e,tp,eg,ep,ev,re,r,rp,chk,tc,smat,mg,min,max) return function(e,tp,eg,ep,ev,re,r,rp,chk,tc,smat,mg,min,max)
if mg~=nil and #mg==min then if mg~=nil and #mg==min then
e:SetLabelObject(mg) e:SetLabelObject(mg)
...@@ -3708,7 +3719,7 @@ function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filt ...@@ -3708,7 +3719,7 @@ function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filt
for _,candidate in ipairs(cg_arr) do for _,candidate in ipairs(cg_arr) do
local can_include=Synchro.CanIncludeMaterial( local can_include=Synchro.CanIncludeMaterial(
candidate,state,sg_arr,tc, candidate,state,sg_arr,tc,
tuner_filter,non_tuner_filter tuner_filter,non_tuner_filter,scheck
) )
if can_include then if can_include then
...@@ -3739,7 +3750,7 @@ function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filt ...@@ -3739,7 +3750,7 @@ function Synchro.SynTarget(tuner_race,tuner_filter,non_tuner_race,non_tuner_filt
tuner_race,tuner_filter, tuner_race,tuner_filter,
non_tuner_race,non_tuner_filter,tc, non_tuner_race,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max, tuner_min,tuner_max,non_tuner_min,non_tuner_max,
base_mapper,test_selection,init_state) base_mapper,scheck,test_selection,init_state)
then then
addable:AddCard(candidate) addable:AddCard(candidate)
break break
...@@ -3798,7 +3809,7 @@ function Synchro.IsSelectionValid(selection,target_level,tuner_race,tuner_filter ...@@ -3798,7 +3809,7 @@ function Synchro.IsSelectionValid(selection,target_level,tuner_race,tuner_filter
selection, selection,
tuner_race,tuner_filter, tuner_race,tuner_filter,
non_tuner_race,non_tuner_filter, non_tuner_race,non_tuner_filter,
Synchro.LevelMapper, Synchro.DefaultLevelMapper,
tc,target_level tc,target_level
) )
for _,state in ipairs(states) do for _,state in ipairs(states) do
...@@ -3821,7 +3832,7 @@ end ...@@ -3821,7 +3832,7 @@ end
--- @param card Card -- The candidate material card. --- @param card Card -- The candidate material card.
--- @param tc Card -- The Synchro monster being summoned. --- @param tc Card -- The Synchro monster being summoned.
--- @return integer[] -- Array of possible level integers (e.g., {1} or {1,2}). --- @return integer[] -- Array of possible level integers (e.g., {1} or {1,2}).
function Synchro.LevelMapper(card,tc) function Synchro.DefaultLevelMapper(card,tc)
local level_dict={} local level_dict={}
local effs={card:IsHasEffect(EFFECT_SYNCHRO_LEVEL)} local effs={card:IsHasEffect(EFFECT_SYNCHRO_LEVEL)}
...@@ -4140,7 +4151,7 @@ end ...@@ -4140,7 +4151,7 @@ end
--- @return boolean can_include --- @return boolean can_include
--- @return function|nil append_material_limit_filter --- @return function|nil append_material_limit_filter
function Synchro.CanIncludeMaterial(mc,state,selected,tc, function Synchro.CanIncludeMaterial(mc,state,selected,tc,
prune_tuner_filter,prune_non_tuner_filter, prune_tuner_filter,prune_non_tuner_filter,scheck,
prune_indexes,index) prune_indexes,index)
prune_indexes=prune_indexes or { prune_indexes=prune_indexes or {
hand_prune_index=math.huge, hand_prune_index=math.huge,
...@@ -4149,14 +4160,22 @@ function Synchro.CanIncludeMaterial(mc,state,selected,tc, ...@@ -4149,14 +4160,22 @@ function Synchro.CanIncludeMaterial(mc,state,selected,tc,
} }
index=index or -1 index=index or -1
-- 1) global material‐limit check -- build a temporary Group = already selected cards + this mc
local sg=Group.FromCards(table.unpack(selected))
sg:AddCard(mc)
-- if either check fails on this partial group, drop this branch
if (not scheck(sg)) or (aux.AdditionalSCheck and not aux.AdditionalSCheck(sg)) then
return false,nil
end
-- global material‐limit check
if not state.material_limit_filter(nil,mc) then if not state.material_limit_filter(nil,mc) then
return false,nil return false,nil
end end
local append_material_limit_filter local append_material_limit_filter
-- 2) per-card EFFECT_TUNER_MATERIAL_LIMIT check against already‐selected -- per-card EFFECT_TUNER_MATERIAL_LIMIT check against already‐selected
local eff=mc:IsHasEffect(EFFECT_TUNER_MATERIAL_LIMIT) local eff=mc:IsHasEffect(EFFECT_TUNER_MATERIAL_LIMIT)
if eff then if eff then
assert(eff:GetTarget(),"EFFECT_TUNER_MATERIAL_LIMIT has no target function") assert(eff:GetTarget(),"EFFECT_TUNER_MATERIAL_LIMIT has no target function")
...@@ -4168,12 +4187,12 @@ function Synchro.CanIncludeMaterial(mc,state,selected,tc, ...@@ -4168,12 +4187,12 @@ function Synchro.CanIncludeMaterial(mc,state,selected,tc,
end end
end end
-- 3) must satisfy at least one of the tuner/non-tuner filters -- 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 if not (prune_tuner_filter(mc,tc) or prune_non_tuner_filter(mc,tc)) then
return false,nil return false,nil
end end
-- 4) hand‐location count limit -- hand‐location count limit
if mc:IsLocation(LOCATION_HAND) if mc:IsLocation(LOCATION_HAND)
and index>prune_indexes.hand_prune_index and index>prune_indexes.hand_prune_index
and state.hand_count>state.hand_count_limit then and state.hand_count>state.hand_count_limit then
......
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