Stacked moves
This commit is contained in:
parent
7f87814d35
commit
93161c6465
12
board.lua
12
board.lua
@ -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)
|
||||||
|
@ -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
|
94
cursor.lua
94
cursor.lua
@ -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())
|
||||||
local card=src:pop()
|
while self:acceptance_state() == acceptance_state.would_accept do
|
||||||
tar:add(card)
|
local card=src:pop()
|
||||||
self.grabbed=nil
|
tar:add(card)
|
||||||
self.board:on_move(card)
|
deli(self.grabbed_slots)
|
||||||
self:restore_hover()
|
end
|
||||||
|
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
|
@ -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
|
||||||
@ -38,16 +45,24 @@ function state_gameround:update()
|
|||||||
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
|
||||||
|
@ -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"
|
||||||
|
}
|
@ -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]
|
||||||
|
Loading…
Reference in New Issue
Block a user