Add challenge

This commit is contained in:
Emik 2026-02-23 17:01:11 +01:00
parent b808184091
commit 8f8a2402dc
Signed by: emik
GPG key ID: 6B0CD72A5E503BDF
3 changed files with 137 additions and 66 deletions

View file

@ -350,6 +350,7 @@ return {
misc = {
challenge_names = {
c_Roland_Jokerful = "Jokerful",
c_Roland_Ornate = "Ornate",
c_Roland_Pastries = "Sweet Pastries",
-- c_Roland_Surgery = "Surgery",
},
@ -371,6 +372,7 @@ return {
},
v_text = {
ch_c_Roland_Jokerful = {"Only the {C:common}default Joker{} can appear in shops"},
ch_c_Roland_Ornate = {"Anything vanilla is banned"},
ch_c_Roland_Pastries = {"All blinds, cards, and tags are of {C:gold}Bakery{} or {C:blue}Roland"},
-- ch_c_Roland_Oops_All_Tranquilizers = {"Non-showdown blinds are replaced with {C:blue}The Tranquilizer"},
-- ch_c_Roland_Linked_Rank = {"Cards of the same rank share state"},

View file

@ -1,7 +1,11 @@
local f, q = unpack(... or require "lib.shared")
local jokerful = {banned_cards = {}}
local pastries = {banned_cards = {}, banned_tags = {}, banned_other = {}}
-- local surgery = {banned_other = {}}
local function bans()
return {banned_cards = {}, banned_tags = {}, banned_other = {}}
end
local jokerful, pastries, vanillas = bans(), bans(), bans()
-- local surgery = bans()
local function adder(tbl)
return function(v)
table.insert(tbl, {id = v.key})
@ -24,6 +28,12 @@ local function is_joker(v)
return v.set == "Joker"
end
local function is_vanilla(v)
return v.set and not v.mod and f(G.P_CENTERS):concat(G.P_CARDS, G.P_TAGS):any(function(c)
return c.mod and c.set == v.set
end)
end
SMODS.Challenge {
key = "Jokerful",
rules = {custom = {{id = "Roland_Jokerful"}}},
@ -31,6 +41,13 @@ SMODS.Challenge {
pronouns = "he_him",
}
SMODS.Challenge {
key = "Ornate",
rules = {custom = {{id = "Roland_Ornate"}}},
restrictions = vanillas,
pronouns = "any_all",
}
SMODS.Challenge {
key = "Pastries",
rules = {custom = {{id = "Roland_Pastries"}}},
@ -54,6 +71,9 @@ SMODS.Challenge {
q(function()
f {
{G.P_CENTERS, is_joker, jokerful.banned_cards},
{G.P_TAGS, is_vanilla, vanillas.banned_tags},
{G.P_BLINDS, is_vanilla, vanillas.banned_other},
{G.P_CENTERS, is_vanilla, vanillas.banned_cards},
{G.P_TAGS, is_banned_from_pastry, pastries.banned_tags},
{G.P_BLINDS, is_banned_from_pastry, pastries.banned_other},
{G.P_CENTERS, is_center_banned_from_pastry, pastries.banned_cards},

View file

@ -15,6 +15,25 @@ if not f then
end
end
---@type F
local none
---@generic K, V
---@param tbl table<K, V>
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)
---@return fun(tbl: table<K, V>, key: K): K, V
---@return K
---@return V
local function autopairs(tbl, fpairs)
return (fpairs or tbl[#tbl] and ipairs or pairs)(tbl)
end
---@param any any
---@return boolean
local function is_f(any)
return type(any) == "table" and any.from == f.from and any.new == f.new
end
--- Always returns nil.
---@return nil
function f.noop()
@ -74,14 +93,99 @@ function f.new(fnext)
return ret
end
--- Creates an enumeration.
---@generic K, V
---@param tbl table<K, V>
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)
---@return fun(tbl: table<K, V>, key: K): K, V
---@return K
---@return V
local function autopairs(tbl, fpairs)
return (fpairs or tbl[#tbl] and ipairs or pairs)(tbl)
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K?, V?)
---@param step? nil
---@return F | { [K]: V }
---@overload fun(tbl: number, fpairs?: number, step?: number): F | { [number]: number }
---@overload fun(tbl: string|K): fun(table: { [string|K]: V }): V
---@overload fun(tbl: false): fun(): false
---@overload fun(tbl: true): fun(): true
---@overload fun(tbl: nil): F
function f.from(tbl, fpairs, step)
if tbl == true then
return f.tru
elseif tbl == false then
return f.fals
elseif tbl == nil then
return none
end
local tbl_type = type(tbl)
if tbl_type == "string" then
return f.index(tbl)
elseif tbl_type == "number" then
local ik = 0
local start = fpairs and tbl or 1
local stop = not fpairs and tbl or
(type(fpairs) == "number") and fpairs or error("Invalid argument type for 'fpairs': " .. type(fpairs))
if step and step ~= 0 and ((step < 0) == (start < stop)) then
return none
end
return f.new(function()
local iv = tbl + ik * (step or 1)
ik = ik + 1
if start > stop and iv >= stop or
start < stop and iv <= stop or
start == stop and iv == stop then
return ik, iv
end
end)
elseif tbl_type ~= "table" then
error("Invalid argument type for 'tbl': " .. type(tbl))
end
local next, context, k, v = autopairs(tbl, fpairs)
return f.new(function()
k, v = next(context, k)
return k, v
end)
end
---@generic K, V
---@param self F|{ [K]: V }
---@param ... F|{ [K]: V }
---@return F|{ [K]: V }
---@nodiscard
function f:concat(...)
local fsi = 0
local fs = {...}
for i = 1, #fs do
if not is_f(fs[i]) then ---@diagnostic disable-next-line: assign-type-mismatch
fs[i] = f.from(fs[i])
end
end
return f.new(function()
if fsi == 0 then
local k, v = self:next()
if k ~= nil then
return k, v
end
fsi = 1
end
while fsi <= #fs do
local k, v = fs[fsi]:next()
if k ~= nil then
return k, v
end
fsi = fsi + 1
end
end)
end
---@generic K, V, U
@ -380,61 +484,6 @@ function f:each(func)
end
end
local none = f.new()
none = f.new()
--- Creates an enumeration.
---@generic K, V
---@param tbl table<K, V>
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K?, V?)
---@param step? nil
---@return F | { [K]: V }
---@overload fun(tbl: number, fpairs?: number, step?: number): F | { [number]: number }
---@overload fun(tbl: string|K): fun(table: { [string|K]: V }): V
---@overload fun(tbl: false): fun(): false
---@overload fun(tbl: true): fun(): true
---@overload fun(tbl: nil): F
return function(tbl, fpairs, step)
if tbl == true then
return f.tru
elseif tbl == false then
return f.fals
elseif tbl == nil then
return none
end
local tbl_type = type(tbl)
if tbl_type == "string" then
return f.index(tbl)
elseif tbl_type == "number" then
local ik = 0
local start = fpairs and tbl or 1
local stop = not fpairs and tbl or
(type(fpairs) == "number") and fpairs or error("Invalid argument type for 'fpairs': " .. type(fpairs))
if step and step ~= 0 and ((step < 0) == (start < stop)) then
return none
end
return f.new(function()
local iv = tbl + ik * (step or 1)
ik = ik + 1
if start > stop and iv >= stop or
start < stop and iv <= stop or
start == stop and iv == stop then
return ik, iv
end
end)
elseif tbl_type ~= "table" then
error("Invalid argument type for 'tbl': " .. type(tbl))
end
local next, context, k, v = autopairs(tbl, fpairs)
return f.new(function()
k, v = next(context, k)
return k, v
end)
end
return f.from