Commit e31bc28c authored by Vury Leo's avatar Vury Leo

lint

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