2024-02-05 06:11:17 +00:00
|
|
|
ruleset=klass()
|
|
|
|
function ruleset:init(
|
2024-02-11 06:19:54 +00:00
|
|
|
completion_level,
|
2024-02-05 06:11:17 +00:00
|
|
|
-- Number of unlocked slots (up to 11)
|
|
|
|
-- Includes the one in the middle
|
|
|
|
-- For Fortune's Foundation: 11
|
|
|
|
n_slots,
|
|
|
|
|
|
|
|
-- Number of suits (up to 5)
|
|
|
|
-- This is also the number of RHS wells
|
|
|
|
-- For Fortune's Foundation: 4
|
|
|
|
n_suits,
|
|
|
|
|
|
|
|
-- Number of cards per suit (up to 13)
|
|
|
|
-- For Fortune's Foundation: 13
|
|
|
|
n_cards_per_suit,
|
|
|
|
|
|
|
|
-- Number of arcana (unbounded)
|
|
|
|
-- For Fortune's Foundation: 22
|
2024-02-10 03:21:47 +00:00
|
|
|
n_arcana,
|
|
|
|
pool
|
2024-02-05 06:11:17 +00:00
|
|
|
)
|
2024-02-11 06:19:54 +00:00
|
|
|
self.completion_level=completion_level
|
2024-02-05 06:11:17 +00:00
|
|
|
self.n_slots=n_slots
|
|
|
|
self.n_suits=n_suits
|
|
|
|
self.n_cards_per_suit=n_cards_per_suit
|
|
|
|
self.n_arcana=n_arcana
|
2024-02-10 03:21:47 +00:00
|
|
|
self.pool=pool
|
2024-02-05 06:11:17 +00:00
|
|
|
assert(self.n_slots<=11)
|
|
|
|
assert(self.n_suits<=5)
|
|
|
|
assert(self.n_cards_per_suit<=13)
|
|
|
|
assert(self.n_arcana<=99)
|
|
|
|
|
|
|
|
-- the middle slot is always auxiliary in
|
|
|
|
-- Fortune's Foundation-style games
|
|
|
|
local usable_slots = n_slots - 1
|
|
|
|
assert(usable_slots%2==0)
|
|
|
|
|
2024-02-09 01:04:33 +00:00
|
|
|
local n_total_cards = n_arcana + n_suits * n_cards_per_suit
|
2024-02-05 06:11:17 +00:00
|
|
|
-- aces aren't usable because they are initially placed in the wells
|
2024-02-09 01:04:33 +00:00
|
|
|
local n_usable_cards = n_total_cards - self.n_suits
|
|
|
|
|
|
|
|
self.n_total_cards=n_total_cards
|
|
|
|
self.n_usable_cards=n_usable_cards
|
2024-02-05 06:11:17 +00:00
|
|
|
|
|
|
|
-- deal has to be symmetrical
|
2024-02-09 01:04:33 +00:00
|
|
|
assert(n_usable_cards % usable_slots == 0, usable_slots-(n_usable_cards%usable_slots))
|
2024-02-05 06:11:17 +00:00
|
|
|
|
|
|
|
-- these cards would be instantly moved to the wells and
|
|
|
|
-- therefore cannot be in the bottom row
|
|
|
|
local instantly_placed_cards = self.n_suits + 2
|
2024-02-09 01:04:33 +00:00
|
|
|
assert((n_total_cards-instantly_placed_cards)-usable_slots >= 0)
|
2024-02-05 06:11:17 +00:00
|
|
|
|
|
|
|
self:generate_deck()
|
|
|
|
self:generate_layouts()
|
|
|
|
end
|
|
|
|
|
|
|
|
function ruleset:generate_deck()
|
|
|
|
local ruleset=self
|
2024-02-09 00:41:40 +00:00
|
|
|
local possible_suits={"c","s","p","w","b"}
|
2024-02-05 06:11:17 +00:00
|
|
|
local deck={
|
|
|
|
aces={},
|
|
|
|
suits={},
|
|
|
|
cards={},
|
2024-02-09 01:04:33 +00:00
|
|
|
instantly_accepted={},
|
2024-02-05 06:11:17 +00:00
|
|
|
rank_name="a23456789tjqk"
|
|
|
|
}
|
|
|
|
self.deck=deck
|
|
|
|
for i=1,self.n_suits do
|
|
|
|
add(deck.suits,possible_suits[i])
|
|
|
|
end
|
|
|
|
|
|
|
|
-- suited cards
|
|
|
|
for suit in all(deck.suits) do
|
|
|
|
for rank=1,self.n_cards_per_suit do
|
|
|
|
add(deck.cards,{suit=suit,rank=rank})
|
|
|
|
if (rank==1) add(deck.aces,#deck.cards)
|
2024-02-09 01:04:33 +00:00
|
|
|
if (rank==2) deck.instantly_accepted[#deck.cards]=true
|
2024-02-05 06:11:17 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- arcana
|
|
|
|
for rank=0,self.n_arcana-1 do
|
|
|
|
add(deck.cards,{suit="a",rank=rank})
|
2024-02-09 01:04:33 +00:00
|
|
|
if (rank==0 or rank==self.n_arcana-1) deck.instantly_accepted[#deck.cards]=true
|
2024-02-05 06:11:17 +00:00
|
|
|
end
|
|
|
|
|
2024-02-10 06:17:57 +00:00
|
|
|
function deck:draw_card(x,y,c,special)
|
|
|
|
if special.rotate then
|
|
|
|
camera(0,-64)
|
|
|
|
poke(0x5f55,0x00)
|
|
|
|
else
|
|
|
|
camera(-x,-y)
|
|
|
|
end
|
|
|
|
|
2024-02-05 06:11:17 +00:00
|
|
|
local meta=deck.cards[c]
|
|
|
|
local is_extreme=meta.rank==0 or meta.rank==ruleset.n_arcana-1
|
|
|
|
|
|
|
|
local s,fg
|
|
|
|
|
2024-02-10 05:43:01 +00:00
|
|
|
local bg
|
2024-02-09 00:41:40 +00:00
|
|
|
if meta.suit=='a' or meta.suit=='b' then
|
2024-02-10 05:43:01 +00:00
|
|
|
bg=1
|
|
|
|
if (is_extreme) bg=15
|
2024-02-05 06:11:17 +00:00
|
|
|
else
|
2024-02-10 05:43:01 +00:00
|
|
|
bg=7
|
2024-02-05 06:11:17 +00:00
|
|
|
end
|
2024-02-10 06:17:57 +00:00
|
|
|
if special.shadowed then
|
|
|
|
if (bg==1) bg=4
|
|
|
|
if (bg==7) bg=6
|
|
|
|
end
|
2024-02-05 06:11:17 +00:00
|
|
|
|
2024-02-10 06:17:57 +00:00
|
|
|
rectfill(0,0,8,15,bg)
|
2024-02-05 06:11:17 +00:00
|
|
|
|
|
|
|
if (meta.suit=='p') s,fg=0,4
|
|
|
|
if (meta.suit=='s') s,fg=1,12
|
|
|
|
if (meta.suit=='c') s,fg=2,2
|
|
|
|
if (meta.suit=='w') s,fg=3,3
|
2024-02-08 21:12:34 +00:00
|
|
|
if (meta.suit=='b') s,fg=4,14
|
2024-02-05 06:11:17 +00:00
|
|
|
if (meta.suit=='a') fg=15
|
|
|
|
|
|
|
|
if meta.suit=='a' then
|
|
|
|
local rank=""..meta.rank
|
|
|
|
pal(7,15)
|
2024-02-09 00:41:40 +00:00
|
|
|
if (is_extreme) pal(7,1)
|
2024-02-10 06:17:57 +00:00
|
|
|
print(meta.rank,5-#rank*2,1,7)
|
|
|
|
spr(5,0,8)
|
2024-02-05 06:11:17 +00:00
|
|
|
pal()
|
|
|
|
else
|
|
|
|
local name=sub(deck.rank_name,meta.rank,meta.rank)
|
2024-02-10 06:17:57 +00:00
|
|
|
local x2=0
|
2024-02-09 00:41:40 +00:00
|
|
|
if (meta.suit=='b') x2+=1
|
2024-02-10 06:17:57 +00:00
|
|
|
rectfill(0,0,3,6,fg)
|
|
|
|
print(name,x2,1,bg)
|
2024-02-05 06:11:17 +00:00
|
|
|
pal(7,fg)
|
2024-02-10 06:17:57 +00:00
|
|
|
spr(s,4,0)
|
|
|
|
spr(15+meta.rank,0,8)
|
2024-02-05 06:11:17 +00:00
|
|
|
pal()
|
|
|
|
end
|
|
|
|
|
2024-02-10 06:17:57 +00:00
|
|
|
camera()
|
|
|
|
if special.rotate then
|
|
|
|
poke(0x5f55,0x60)
|
|
|
|
mset(0,0,128)
|
|
|
|
mset(1,0,129)
|
|
|
|
mset(0,1,144)
|
|
|
|
mset(1,1,145)
|
|
|
|
x-=3
|
|
|
|
y+=7
|
|
|
|
for sx=0,8 do
|
|
|
|
for sy=0,15 do
|
|
|
|
tline(x+sy,y+sx,x+sy,y,(0)/8,sy/8,1/8,0)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
tline()
|
|
|
|
end
|
|
|
|
|
2024-02-05 06:11:17 +00:00
|
|
|
return fg
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function ruleset:generate_layouts()
|
|
|
|
local layouts={}
|
|
|
|
self.layouts=layouts
|
|
|
|
|
|
|
|
local ruleset=self
|
|
|
|
local width=ruleset.n_slots*10
|
|
|
|
local x=(128-width)\2
|
2024-02-11 05:02:31 +00:00
|
|
|
local y=9 -- 1 is also fine
|
2024-02-05 06:11:17 +00:00
|
|
|
|
|
|
|
function layouts:well(i)
|
|
|
|
if i<=ruleset.n_suits then
|
|
|
|
local wx=width-ruleset.n_suits*10+(i-1)*10
|
2024-02-11 05:02:31 +00:00
|
|
|
return layout:new(x+wx,y,layout_mode.obscured)
|
2024-02-05 06:11:17 +00:00
|
|
|
end
|
|
|
|
i-=ruleset.n_suits
|
2024-02-11 05:02:31 +00:00
|
|
|
if (i==1) return layout:new(x,y,layout_mode.obscured)
|
|
|
|
if (i==2) return layout:new(x+10,y,layout_mode.obscured)
|
2024-02-05 06:11:17 +00:00
|
|
|
assert(false,"unknown well")
|
|
|
|
end
|
|
|
|
|
2024-02-10 06:35:55 +00:00
|
|
|
function layouts:checkpoint()
|
|
|
|
local wx=(ruleset.n_slots\2)*10
|
2024-02-11 05:02:31 +00:00
|
|
|
return layout:new(x+wx,y,layout_mode.obscured)
|
2024-02-10 06:35:55 +00:00
|
|
|
end
|
|
|
|
|
2024-02-05 06:11:17 +00:00
|
|
|
function layouts:slot(i)
|
|
|
|
if i<=ruleset.n_slots then
|
|
|
|
local sx=(i-1)*10
|
2024-02-11 05:02:31 +00:00
|
|
|
return layout:new(x+sx,y+17,layout_mode.vertical)
|
2024-02-05 06:11:17 +00:00
|
|
|
end
|
2024-02-11 05:02:31 +00:00
|
|
|
if (i==ruleset.n_slots+1) return layout:new(x+width-ruleset.n_suits*5-5,y,layout_mode.rotated)
|
2024-02-05 06:11:17 +00:00
|
|
|
assert(false, "unknown slot")
|
|
|
|
end
|
|
|
|
end
|