Commit e31bc28c authored by Vury Leo's avatar Vury Leo

lint

parent 4451e60b
--アームズ・エイド
function c29071332.initial_effect(c)
--synchro summon
aux.AddSynchroProcedure(c,nil,aux.NonTuner(nil),1)
Synchro.AddSynchroProcedure(c)
c:EnableReviveLimit()
--equip
local e1=Effect.CreateEffect(c)
......
......@@ -3454,12 +3454,12 @@ Synchro.Infinite={}
--- @param params? table -- parameters table with keys: f1,f2,minc,maxc
function Synchro.AddSynchroProcedure(c,params)
params=params or {}
local tunerFilter=params.tunerFilter or function(mc,tc) return mc:IsType(TYPE_TUNER) end
local nonTunerFilter=params.nonTunerFilter or function(mc,tc) return not mc:IsType(TYPE_TUNER) end
local tunerMin=params.tunerMin or 1
local tunerMax=params.tunerMax or 1
local nonTunerMin=params.nonTunerMin or 1
local nonTunerMax=params.nonTunerMax or Synchro.Infinite
local tuner_filter=params.tuner_filter or function(mc,tc) return mc:IsType(TYPE_TUNER) end
local non_tuner_filter=params.non_tuner_filter or function(mc,tc) return not mc:IsType(TYPE_TUNER) end
local tuner_min=params.tuner_min or 1
local tuner_max=params.tuner_max or 1
local non_tuner_min=params.non_tuner_min or 1
local non_tuner_max=params.non_tuner_max or Synchro.Infinite
local e1=Effect.CreateEffect(c)
e1:SetDescription(1164)
......@@ -3467,8 +3467,8 @@ function Synchro.AddSynchroProcedure(c,params)
e1:SetCode(EFFECT_SPSUMMON_PROC)
e1:SetProperty(EFFECT_FLAG_CANNOT_DISABLE+EFFECT_FLAG_UNCOPYABLE)
e1:SetRange(LOCATION_EXTRA)
e1:SetCondition(Synchro.SynCondition(tunerFilter,nonTunerFilter,tunerMin,tunerMax,nonTunerMin,nonTunerMax))
e1:SetTarget(Synchro.SynTarget(tunerFilter,nonTunerFilter,tunerMin,tunerMax,nonTunerMin,nonTunerMax))
e1:SetCondition(Synchro.SynCondition(tuner_filter,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max))
e1:SetTarget(Synchro.SynTarget(tuner_filter,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max))
e1:SetOperation(Synchro.SynOperation())
e1:SetValue(SUMMON_TYPE_SYNCHRO)
c:RegisterEffect(e1)
......@@ -3478,84 +3478,73 @@ end
--- satisfying tuner/non-tuner counts and total level, supporting multiple possible levels per card.
---
--- @param candidates Card[] -- Array of candidate material cards.
--- @param targetLevel integer -- Required total level for Synchro Summon.
--- @param tunerFilter fun(card:Card,targetCard:Card):boolean
--- @param target_level integer -- Required total level for Synchro Summon.
--- @param tuner_filter fun(card:Card,tc:Card):boolean
--- -- Function to identify tuner materials.
--- @param nonTunerFilter fun(card:Card,targetCard:Card):boolean
--- @param non_tuner_filter fun(card:Card,tc:Card):boolean
--- -- Function to identify non-tuner materials.
--- @param targetCard Card -- The Synchro monster being summoned.
--- @param tunerMin integer -- Minimum number of tuner materials required.
--- @param tunerMax integer|table -- Maximum number of tuner materials allowed.
--- @param nonTunerMin integer -- Minimum number of non-tuner materials required.
--- @param nonTunerMax integer|table -- Maximum number of non-tuner materials allowed.
--- @param levelMapper fun(card:Card,targetCard:Card):integer[]
--- @param tc Card -- The Synchro monster being summoned.
--- @param tuner_min integer -- Minimum number of tuner materials required.
--- @param tuner_max integer|table -- Maximum number of tuner materials allowed.
--- @param non_tuner_min integer -- Minimum number of non-tuner materials required.
--- @param non_tuner_max integer|table -- Maximum number of non-tuner materials allowed.
--- @param levelMapper 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:
--- -- sum (integer): current total level sum,
--- -- tunerCount (integer): current tuner count,
--- -- nonTunerCount (integer): current non-tuner count.
--- -- tuner_count (integer): current tuner count,
--- -- non_tuner_count (integer): current non-tuner count.
--- @return boolean -- True if a valid selection exists, false otherwise.
function Synchro.CanCompleteSelection(candidates,targetLevel,tunerFilter,nonTunerFilter,targetCard,
tunerMin,tunerMax,nonTunerMin,nonTunerMax,levelMapper,selected,index,state)
index = index or 1
selected = selected or {}
state = state or {
possibleSums = {[0]=true},
tunerCount = 0,
nonTunerCount = 0,
function Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,levelMapper,selected,index,state)
index=index or 1
selected=selected or {}
state=state or {
possible_sums={[0]=true},
tuner_count=0,
non_tuner_count=0,
}
if Synchro.ExceedsMax(state.tunerCount,tunerMax) then return false end
if Synchro.ExceedsMax(state.nonTunerCount,nonTunerMax) then return false end
if Synchro.ExceedsMax(state.tuner_count,tuner_max) then return false end
if Synchro.ExceedsMax(state.non_tuner_count,non_tuner_max) then return false end
if index>#candidates then
-- check if targetLevel achievable exactly
if state.possibleSums[targetLevel] and
state.tunerCount>=tunerMin and
state.nonTunerCount>=nonTunerMin then
-- check if target_level achievable exactly
if state.possible_sums[target_level] and
state.tuner_count>=tuner_min and
state.non_tuner_count>=non_tuner_min then
return true
end
return false
end
local card = candidates[index]
local lvls = levelMapper(card,targetCard)
local tunerInc=tunerFilter(card,targetCard) and 1 or 0
local nonTunerInc=nonTunerFilter(card,targetCard) and 1 or 0
local newPossibleSums=Synchro.UpdatePossibleSums(state.possibleSums, lvls, targetLevel)
local mc=candidates[index]
local lvls=levelMapper(mc,tc)
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 newpossible_sums=Synchro.Updatepossible_sums(state.possible_sums,lvls,target_level)
if next(newPossibleSums) then
-- push state
local prevPossibleSums = state.possibleSums
local prevTunerCount = state.tunerCount
local prevNonTunerCount = state.nonTunerCount
if next(newpossible_sums) then
local new_state={
possible_sums=newpossible_sums,
tuner_count=state.tuner_count+tuner_inc,
non_tuner_count=state.non_tuner_count+non_tuner_inc,
}
state.possibleSums = newPossibleSums
state.tunerCount = state.tunerCount + tunerInc
state.nonTunerCount = state.nonTunerCount + nonTunerInc
table.insert(selected, card)
if Synchro.CanCompleteSelection(candidates,targetLevel,tunerFilter,nonTunerFilter,targetCard,
tunerMin,tunerMax,nonTunerMin,nonTunerMax,levelMapper,selected,index+1,state) then
table.insert(selected,mc)
if Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,levelMapper,selected,index+1,new_state) then
table.remove(selected)
-- pop state
state.possibleSums = prevPossibleSums
state.tunerCount = prevTunerCount
state.nonTunerCount = prevNonTunerCount
return true
end
table.remove(selected)
-- pop state
state.possibleSums = prevPossibleSums
state.tunerCount = prevTunerCount
state.nonTunerCount = prevNonTunerCount
end
-- Option: exclude this card
if Synchro.CanCompleteSelection(candidates,targetLevel,tunerFilter,nonTunerFilter,targetCard,
tunerMin,tunerMax,nonTunerMin,nonTunerMax,levelMapper,selected,index+1,state) then
if Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_tuner_filter,tc,
tuner_min,tuner_max,non_tuner_min,non_tuner_max,levelMapper,selected,index+1,state) then
return true
end
......@@ -3563,23 +3552,23 @@ function Synchro.CanCompleteSelection(candidates,targetLevel,tunerFilter,nonTune
end
--- Synchro condition generator using tuner/non-tuner min/max counts and filters
function Synchro.SynCondition(tunerFilter,nonTunerFilter,tunerMin,tunerMax,nonTunerMin,nonTunerMax)
function Synchro.SynCondition(tuner_filter,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max)
return function(e,c,smat,mg,min,max)
if c==nil then return true end
if c:IsType(TYPE_PENDULUM) and c:IsFaceup() then return false end
local targetLevel=c:GetLevel()
local target_level=c:GetLevel()
mg=mg or Duel.GetMatchingGroup(Card.IsCanBeSynchroMaterial,c:GetControler(),LOCATION_MZONE+LOCATION_HAND,0,nil)
local candidates={}
for card in aux.Next(mg) do
table.insert(candidates,card)
for mc in aux.Next(mg) do
table.insert(candidates,mc)
end
return Synchro.CanCompleteSelection(candidates,targetLevel,tunerFilter,nonTunerFilter,c,tunerMin,tunerMax,nonTunerMin,nonTunerMax,Synchro.LevelMapper)
return Synchro.CanCompleteSelection(candidates,target_level,tuner_filter,non_tuner_filter,c,tuner_min,tuner_max,non_tuner_min,non_tuner_max,Synchro.LevelMapper)
end
end
function Synchro.SynTarget(tunerFilter,nonTunerFilter,tunerMin,tunerMax,nonTunerMin,nonTunerMax)
function Synchro.SynTarget(tuner_filter,non_tuner_filter,tuner_min,tuner_max,non_tuner_min,non_tuner_max)
return function(e,tp,eg,ep,ev,re,r,rp,chk,tc,smat,mg,min,max)
mg=mg or Duel.GetMatchingGroup(function(mc) return mc:IsCanBeSynchroMaterial(mc,tc) end,tc:GetOwner(),LOCATION_MZONE+LOCATION_HAND,0,nil)
local sg=Group.CreateGroup()
......@@ -3594,12 +3583,12 @@ function Synchro.SynTarget(tunerFilter,nonTunerFilter,tunerMin,tunerMax,nonTuner
local addable=Group.CreateGroup()
local sg_arr=GroupToArray(sg)
local cg_arr=GroupToArray(mg-sg)
local targetLevel=tc:GetLevel()
local target_level=tc:GetLevel()
for _, candidate in ipairs(cg_arr) do
-- simulate adding candidate to sg_arr
local testSelection = {}
for _, card in ipairs(sg_arr) do table.insert(testSelection, card) end
table.insert(testSelection, 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 = {}
......@@ -3611,18 +3600,18 @@ function Synchro.SynTarget(tunerFilter,nonTunerFilter,tunerMin,tunerMax,nonTuner
if Synchro.CanCompleteSelection(
rest_candidates,
targetLevel,
tunerFilter,
nonTunerFilter,
target_level,
tuner_filter,
non_tuner_filter,
tc,
tunerMin,
tunerMax,
nonTunerMin,
nonTunerMax,
tuner_min,
tuner_max,
non_tuner_min,
non_tuner_max,
Synchro.LevelMapper,
testSelection,
test_selection,
1,
Synchro.BuildStateFromSelection(testSelection,tunerFilter,nonTunerFilter,Synchro.LevelMapper,tc,targetLevel)
Synchro.BuildStateFromSelection(test_selection,tuner_filter,non_tuner_filter,Synchro.LevelMapper,tc,target_level)
) then
addable:AddCard(candidate)
end
......@@ -3632,9 +3621,9 @@ function Synchro.SynTarget(tunerFilter,nonTunerFilter,tunerMin,tunerMax,nonTuner
break
end
local finishable=Synchro.IsSelectionValid(sg_arr,targetLevel,tunerFilter,nonTunerFilter,tc,tunerMin,tunerMax,nonTunerMin,nonTunerMax)
local finishable=Synchro.IsSelectionValid(sg_arr,target_level,tuner_filter,non_tuner_filter,tc,tuner_min,tuner_max,non_tuner_min,non_tuner_max)
local picked=Group.SelectUnselect(addable,sg,tp,finishable,true,tunerMin+nonTunerMin,Synchro.GetDisplayMax(tunerMax,nonTunerMax))
local picked=Group.SelectUnselect(addable,sg,tp,finishable,true,tuner_min+non_tuner_min,Synchro.GetDisplayMax(tuner_max,non_tuner_max))
if not picked then
-- user clicked Complete
......@@ -3675,22 +3664,22 @@ function Synchro.ExceedsMax(count,max)
return count>max
end
function Synchro.GetDisplayMax(tunerMax,nonTunerMax)
if tunerMax==Synchro.Infinite or nonTunerMax==Synchro.Infinite then
function Synchro.GetDisplayMax(tuner_max,non_tuner_max)
if tuner_max==Synchro.Infinite or non_tuner_max==Synchro.Infinite then
return 99
end
return tunerMax+nonTunerMax
return tuner_max+non_tuner_max
end
function Synchro.IsSelectionValid(selection,targetLevel,tunerFilter,nonTunerFilter,targetCard,tunerMin,tunerMax,nonTunerMin,nonTunerMax)
local state=Synchro.BuildStateFromSelection(selection,tunerFilter,nonTunerFilter,Synchro.LevelMapper,targetCard,targetLevel)
-- check if targetLevel achievable exactly
if Synchro.ExceedsMax(state.tunerCount,tunerMax) then return false end
if Synchro.ExceedsMax(state.nonTunerCount,nonTunerMax) then return false end
function Synchro.IsSelectionValid(selection,target_level,tuner_filter,non_tuner_filter,tc,tuner_min,tuner_max,non_tuner_min,non_tuner_max)
local state=Synchro.BuildStateFromSelection(selection,tuner_filter,non_tuner_filter,Synchro.LevelMapper,tc,target_level)
-- check if target_level achievable exactly
if Synchro.ExceedsMax(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.possibleSums[targetLevel] and
state.tunerCount>=tunerMin and
state.nonTunerCount>=nonTunerMin then
if state.possible_sums[target_level] and
state.tuner_count>=tuner_min and
state.non_tuner_count>=non_tuner_min then
return true
end
return false
......@@ -3698,16 +3687,16 @@ end
--- Returns a list of possible levels this card can be treated as when used as Synchro material.
--- @param card Card -- The candidate material card.
--- @param targetCard 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}).
function Synchro.LevelMapper(card,targetCard)
function Synchro.LevelMapper(card,tc)
Debug.Message(string.format("lvel mapper for %d",card:GetCode()))
local levelDict={}
local effs={card:IsHasEffect(EFFECT_SYNCHRO_LEVEL)}
Debug.Message(string.format("lvel mapper for %d, effs %d",card:GetCode(),#effs))
if #effs>0 then
local val=effs[1]:GetValue()(effs[1],targetCard)
local val=effs[1]:GetValue()(effs[1],tc)
Debug.Message(string.format("lvel mapper for %d, effs %d",card:GetCode(),#effs))
if type(val)=="table" then
for _, v in ipairs(val) do
......@@ -3735,12 +3724,12 @@ function Synchro.LevelMapper(card,targetCard)
return levels
end
function Synchro.UpdatePossibleSums(possibleSums, cardLevels, targetLevel)
local newSums = {}
for sum, _ in pairs(possibleSums) do
function Synchro.Updatepossible_sums(possible_sums, cardLevels, target_level)
local newSums={}
for sum, _ in pairs(possible_sums) do
for _, lvl in ipairs(cardLevels) do
local newSum = sum + lvl
if newSum <= targetLevel then
local newSum=sum+lvl
if newSum<=target_level then
newSums[newSum] = true
end
end
......@@ -3748,24 +3737,24 @@ function Synchro.UpdatePossibleSums(possibleSums, cardLevels, targetLevel)
return newSums
end
function Synchro.BuildStateFromSelection(sg_arr, tunerFilter, nonTunerFilter, levelMapper, targetCard, targetLevel)
local possibleSums={[0]=true}
local tunerCount=0
local nonTunerCount=0
function Synchro.BuildStateFromSelection(sg_arr, tuner_filter, non_tuner_filter, levelMapper, tc, target_level)
local possible_sums={[0]=true}
local tuner_count=0
local non_tuner_count=0
for _,card in ipairs(sg_arr) do
local levels=levelMapper(card,targetCard)
possibleSums=Synchro.UpdatePossibleSums(possibleSums,levels,targetLevel)
if next(possibleSums)==nil then
local levels=levelMapper(card,tc)
possible_sums=Synchro.Updatepossible_sums(possible_sums,levels,target_level)
if next(possible_sums)==nil then
-- no possible sums from current selection, invalid state
assert(false)
return {}
end
if tunerFilter(card,targetCard) then
tunerCount=tunerCount+1
elseif nonTunerFilter(card,targetCard) then
nonTunerCount=nonTunerCount+1
if tuner_filter(card,tc) then
tuner_count=tuner_count+1
elseif non_tuner_filter(card,tc) then
non_tuner_count=non_tuner_count+1
else
assert(false)
return {} -- invalid material type
......@@ -3773,8 +3762,30 @@ function Synchro.BuildStateFromSelection(sg_arr, tunerFilter, nonTunerFilter, le
end
return {
possibleSums=possibleSums,
tunerCount=tunerCount,
nonTunerCount=nonTunerCount,
possible_sums=possible_sums,
tuner_count=tuner_count,
non_tuner_count=non_tuner_count,
}
end
function Synchro.DeepcopyState(base_state)
local new_state={}
-- Copy primitive flags and counters
new_state.tuner_count=base_state and base_state.tuner_count or 0
new_state.non_tuner_count=base_state and base_state.non_tuner_count or 0
-- Copy or create possible sums table
if base_state and base_state.possible_sums then
new_state.possible_sums={}
for k,v in pairs(base_state.possible_sums) do
new_state.possible_sums[k]=v
end
else
new_state.possible_sums={[0]=true}
end
-- Copy other as needed
return new_state
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