Compare commits

..

2 Commits

Author SHA1 Message Date
93161c6465 Stacked moves 2024-02-14 15:55:00 -08:00
7f87814d35 Remove unused code 2024-02-14 14:10:19 -08:00
9 changed files with 112 additions and 104 deletions

View File

@ -129,6 +129,7 @@ function board:find_automove()
if w<=self.ruleset.n_suits and self.slots[self.ruleset.n_slots+1]:peek()!=nil then if w<=self.ruleset.n_suits and self.slots[self.ruleset.n_slots+1]:peek()!=nil then
-- the top wells are blocked -- the top wells are blocked
elseif self.wells[w]:would_accept(top) then elseif self.wells[w]:would_accept(top) then
self.cursor:drop_grab_silent()
self:animate_and_move_to_well(s,w) self:animate_and_move_to_well(s,w)
self.last_card=top self.last_card=top
@ -174,13 +175,16 @@ function board:draw()
end end
end end
local grabs={}
for s_ix in all(self.cursor.grabbed_slots) do
grabs[s_ix]=(grabs[s_ix] or 0)+1
end
local function forall_slots(cb) local function forall_slots(cb)
for s_ix=1,#self.slots do for s_ix=1,#self.slots do
local s=self.slots[s_ix] local s=self.slots[s_ix]
local l=self.ruleset.layouts:slot(s_ix) local l=self.ruleset.layouts:slot(s_ix)
local n=#s.contents local n=#s.contents-(grabs[s_ix] or 0)
if (self.cursor.grabbed==s_ix) n-=1
cb(x,y,s_ix,s,l,n) cb(x,y,s_ix,s,l,n)
end end
@ -233,8 +237,8 @@ end
function slot:add(card) function slot:add(card)
add(self.contents,card) add(self.contents,card)
end end
function slot:peek() function slot:peek(depth)
return self.contents[#self.contents] return self.contents[#self.contents-(depth or 0)]
end end
function slot:pop() function slot:pop()
return deli(self.contents,#self.contents) return deli(self.contents,#self.contents)

View File

@ -36,5 +36,5 @@ function checkpoint:apply(board)
add(board.wells[w].contents,i) add(board.wells[w].contents,i)
end end
end end
board.cursor.grabbed=nil board.cursor:drop_grab()
end end

View File

@ -11,16 +11,17 @@ function cursor:init(board)
self.hover_x=self.ruleset.n_slots\2 self.hover_x=self.ruleset.n_slots\2
self.hover_y=1 self.hover_y=1
self.saved_hover_x_y=nil self.saved_hover_x_y=nil
self.grabbed=nil self.grabbed_slots={}
end end
function cursor:acceptance_state() function cursor:acceptance_state()
local hover=self:hover_slot() local hover=self:hover_slot()
if self.grabbed then local slot=self:grabbed_slot()
if hover==self.grabbed then if slot then
if hover==slot then
return acceptance_state.no_move return acceptance_state.no_move
end end
local source=self.board.slots[self.grabbed] local source=self.board.slots[slot]
local target=self.board.slots[self:hover_slot()] local target=self.board.slots[self:hover_slot()]
local card=source:peek() local card=source:peek()
if target:would_accept(card) then if target:would_accept(card) then
@ -38,13 +39,16 @@ function cursor:save_hover()
self.saved_hover_x_y={self.hover_x,self.hover_y} self.saved_hover_x_y={self.hover_x,self.hover_y}
end end
--[[
function cursor:restore_hover() function cursor:restore_hover()
self.wants_to_restore_hover=true self.wants_to_restore_hover=true
end end
]]
--[[
function cursor:actually_restore_hover() function cursor:actually_restore_hover()
if (not self.saved_hover_x_y) return if (not self.saved_hover_x_y) return
self.wants_to_restore_hover=false -- self.wants_to_restore_hover=false
-- try restoring hover x -- try restoring hover x
local old_hover_x,old_hover_y=self.hover_x,self.hover_y local old_hover_x,old_hover_y=self.hover_x,self.hover_y
@ -62,23 +66,27 @@ function cursor:actually_restore_hover()
i() i()
end end
end end
]]--
function cursor:toggle_grab() function cursor:toggle_grab()
local acc,src,tar=self:acceptance_state() local acc,src,tar=self:acceptance_state()
local slot=self:hover_slot() local slot=self:hover_slot()
if acc==acceptance_state.not_grabbed then if acc==acceptance_state.not_grabbed then
if (not self.board.watcher:intercept("grab",slot)) sounds:dire() return if (not self.board.watcher:intercept("grab",slot)) sounds:dire() return
if (self.board.slots[slot]:peek()) self.grabbed=slot if (self.board.slots[slot]:peek()) self.grabbed_slots={slot}
self:save_hover() self:save_hover()
sounds:menu() sounds:menu()
elseif acc==acceptance_state.would_accept then elseif acc==acceptance_state.would_accept then
if (not self.board.watcher:intercept("drop",slot)) sounds:dire() return if (not self.board.watcher:intercept("drop",slot)) sounds:dire() return
self.board:pre_move(src:peek()) self.board:pre_move(src:peek())
while self:acceptance_state() == acceptance_state.would_accept do
local card=src:pop() local card=src:pop()
tar:add(card) tar:add(card)
self.grabbed=nil deli(self.grabbed_slots)
self.board:on_move(card) end
self:restore_hover() self.grabbed_slots={}
self.board:on_move()
-- if (#self.grabbed_slots == 0) self:restore_hover()
sounds:menu() sounds:menu()
elseif acc==acceptance_state.no_move or acc==acceptance_state.would_not_accept then elseif acc==acceptance_state.no_move or acc==acceptance_state.would_not_accept then
self:drop_grab() self:drop_grab()
@ -87,15 +95,30 @@ function cursor:toggle_grab()
end end
end end
function cursor:incr_grab()
local slot=self:hover_slot()
if (slot!=self:grabbed_slot()) return
if (not self.board.watcher:intercept("incr_grab",slot)) sounds:dire() return
local new_card = self.board.slots[slot]:peek(#self.grabbed_slots)
if (not new_card) return
local old_card = self.board.slots[slot]:peek(#self.grabbed_slots-1)
if (not self:_can_incr_grab(old_card,new_card)) return
add(self.grabbed_slots,slot)
sounds:menu()
end
function cursor:drop_grab_silent()
self.grabbed_slots={}
end
function cursor:drop_grab() function cursor:drop_grab()
if (not self.board.watcher:intercept("cancel")) sounds:dire() return if (not self.board.watcher:intercept("cancel")) sounds:dire() return
self.grabbed=nil self.grabbed_slots={}
self:restore_hover() -- self:restore_hover()
sounds:menu() sounds:menu()
end end
function cursor:update() function cursor:update()
if (self.wants_to_restore_hover) self:actually_restore_hover() -- if (self.wants_to_restore_hover) self:actually_restore_hover()
end end
function cursor:move_x(dx) function cursor:move_x(dx)
@ -114,7 +137,7 @@ end
function cursor:move_y(dy) function cursor:move_y(dy)
local old_y=self.hover_y local old_y=self.hover_y
if (self.hover_y==0 and dy==1) self.hover_y=1 if (self.hover_y==0 and dy==1) self.hover_y=1
if (self.hover_y==1 and dy==-1) self.hover_y=0 if (self.hover_y==1 and dy==-1 and #self.grabbed_slots<2) self.hover_y=0
if (self:acceptance_state()==acceptance_state.would_not_accept) if (not self:move_x(-1)) self.hover_y=old_y if (self:acceptance_state()==acceptance_state.would_not_accept) if (not self:move_x(-1)) self.hover_y=old_y
end end
@ -123,27 +146,42 @@ function cursor:hover_slot()
return self.hover_x+1 return self.hover_x+1
end end
function cursor:grabbed_slot()
return self.grabbed_slots[#self.grabbed_slots]
end
function cursor:grabbed_card() function cursor:grabbed_card()
if self.grabbed then local grabbed_slot=self:grabbed_slot()
local slot=self.board.slots[self.grabbed] if grabbed_slot then
return slot:peek() return self.board.slots[grabbed_slot]:peek()
end end
return nil
end end
function cursor:draw_at(l,i) function cursor:draw_at(l,i)
local card=self:grabbed_card() local slot=self:grabbed_slot()
local acc=self:acceptance_state()
if card then if not slot then
i+=1
local x,y=l:place_card(i)
local card_fg=self.ruleset.deck:draw_card(x,y,card,{rotate=l.rotated})
local fg=card_fg
draw_layout_hint(l,i,9,false)
else
local filled=false local filled=false
if (i<1) i=1 filled=true if (i<1) i=1 filled=true
draw_layout_hint(l,i,12,filled) draw_layout_hint(l,i,12,filled)
return
end
local not_moving=self:acceptance_state()==acceptance_state.no_move
for i2=1,#self.grabbed_slots do
local ix=i2-1
if (not_moving) ix=#self.grabbed_slots-i2
local card=self.board.slots[slot]:peek(ix)
local x,y=l:place_card(i+i2)
local card_fg=self.ruleset.deck:draw_card(x,y,card,{rotate=l.rotated})
local fg=card_fg
if (i2==1) draw_layout_hint(l,i+i2,9,false)
end end
end end
function cursor:_can_incr_grab(c0,c1)
c0=self.board.ruleset.deck.cards[c0]
c1=self.board.ruleset.deck.cards[c1]
if (c0.suit!=c1.suit) return false
return c0.rank==c1.rank+1 or c1.rank==c0.rank+1
end

View File

@ -32,39 +32,6 @@ function klass()
return k return k
end end
function alives(tbl)
local tbl2={}
for i in all(tbl) do
if (not i.dead) add(tbl2,i)
end
return tbl2
end
function trunc4(x)
if (x < 0) return -trunc4(-x)
return x\0.25/4
end
function stepstep(by,x0,x1,f)
local x=x0
if (x==x1) return
if x0>x1 then
return stepstep(by,-x0,-x1,function(x) return f(-x) end)
end
x=x\by*by
while true do
x+=by
if (x>=x1) f(x1) break
if (not f(x)) break
end
end
function lerp(x,x0,x1)
return x0+x*(x1-x0)
end
function gsv(s) function gsv(s)
local ret=split(s,"\n") local ret=split(s,"\n")
for i,v in ipairs(ret) do for i,v in ipairs(ret) do

View File

@ -31,7 +31,6 @@ __lua__
#include state_gameround.lua #include state_gameround.lua
#include state_ironman.lua #include state_ironman.lua
#include state_reset_menu.lua #include state_reset_menu.lua
#include state_restartmenu.lua
#include state_wonironman.lua #include state_wonironman.lua
#include state_wonround.lua #include state_wonround.lua
#include tutorial.lua #include tutorial.lua

View File

@ -2,7 +2,9 @@ state_gameround=klass()
function state_gameround:init(watcher,ruleset) function state_gameround:init(watcher,ruleset)
self.board=board:new(watcher,ruleset) self.board=board:new(watcher,ruleset)
self.outcome=nil self.outcome=nil
self.grab_frames=0
self.restart_frames=0 self.restart_frames=0
self.picking_up=false
end end
function state_gameround:enter() self:add_menu() end function state_gameround:enter() self:add_menu() end
function state_gameround:exit() self:remove_menu() end function state_gameround:exit() self:remove_menu() end
@ -22,6 +24,11 @@ end
function state_gameround:update() function state_gameround:update()
self.board:update() self.board:update()
if btn(4) then
self.grab_frames+=1
else
self.grab_frames=0
end
if btn(5) then if btn(5) then
self.restart_frames+=1 self.restart_frames+=1
else else
@ -30,22 +37,32 @@ function state_gameround:update()
local restart_progress=self.restart_frames/60 local restart_progress=self.restart_frames/60
self.board:set_restart_progress(restart_progress) self.board:set_restart_progress(restart_progress)
if restart_progress>=1.0 then if restart_progress>=1.0 then
main.state_manager:push(state_restartmenu:new()) self.outcome="restart"
self.done=true
return return
end end
if self.board:can_take_input() then if self.board:can_take_input() then
if (btnp(0)) self.board.cursor:move_x(-1) if (btnp(0)) self.board.cursor:move_x(-1) self.picking_up=false
if (btnp(1)) self.board.cursor:move_x(1) if (btnp(1)) self.board.cursor:move_x(1) self.picking_up=false
if (btnp(2)) self.board.cursor:move_y(-1) if (btnp(2)) self.board.cursor:move_y(-1) self.picking_up=false
if (btnp(3)) self.board.cursor:move_y(1) if (btnp(3)) self.board.cursor:move_y(1) self.picking_up=false
if (btnp(4)) self.board.cursor:toggle_grab() if btnp(4) then
if self.grab_frames<4 then
self.board.cursor:toggle_grab()
self.picking_up=true
else
self.board.cursor:incr_grab()
end
end
if btnp(5) and self.restart_frames < 4 then if btnp(5) and self.restart_frames < 4 then
if self.board.cursor:grabbed_card() then if self.board.cursor:grabbed_card() then
self.board.cursor:drop_grab() self.board.cursor:drop_grab()
else else
self.board:undo() self.board:undo()
self.picking_up=false
end end
end end
end end

View File

@ -1,24 +0,0 @@
state_restartmenu=klass()
function state_restartmenu:init()
end
function state_restartmenu:enter()
-- for now, make this only a restart button
self.outcome="restart" self.done=true
end
function state_restartmenu:exit(new_top)
new_top.outcome=self.outcome
new_top.done=true
end
function state_restartmenu:reenter() end
function state_restartmenu:suspend() end
function state_restartmenu:update()
if (btnp(0)) self.outcome="menu" self.done=true
if (btnp(4)) self.outcome="restart" self.done=true
end
function state_restartmenu:draw()
cls(13)
print("⬅️ back to menu",1,58,7)
print("🅾️ restart",1,64,7)
end

View File

@ -12,8 +12,7 @@ function state_wonround:enter()
sounds:win() sounds:win()
completion_tracker:mark_seen(self.verse_id) completion_tracker:mark_seen(self.verse_id)
completion_tracker:advance_completion_level(self.board:get_completion_level()) completion_tracker:advance_completion_level(self.board:get_completion_level())
self.has_tip = not seen_tip_this_session if (self.board.watcher:allow_tips()) self.tip=deli(_won_round_tips,1)
seen_tip_this_session=true
end end
function state_wonround:exit(new_top) end function state_wonround:exit(new_top) end
@ -65,9 +64,13 @@ function state_wonround:draw()
print("next",57,y+2,15) print("next",57,y+2,15)
print("(🅾️)",57,y+8,15) print("(🅾️)",57,y+8,15)
if self.has_tip then if self.tip then
local tip="tip: hold ❎ to restart" local w=measure_text(self.tip)
local w=measure_text(tip) print(self.tip,64-w\2,122,15)
print(tip,64-w\2,122,15)
end end
end end
_won_round_tips={
"tip: hold ❎ to restart",
"tip: hold 🅾️ to stack cards"
}

View File

@ -3,6 +3,10 @@ function watcher:init(ruleset,seed,stages)
self.ruleset=ruleset self.ruleset=ruleset
self.seed=seed self.seed=seed
self._stages=stages or {} self._stages=stages or {}
self._allow_tips=#self._stages == 0
end
function watcher:allow_tips()
return self._allow_tips
end end
function watcher:active_stage(board) function watcher:active_stage(board)
local stage=self._stages[1] local stage=self._stages[1]