From a5c76557d2022c7797cc7b59c54a5fbca0512304 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Sun, 4 Feb 2024 22:11:17 -0800 Subject: [PATCH] Multiple rulesets --- board.lua | 75 ++++++++++++----------- cursor.lua | 9 +-- deck.lua | 67 --------------------- layout.lua | 15 +---- main.lua | 2 +- main.p8 | 15 ++--- progression.lua | 16 +++++ ruleset.lua | 154 ++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 222 insertions(+), 131 deletions(-) delete mode 100644 deck.lua create mode 100644 progression.lua create mode 100644 ruleset.lua diff --git a/board.lua b/board.lua index da70893..0fbe45b 100644 --- a/board.lua +++ b/board.lua @@ -1,41 +1,41 @@ board=klass() -function board:init() +function board:init(ruleset) + self.ruleset=ruleset self.cursor=cursor:new(self) self.slots={} self.wells={} -- board slots - -- 1,11: normal - for i=1,11 do - add(self.slots,slot:new()) + -- ...n_slots: normal + for i=1,ruleset.n_slots do + add(self.slots,slot:new(ruleset)) end - -- 12: special - add(self.slots,slot:new(1)) - assert(#self.slots==12) + -- n_slots+1: special + add(self.slots,slot:new(ruleset,1)) -- wells: - -- 1,2,3,4: wands, cups, swords, pentacles + -- ...n_suits: wands, cups, swords, pentacles, etc local function add_suit(_self,suit) - add(_self.wells,well:new(function(lst,new) + add(_self.wells,well:new(_self.ruleset, function(lst,new) assert(lst) -- the ace is always present initially if (new.suit!=suit) return return new.suit==suit and new.rank==lst.rank+1 end)) end - for suit in all(deck.suits) do + for suit in all(self.ruleset.deck.suits) do add_suit(self,suit) end - -- 5: arcana ascending - add(self.wells,well:new(function(lst,new) + -- n_suits+1: arcana ascending + add(self.wells,well:new(self.ruleset,function(lst,new) if (new.suit!='a') return if (not lst) return new.rank==0 return new.rank==lst.rank+1 end)) - -- 6: arcana descending - add(self.wells,well:new(function(lst,new) + -- n_suits+2: arcana descending + add(self.wells,well:new(self.ruleset,function(lst,new) if (new.suit!='a') return - if (not lst) return new.rank==21 + if (not lst) return new.rank==self.ruleset.n_arcana-1 return new.rank==lst.rank-1 end)) @@ -43,24 +43,21 @@ function board:init() end function board:deal() - local n_conventional_wells=4 - local n_slots=10 + local n_usable_slots=self.ruleset.n_slots - 1 -- first, pull the aces - assert(#deck.aces==n_conventional_wells) - assert(#self.wells==n_conventional_wells+2) local available={} - for card=1,#deck.cards do + for card=1,#self.ruleset.deck.cards do available[card]=true end - for i=1,n_conventional_wells do + for i=1,#self.ruleset.deck.aces do local well=self.wells[i] - local ace=deck.aces[i] + local ace=self.ruleset.deck.aces[i] well:add(ace) available[ace]=false end local eligible_bottom_row={} - for card=1,#deck.cards do + for card=1,#self.ruleset.deck.cards do local skip if not available[card] then skip=true @@ -73,20 +70,20 @@ function board:deal() end function i_to_slot(i) - if (i 6") -end -function layouts:slot(i) - if (i<=11) return layout:new(9+(i-1)*10,18,layout_mode.vertical) - if (i==12) return layout:new(94,1,layout_mode.obscured) - assert(false,"shouldn't be > 12") -end - layout_mode={ obscured=0, -- for wells vertical=1, -- for conventional slots @@ -27,5 +14,5 @@ end function layout:place_card(i) if (self.mode==layout_mode.obscured) return self.x,self.y if (self.mode==layout_mode.vertical) return self.x,self.y+(i-1)*6 - assert(false,"unexpected mode") + assert(false,"unexpected mode: "..self.mode) end \ No newline at end of file diff --git a/main.lua b/main.lua index 647d6be..f917970 100644 --- a/main.lua +++ b/main.lua @@ -2,7 +2,7 @@ main={} add(modules,main) function main:init() - self.board=board:new() + self.board=board:new(progression[1]) end function main:update() diff --git a/main.p8 b/main.p8 index 9c5dd78..7fe85df 100644 --- a/main.p8 +++ b/main.p8 @@ -4,16 +4,17 @@ __lua__ #include engine.lua #include board.lua #include cursor.lua -#include deck.lua #include layout.lua +#include ruleset.lua +#include progression.lua #include main.lua __gfx__ -00000000070000007770000000700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -70700000070000007770000007000000070707000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -07000000070000007770000007000000007777000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -70700000777000000700000070000000077070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -00000000070000007770000070000000007777700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000070077700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000070000007770000000700000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +70700000070000007770000007000000770000000707070000000000000000000000000000000000000000000000000000000000000000000000000000000000 +07000000070000007770000007000000070000000077770000000000000000000000000000000000000000000000000000000000000000000000000000000000 +70700000777000000700000070000000070000000770700000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000070000007770000070000000077000000077777000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000700777000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000070000000700000007000000000000000000000000000000000000000000000000000 diff --git a/progression.lua b/progression.lua new file mode 100644 index 0000000..df0a447 --- /dev/null +++ b/progression.lua @@ -0,0 +1,16 @@ +progression={ + -- level 1 + ruleset:new(5,1,9,0), + -- level 2 + -- ruleset:new(5,2,9,0), + -- level 3 + -- ruleset:new(7,2,9,8), + -- level 4 (first challenging) + -- ruleset:new(9,3,9,16), + -- level 5 + -- ruleset:new(9,3,11,18), + -- fortune's foundation + -- ruleset:new(11,4,13,22) + -- harder than fortune's foundation + -- ruleset:new(11,5,10,25) +} \ No newline at end of file diff --git a/ruleset.lua b/ruleset.lua new file mode 100644 index 0000000..1d063f2 --- /dev/null +++ b/ruleset.lua @@ -0,0 +1,154 @@ +ruleset=klass() +function ruleset:init( + -- 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 + n_arcana +) + self.n_slots=n_slots + self.n_suits=n_suits + self.n_cards_per_suit=n_cards_per_suit + self.n_arcana=n_arcana + 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) + + local total_n_cards = n_arcana + n_suits * n_cards_per_suit + -- aces aren't usable because they are initially placed in the wells + local usable_n_cards = total_n_cards - self.n_suits + + -- deal has to be symmetrical + assert(usable_n_cards % usable_slots == 0, usable_slots-(usable_n_cards%usable_slots)) + + -- 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 + assert((total_n_cards-instantly_placed_cards)-usable_slots >= 0) + + self:generate_deck() + self:generate_layouts() +end + +function ruleset:generate_deck() + local ruleset=self + local possible_suits={"p","s","c","w","b"} + local deck={ + aces={}, + suits={}, + cards={}, + 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) + end + end + + -- arcana + for rank=0,self.n_arcana-1 do + add(deck.cards,{suit="a",rank=rank}) + end + + function deck:draw_card(x,y,c,shadow) + local meta=deck.cards[c] + local is_extreme=meta.rank==0 or meta.rank==ruleset.n_arcana-1 + + local s,fg + + local bg,shadowbg + if meta.suit=='a' then + bg,shadowbg=1,1 + if (shadow) bg,shadowbg=1,0 + if (is_extreme) bg,shadowbg=8,8 + else + bg,shadowbg=7,7 + --if (shadow) bg,shadowbg=7,6 + end + + rectfill(x,y,x+8,y+4,bg) + rectfill(x,y+5,x+8,y+15,shadowbg) + + 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 + if (meta.suit=='b') s,fg=3,0 + if (meta.suit=='a') fg=15 + + if meta.suit=='a' then + local rank=""..meta.rank + pal(7,15) + if (is_extreme) pal(7,0) + print(meta.rank,x+5-#rank*2,y+1,7) + spr(5,x,y+8) + pal() + else + local name=sub(deck.rank_name,meta.rank,meta.rank) + rectfill(x,y,x+3,y+6,fg) + print(name,x,y+1,7) + pal(7,fg) + spr(s,x+5,y+1) + if not shadow then + spr(15+meta.rank,x,y+8) + end + pal() + end + + 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 + + function layouts:well(i) + if i<=ruleset.n_suits then + local wx=width-ruleset.n_suits*10+(i-1)*10 + return layout:new(x+wx,1,layout_mode.obscured) + end + i-=ruleset.n_suits + if (i==1) return layout:new(x,1,layout_mode.obscured) + if (i==2) return layout:new(x+10,1,layout_mode.obscured) + assert(false,"unknown well") + end + + function layouts:slot(i) + if i<=ruleset.n_slots then + local sx=(i-1)*10 + return layout:new(x+sx,18,layout_mode.vertical) + end + if (i==ruleset.n_slots+1) return layout:new(x+width-ruleset.n_suits*5-5,1,layout_mode.obscured) + assert(false, "unknown slot") + end +end \ No newline at end of file