Commit aff94e43 authored by Vury Leo's avatar Vury Leo

add Tatsunoko

parent 98f9633c
...@@ -3375,7 +3375,7 @@ end ...@@ -3375,7 +3375,7 @@ end
Synchro = {} Synchro = {}
-- Use this as the "infinite" maximum count -- Use this as the "infinite" maximum count
Synchro.Infinite={} Synchro.Infinite=math.huge
--- Add Synchro procedure effect to a card using a single params table --- Add Synchro procedure effect to a card using a single params table
--- @param c Card -- the Synchro monster card --- @param c Card -- the Synchro monster card
...@@ -3419,6 +3419,10 @@ function Synchro.FindValidSelection(candidates,target_level, ...@@ -3419,6 +3419,10 @@ function Synchro.FindValidSelection(candidates,target_level,
return c:IsCode(57261568,33541430,89818984) return c:IsCode(57261568,33541430,89818984)
end end
local function is_tatsunoko(c)
return c:IsCode(55863245)
end
table.sort(candidates,function(a,b) table.sort(candidates,function(a,b)
if is_mono(a)~=is_mono(b) then if is_mono(a)~=is_mono(b) then
return is_mono(a) -- monos first return is_mono(a) -- monos first
...@@ -3426,11 +3430,17 @@ function Synchro.FindValidSelection(candidates,target_level, ...@@ -3426,11 +3430,17 @@ function Synchro.FindValidSelection(candidates,target_level,
if is_flower(a)~=is_flower(b) then if is_flower(a)~=is_flower(b) then
return is_flower(a) -- then flowers return is_flower(a) -- then flowers
end end
if is_tatsunoko(a)~=is_tatsunoko(b) then
return is_tatsunoko(a) -- then tatsunoko
end
if tuner_filter(a,tc)~=tuner_filter(b,tc) then
return tuner_filter(a,tc) -- then tuner
end
-- otherwise normals: sort descending by level -- otherwise normals: sort descending by level
return a:GetLevel()>b:GetLevel() return a:GetLevel()>b:GetLevel()
end) end)
-- 2) Find the index of the last dynamic card -- 2) Find the index of the last level card
local level_prune_index=0 local level_prune_index=0
for i, c in ipairs(candidates) do for i, c in ipairs(candidates) do
if is_mono(c) or is_flower(c) then if is_mono(c) or is_flower(c) then
...@@ -3438,6 +3448,14 @@ function Synchro.FindValidSelection(candidates,target_level, ...@@ -3438,6 +3448,14 @@ function Synchro.FindValidSelection(candidates,target_level,
end end
end end
-- 3) Find the index of the last hand card
local hand_prune_index=0
for i, c in ipairs(candidates) do
if is_tatsunoko(c) then
hand_prune_index=i
end
end
-- 3) Invoke the core DFS, passing last_dyn along -- 3) Invoke the core DFS, passing last_dyn along
return Synchro.CanCompleteSelection( return Synchro.CanCompleteSelection(
candidates,target_level, candidates,target_level,
...@@ -3453,9 +3471,12 @@ function Synchro.FindValidSelection(candidates,target_level, ...@@ -3453,9 +3471,12 @@ function Synchro.FindValidSelection(candidates,target_level,
non_tuner_count=0, non_tuner_count=0,
level_mapper=base_mapper, level_mapper=base_mapper,
level_mapper_priority=0, level_mapper_priority=0,
hand_count_limit=0,
hand_count=0,
}, },
{ {
level_prune_index=level_prune_index level_prune_index=level_prune_index,
hand_prune_index=hand_prune_index,
} }
) )
end end
...@@ -3489,8 +3510,8 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t ...@@ -3489,8 +3510,8 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t
--- Mono Synchron (priority=2) > Flower Cardian (1) > normal (0) --- Mono Synchron (priority=2) > Flower Cardian (1) > normal (0)
local mapper = state.level_mapper local mapper = state.level_mapper
if Synchro.ExceedsMax(state.tuner_count,tuner_max) then return false end if state.tuner_count>tuner_max then return false end
if Synchro.ExceedsMax(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>#candidates then if index>#candidates then
-- check if target_level achievable exactly -- check if target_level achievable exactly
...@@ -3511,10 +3532,17 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t ...@@ -3511,10 +3532,17 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t
local mc=candidates[index] local mc=candidates[index]
local tuner_inc=tuner_filter(mc,tc) and 1 or 0 local tuner_inc=tuner_filter(mc,tc) and 1 or 0
local non_tuner_inc=non_tuner_filter(mc,tc) and 1 or 0 local non_tuner_inc=non_tuner_filter(mc,tc) and 1 or 0
local hand_inc=mc:IsLocation(LOCATION_HAND) and 1 or 0
-- include branch -- include branch
local variants={} local variants={}
-- build inclusion variants if prune not blocking
-- before/at hand_prune_index: allow any hand inclusion (no limit)
-- after hand_prune_index: enforce state.hand_count + hand_inc <= hand_max
local can_include=(index<=prune_indexes.hand_prune_index) or (state.hand_count+hand_inc<=state.hand_count_limit)
if can_include then
-- 1) MonoSynchron branch (priority<2 → first Mono; priority==2 → full Mono) -- 1) MonoSynchron branch (priority<2 → first Mono; priority==2 → full Mono)
if mc:IsCode(56897896) then if mc:IsCode(56897896) then
if state.level_mapper_priority<2 then if state.level_mapper_priority<2 then
...@@ -3550,16 +3578,18 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t ...@@ -3550,16 +3578,18 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t
end end
end end
if not mc:IsCode(56897896) then --- mono is mandatory so it can not be include Normal
--- Tatsunoko never harm to enable
if not mc:IsCode(56897896,55863245) then
-- 1) Normal include branch -- 1) Normal include branch
local lvls=mapper(mc,tc) local lvls=mapper(mc,tc)
local sums_norm=Synchro.UpdatepossibleSums(state.possible_sums,lvls,prune_level) local sums_norm=Synchro.UpdatepossibleSums(state.possible_sums,lvls,prune_level)
if next(sums_norm) then if next(sums_norm) then
table.insert(variants,{possible_sums=sums_norm,level_mapper=mapper}) table.insert(variants,{possible_sums=sums_norm})
end end
end end
-- 2) override if Flower Cardian -- override if Flower Cardian
if mc:IsCode(57261568,33541430,89818984) then if mc:IsCode(57261568,33541430,89818984) then
if state.level_mapper_priority<1 then if state.level_mapper_priority<1 then
local cnt=#selected+1 local cnt=#selected+1
...@@ -3572,13 +3602,26 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t ...@@ -3572,13 +3602,26 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t
end end
end end
-- Tatsunoko effect: include and grant hand material slot
if mc:IsCode(55863245) then
-- include Tatsunoko's own level contributions
local lvls=mapper(mc,tc)
local sums_tats=Synchro.UpdatepossibleSums(state.possible_sums,lvls,prune_level)
table.insert(variants,{
possible_sums=sums_tats,
hand_count_limit=1,
})
end
for _,var in ipairs(variants) do for _,var in ipairs(variants) do
local new_state={ local new_state={
possible_sums=var.possible_sums, possible_sums=var.possible_sums,
tuner_count=state.tuner_count+tuner_inc, tuner_count=state.tuner_count+tuner_inc,
non_tuner_count=state.non_tuner_count+non_tuner_inc, non_tuner_count=state.non_tuner_count+non_tuner_inc,
level_mapper=var.level_mapper, level_mapper=var.level_mapper or state.level_mapper,
level_mapper_priority=var.level_mapper_priority, level_mapper_priority=var.level_mapper_priority or state.level_mapper_priority,
hand_count_limit=var.hand_count_limit or state.hand_count_limit,
hand_count=state.hand_count+hand_inc,
} }
table.insert(selected,mc) table.insert(selected,mc)
...@@ -3594,6 +3637,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t ...@@ -3594,6 +3637,7 @@ function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_t
end end
table.remove(selected) table.remove(selected)
end end
end
-- exclude branch -- exclude branch
if Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_tuner_filter,tc, if Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_tuner_filter,tc,
...@@ -3736,18 +3780,6 @@ function Synchro.SynOperation() ...@@ -3736,18 +3780,6 @@ function Synchro.SynOperation()
end end
end end
function Synchro.ExceedsMax(count,max)
if max==Synchro.Infinite then return false end
return count>max
end
function Synchro.GetDisplayMax(tuner_max,non_tuner_max)
if tuner_max==Synchro.Infinite or non_tuner_max==Synchro.Infinite then
return 99
end
return tuner_max+non_tuner_max
end
function Synchro.IsSelectionValid(selection,target_level,tuner_filter,non_tuner_filter,tc,tuner_min,tuner_max,non_tuner_min,non_tuner_max) function Synchro.IsSelectionValid(selection,target_level,tuner_filter,non_tuner_filter,tc,tuner_min,tuner_max,non_tuner_min,non_tuner_max)
local states=Synchro.BuildStatesFromSelection( local states=Synchro.BuildStatesFromSelection(
selection, selection,
...@@ -3755,18 +3787,16 @@ function Synchro.IsSelectionValid(selection,target_level,tuner_filter,non_tuner_ ...@@ -3755,18 +3787,16 @@ function Synchro.IsSelectionValid(selection,target_level,tuner_filter,non_tuner_
Synchro.LevelMapper, Synchro.LevelMapper,
tc,0xff tc,0xff
) )
for _,state in ipairs(states)do for _,state in ipairs(states) do
if not Synchro.ExceedsMax(state.tuner_count,tuner_max) then if state.tuner_count<=tuner_max
if not Synchro.ExceedsMax(state.non_tuner_count,non_tuner_max) then and state.non_tuner_count<=non_tuner_max
if state.possible_sums[target_level] and state.possible_sums[target_level]
and state.tuner_count>=tuner_min and state.tuner_count>=tuner_min
and state.non_tuner_count>=non_tuner_min and state.non_tuner_count>=non_tuner_min
then then
return true return true
end end
end end
end
end
return false return false
end end
...@@ -3827,16 +3857,22 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte ...@@ -3827,16 +3857,22 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte
non_tuner_count=0, non_tuner_count=0,
level_mapper=base_mapper, level_mapper=base_mapper,
level_mapper_priority=0, level_mapper_priority=0,
hand_count_limit=0,
hand_count=0,
} }
} }
-- 1) Sort candidates: Mono first, then Flower, then normals -- 1) Sort candidates: Mono first, then Flower, then Tatsunoko then normals
local function is_mono(c) local function is_mono(c)
return c:IsCode(56897896) return c:IsCode(56897896)
end end
local function is_flower(c) local function is_flower(c)
return c:IsCode(57261568, 33541430, 89818984) return c:IsCode(57261568,33541430,89818984)
end
local function is_tatsunoko(c)
return c:IsCode(55863245)
end end
table.sort(selection,function(a,b) table.sort(selection,function(a,b)
...@@ -3846,6 +3882,12 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte ...@@ -3846,6 +3882,12 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte
if is_flower(a)~=is_flower(b) then if is_flower(a)~=is_flower(b) then
return is_flower(a) -- then flowers return is_flower(a) -- then flowers
end end
if is_tatsunoko(a)~=is_tatsunoko(b) then
return is_tatsunoko(a) -- then tatsunoko
end
if tuner_filter(a,tc)~=tuner_filter(b,tc) then
return tuner_filter(a,tc) -- then tuner
end
-- otherwise normals: sort descending by level -- otherwise normals: sort descending by level
return a:GetLevel()>b:GetLevel() return a:GetLevel()>b:GetLevel()
end) end)
...@@ -3856,6 +3898,7 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte ...@@ -3856,6 +3898,7 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte
for _,st in ipairs(states) do for _,st in ipairs(states) do
local tuner_inc=tuner_filter(card,tc) and 1 or 0 local tuner_inc=tuner_filter(card,tc) and 1 or 0
local non_tuner_inc=non_tuner_filter(card,tc) and 1 or 0 local non_tuner_inc=non_tuner_filter(card,tc) and 1 or 0
local hand_inc=card:IsLocation(LOCATION_HAND) and 1 or 0
local mapper=st.level_mapper local mapper=st.level_mapper
-- 1) MonoSynchron branch (priority<2 → first Mono; priority==2 → full Mono) -- 1) MonoSynchron branch (priority<2 → first Mono; priority==2 → full Mono)
...@@ -3877,6 +3920,8 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte ...@@ -3877,6 +3920,8 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte
non_tuner_count=st.non_tuner_count+non_tuner_inc, non_tuner_count=st.non_tuner_count+non_tuner_inc,
level_mapper=mono_mapper, level_mapper=mono_mapper,
level_mapper_priority=2, level_mapper_priority=2,
hand_count_limit=st.hand_count_limit,
hand_count=st.hand_count+hand_inc,
}) })
elseif st.level_mapper_priority==2 then elseif st.level_mapper_priority==2 then
-- second (or later) Mono: full override—all cards=Level 1 -- second (or later) Mono: full override—all cards=Level 1
...@@ -3889,6 +3934,8 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte ...@@ -3889,6 +3934,8 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte
non_tuner_count=st.non_tuner_count+non_tuner_inc, non_tuner_count=st.non_tuner_count+non_tuner_inc,
level_mapper=full_mapper, level_mapper=full_mapper,
level_mapper_priority=2, -- stays in Mono mode level_mapper_priority=2, -- stays in Mono mode
hand_count_limit=st.hand_count_limit,
hand_count=st.hand_count+hand_inc,
}) })
end end
end end
...@@ -3904,6 +3951,8 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte ...@@ -3904,6 +3951,8 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte
non_tuner_count=st.non_tuner_count+non_tuner_inc, non_tuner_count=st.non_tuner_count+non_tuner_inc,
level_mapper=mapper, level_mapper=mapper,
level_mapper_priority=st.level_mapper_priority, level_mapper_priority=st.level_mapper_priority,
hand_count_limit=st.hand_count_limit,
hand_count=st.hand_count+hand_inc,
}) })
end end
end end
...@@ -3918,12 +3967,31 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte ...@@ -3918,12 +3967,31 @@ function Synchro.BuildStatesFromSelection(selection,tuner_filter,non_tuner_filte
non_tuner_count=st.non_tuner_count+non_tuner_inc, non_tuner_count=st.non_tuner_count+non_tuner_inc,
level_mapper=function() return {2} end, level_mapper=function() return {2} end,
level_mapper_priority=1, level_mapper_priority=1,
hand_count_limit=st.hand_count_limit,
hand_count=st.hand_count+hand_inc,
}) })
end end
end end
-- increase hand count limit if tatsunoko
if card:IsCode(55863245) then
-- include Tatsunoko's own level contributions
local lvls=mapper(card,tc)
local sums_tats=Synchro.UpdatepossibleSums(st.possible_sums,lvls,prune_level)
table.insert(next_states,{
possible_sums=sums_tats,
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,
hand_count_limit=1,
hand_count=st.hand_count+hand_inc,
})
end
end end
states=next_states states=next_states
if #states==0 then if #states==0 then
break break
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