refactor: designed based on hypermedia principles
parent
e87b3c75bf
commit
bcfa629419
516
rummy.lua
516
rummy.lua
|
@ -16,8 +16,9 @@ cards_in_meld_draft=nil
|
||||||
melds_on_tabletop=nil
|
melds_on_tabletop=nil
|
||||||
|
|
||||||
-- `points_of_interest` is an array of things that can be hovered/selected by the controller
|
-- `points_of_interest` is an array of things that can be hovered/selected by the controller
|
||||||
|
current_page=nil
|
||||||
hovered=nil
|
hovered=nil
|
||||||
player_state=nil
|
current_handler=nil
|
||||||
|
|
||||||
function BOOT()
|
function BOOT()
|
||||||
draw_pile = create_deck()
|
draw_pile = create_deck()
|
||||||
|
@ -30,208 +31,280 @@ function BOOT()
|
||||||
|
|
||||||
discard_pile = draw_pile:draw_stack(1)
|
discard_pile = draw_pile:draw_stack(1)
|
||||||
|
|
||||||
player_state = player_state_draw_card
|
current_handler=handler_draw_card
|
||||||
|
|
||||||
melds_on_tabletop={}
|
melds_on_tabletop={}
|
||||||
end
|
end
|
||||||
|
|
||||||
function TIC()
|
function TIC()
|
||||||
|
local c_sel=btnp(5)
|
||||||
|
|
||||||
|
local request=nil
|
||||||
|
if c_sel and hovered then
|
||||||
|
request=hovered.action
|
||||||
|
current_page=nil
|
||||||
|
end
|
||||||
|
|
||||||
|
while not current_page do
|
||||||
|
trace(current_handler)
|
||||||
|
trace(request)
|
||||||
|
local response=current_handler(request)
|
||||||
|
if response.redirect then
|
||||||
|
current_handler=response.redirect
|
||||||
|
request=nil
|
||||||
|
elseif response.page then
|
||||||
|
current_page=response.page
|
||||||
|
else
|
||||||
cls(12)
|
cls(12)
|
||||||
|
print("Invalid response!")
|
||||||
|
for key,val in pairs(response) do
|
||||||
|
trace("key="..key)
|
||||||
|
trace("val="..val)
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local points_of_interest = player_state.get_points_of_interest()
|
local actions = get_actions_from_page(current_page)
|
||||||
|
|
||||||
local discard_x=((240 - 24) / 2)
|
if not hovered and #actions>0 then
|
||||||
local draw_pile_x=discard_x - 24 - 4
|
hovered=actions[1]
|
||||||
local end_turn_x=discard_x + 24 + 4
|
|
||||||
|
|
||||||
if not hovered and #points_of_interest>0 then
|
|
||||||
hovered=points_of_interest[1]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local c_up=btnp(0,10,3)
|
local c_up=btnp(0,10,3)
|
||||||
local c_down=btnp(1,10,3)
|
local c_down=btnp(1,10,3)
|
||||||
local c_left=btnp(2,10,3)
|
local c_left=btnp(2,10,3)
|
||||||
local c_right=btnp(3,10,3)
|
local c_right=btnp(3,10,3)
|
||||||
local c_sel=btnp(5)
|
|
||||||
local c_back=btnp(4)
|
local c_back=btnp(4)
|
||||||
|
|
||||||
if c_sel and hovered then
|
-- update hovered action
|
||||||
player_state = player_state.update(hovered)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- update hovered position
|
|
||||||
local moved = c_up or c_down or c_left or c_right
|
local moved = c_up or c_down or c_left or c_right
|
||||||
if moved and #points_of_interest > 0 then
|
if moved and #actions > 0 then
|
||||||
local start = hovered or {x=0,y=0,interest=nil}
|
local start=hovered or {x=0,y=0,action=nil}
|
||||||
local dir = {0, 0}
|
local dir={0, 0}
|
||||||
if c_left then dir[1] = dir[1] - 1 end
|
if c_left then dir[1]=dir[1] - 1 end
|
||||||
if c_right then dir[1] = dir[1] + 1 end
|
if c_right then dir[1]=dir[1] + 1 end
|
||||||
if c_up then dir[2] = dir[2] - 1 end
|
if c_up then dir[2]=dir[2] - 1 end
|
||||||
if c_down then dir[2] = dir[2] + 1 end
|
if c_down then dir[2]=dir[2] + 1 end
|
||||||
|
|
||||||
local nearest = nil
|
local nearest=nil
|
||||||
for i,point in ipairs(points_of_interest) do
|
for i,action in ipairs(actions) do
|
||||||
if hovered and point.interest == hovered.interest then
|
if hovered and action.action==hovered.action then
|
||||||
-- pass
|
-- pass
|
||||||
elseif not nearest then
|
elseif not nearest then
|
||||||
local distance = distance_to_point_of_interest(start,dir,point)
|
local distance=distance_to_point_of_interest(start,dir,action)
|
||||||
if distance > 0 then
|
if distance>0 then
|
||||||
nearest = point
|
nearest=action
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local distance = distance_to_point_of_interest(start,dir,point)
|
local distance=distance_to_point_of_interest(start,dir,action)
|
||||||
if distance > 0 and distance < distance_to_point_of_interest(start,dir,nearest) then
|
if distance>0 and distance<distance_to_point_of_interest(start,dir,nearest) then
|
||||||
nearest = point
|
nearest=action
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if nearest then
|
if nearest then
|
||||||
hovered = nearest
|
hovered=nearest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- render melds on tabletop
|
-- render current page
|
||||||
|
cls(12)
|
||||||
|
for i,element in ipairs(current_page) do
|
||||||
|
if element.visual then
|
||||||
|
if getmetatable(element.visual)==Card then
|
||||||
|
element.visual:render(element.x, element.y, element.hidden, element.sel_state)
|
||||||
|
elseif getmetatable(element.visual)==Sprite then
|
||||||
|
spr(element.visual.sid,
|
||||||
|
element.x,
|
||||||
|
element.y,
|
||||||
|
element.visual.colorkey,
|
||||||
|
1, 0, 0,
|
||||||
|
element.visual.tw,
|
||||||
|
element.visual.th)
|
||||||
|
else
|
||||||
|
local x = element.textx or element.x
|
||||||
|
local y = element.texty or element.y
|
||||||
|
local text_color=13
|
||||||
|
if element.action then
|
||||||
|
text_color=0
|
||||||
|
end
|
||||||
|
print(element.visual, x, y, text_color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if hovered and hovered.action==element.action then
|
||||||
|
spr(Card.spr_hilight.sid,
|
||||||
|
element.x,
|
||||||
|
element.y,
|
||||||
|
Card.spr_hilight.colorkey,
|
||||||
|
1, 0, 0,
|
||||||
|
Card.spr_hilight.tw,
|
||||||
|
Card.spr_hilight.th)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_actions_from_page(page)
|
||||||
|
local actions={}
|
||||||
|
for i,element in ipairs(page) do
|
||||||
|
if element.action then
|
||||||
|
table.insert(actions, {
|
||||||
|
action=element.action,
|
||||||
|
x=element.action_x or element.x,
|
||||||
|
y=element.action_y or element.y,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return actions
|
||||||
|
end
|
||||||
|
|
||||||
|
function build_meld_ui(elements, draft, new_meld_allowed)
|
||||||
local meld_x=2
|
local meld_x=2
|
||||||
|
local meld_y=10
|
||||||
for j,meld in ipairs(melds_on_tabletop) do
|
for j,meld in ipairs(melds_on_tabletop) do
|
||||||
local sel_state = nil
|
local meld_action=nil
|
||||||
if hovered and hovered.interest == meld then
|
if #cards_in_meld_draft>0 then
|
||||||
sel_state = 1
|
local meld_with_draft=meld:with(draft)
|
||||||
|
if rummy_is_valid_meld(meld_with_draft) then
|
||||||
|
meld_action=meld
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for i,card in ipairs(meld) do
|
for i,card in ipairs(meld) do
|
||||||
card:render(meld_x, 10, false, sel_state)
|
table.insert(elements, {
|
||||||
|
visual=card,
|
||||||
|
x=meld_x, y=meld_y,
|
||||||
|
action=meld_action,
|
||||||
|
})
|
||||||
meld_x=meld_x + 8
|
meld_x=meld_x + 8
|
||||||
end
|
end
|
||||||
meld_x=meld_x + 28
|
meld_x=meld_x + 28
|
||||||
end
|
end
|
||||||
|
|
||||||
if is_an_interest(points_of_interest, "New\nMeld") then
|
table.insert(elements, {
|
||||||
print("New\nMeld", meld_x, 17, 0)
|
visual="New\nMeld",
|
||||||
if hovered and hovered.interest=="New\nMeld" then
|
textx=meld_x, texty=meld_y+7,
|
||||||
spr(Card.spr_hilight.sid,
|
x=meld_x, y=meld_y,
|
||||||
meld_x,
|
action=((new_meld_allowed and rummy_is_valid_meld(draft)) and "New\nMeld" or nil),
|
||||||
10,
|
action_x=meld_x, action_y=meld_y,
|
||||||
Card.spr_hilight.colorkey,
|
})
|
||||||
1, 0, 0,
|
end
|
||||||
Card.spr_hilight.tw,
|
|
||||||
Card.spr_hilight.th)
|
function build_draw_discard_ui(elements, options)
|
||||||
end
|
local discard_x=((240 - 24) / 2)
|
||||||
|
local discard_y=80
|
||||||
|
local draw_pile_x=discard_x - 24 - 4
|
||||||
|
local end_turn_x=discard_x + 24 + 4
|
||||||
|
|
||||||
|
-- render draw pile
|
||||||
|
for i,card in ipairs(draw_pile) do
|
||||||
|
if i==#draw_pile and options.is_drawing then
|
||||||
|
table.insert(elements, {
|
||||||
|
visual=card,
|
||||||
|
x=draw_pile_x, y=discard_y + (i - 1) * -0.25,
|
||||||
|
hidden=true,
|
||||||
|
action=card,
|
||||||
|
})
|
||||||
else
|
else
|
||||||
print("New\nMeld", meld_x, 17, 13)
|
table.insert(elements, {
|
||||||
|
visual=card,
|
||||||
|
x=draw_pile_x, y=discard_y + (i - 1) * -0.25,
|
||||||
|
hidden=true,
|
||||||
|
})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- render discard pile
|
-- render discard pile
|
||||||
for i,card in ipairs(discard_pile) do
|
for i,card in ipairs(discard_pile) do
|
||||||
local sel_state = nil
|
if i==#discard_pile and options.is_drawing then
|
||||||
if hovered and hovered.interest == card then
|
table.insert(elements, {
|
||||||
sel_state = 1
|
visual=card,
|
||||||
end
|
x=discard_x, y=discard_y + (i - 1) * -0.25,
|
||||||
|
action=card,
|
||||||
card:render(discard_x, 80 + (i - 1) * -0.25, false, sel_state)
|
})
|
||||||
end
|
|
||||||
if is_an_interest(points_of_interest, "Discard") then
|
|
||||||
if hovered and hovered.interest=="Discard" then
|
|
||||||
spr(Card.spr_hilight.sid,
|
|
||||||
discard_x,
|
|
||||||
80 + (#discard_pile - 1) * -0.25,
|
|
||||||
Card.spr_hilight.colorkey,
|
|
||||||
1, 0, 0,
|
|
||||||
Card.spr_hilight.tw,
|
|
||||||
Card.spr_hilight.th)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- render draw pile
|
|
||||||
for i,card in ipairs(draw_pile) do
|
|
||||||
local sel_state = nil
|
|
||||||
if hovered and hovered.interest == card then
|
|
||||||
sel_state = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
card:render(draw_pile_x, 80 + (i - 1) * -0.25, true, sel_state)
|
|
||||||
end
|
|
||||||
|
|
||||||
if is_an_interest(points_of_interest, "End\nTurn") then
|
|
||||||
print("End\nTurn", end_turn_x, 80+7, 0)
|
|
||||||
if hovered and hovered.interest=="End\nTurn" then
|
|
||||||
spr(Card.spr_hilight.sid,
|
|
||||||
end_turn_x, 80,
|
|
||||||
Card.spr_hilight.colorkey,
|
|
||||||
1, 0, 0,
|
|
||||||
Card.spr_hilight.tw,
|
|
||||||
Card.spr_hilight.th)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
print("End\nTurn", end_turn_x, 80+7, 13)
|
table.insert(elements, {
|
||||||
|
visual=card,
|
||||||
|
x=discard_x, y=discard_y + (i - 1) * -0.25
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
table.insert(elements, {
|
||||||
|
visual=(#discard_pile==0 and Card.sprite),
|
||||||
|
x=discard_x, y=discard_y + (#discard_pile - 1) * -0.25,
|
||||||
|
action=options.discard_action,
|
||||||
|
})
|
||||||
|
|
||||||
|
table.insert(elements, {
|
||||||
|
visual="End\nTurn",
|
||||||
|
textx=end_turn_x, texty=discard_y + 7,
|
||||||
|
x=end_turn_x, y=discard_y,
|
||||||
|
action=options.end_turn_action,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function build_hand_ui(elements, hand, draft, can_select)
|
||||||
local hand_start_x=((240 - #cards_in_hand * 12 - 24) / 2)
|
local hand_start_x=((240 - #cards_in_hand * 12 - 24) / 2)
|
||||||
for i,card in ipairs(cards_in_hand) do
|
local hand_y=110
|
||||||
|
for i,card in ipairs(hand) do
|
||||||
|
if can_select then
|
||||||
local ty=0
|
local ty=0
|
||||||
local sel_state = nil
|
local sel_state = nil
|
||||||
|
|
||||||
if cards_in_meld_draft:contains(card) then
|
if draft:contains(card) then
|
||||||
ty = -4
|
ty = -4
|
||||||
sel_state = 2
|
sel_state = 2
|
||||||
end
|
end
|
||||||
|
|
||||||
if hovered and hovered.interest == card then
|
table.insert(elements, {
|
||||||
sel_state = 1
|
visual=card,
|
||||||
|
x=hand_start_x + (i - 1) * 12, y=hand_y + ty,
|
||||||
|
sel_state=sel_state,
|
||||||
|
action=card, action_y=hand_y,
|
||||||
|
})
|
||||||
|
else
|
||||||
|
table.insert(elements, {
|
||||||
|
visual=card,
|
||||||
|
x=hand_start_x + (i - 1) * 12, y=hand_y
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
card:render(hand_start_x + (i - 1) * 12, 110 + ty, false, sel_state)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
player_state_draw_card = {
|
function handler_draw_card(action)
|
||||||
update=function(point_of_interest)
|
if draw_pile:contains(action) then
|
||||||
-- only accept drawing cards from the draw pile or
|
|
||||||
if draw_pile:contains(point_of_interest.interest) then
|
|
||||||
table.insert(cards_in_hand, draw_pile:draw())
|
table.insert(cards_in_hand, draw_pile:draw())
|
||||||
cards_in_hand:sort(rummy_hand_sort_comparison)
|
cards_in_hand:sort(rummy_hand_sort_comparison)
|
||||||
hovered = nil
|
hovered = nil
|
||||||
return player_state_action
|
return { redirect=handler_player_action }
|
||||||
elseif discard_pile:contains(point_of_interest.interest) then
|
elseif discard_pile:contains(action) then
|
||||||
table.insert(cards_in_hand, discard_pile:draw())
|
table.insert(cards_in_hand, discard_pile:draw())
|
||||||
cards_in_hand:sort(rummy_hand_sort_comparison)
|
cards_in_hand:sort(rummy_hand_sort_comparison)
|
||||||
hovered = nil
|
hovered = nil
|
||||||
return player_state_action
|
return { redirect=handler_player_action }
|
||||||
end
|
|
||||||
return player_state_draw_card
|
|
||||||
end,
|
|
||||||
get_points_of_interest=function()
|
|
||||||
local points_of_interest = {}
|
|
||||||
|
|
||||||
if #draw_pile > 0 then
|
|
||||||
table.insert(points_of_interest, {
|
|
||||||
x=3 + 12,
|
|
||||||
y=80 + (#draw_pile - 1) * -0.25 + 12,
|
|
||||||
interest=draw_pile[#draw_pile]
|
|
||||||
})
|
|
||||||
end
|
|
||||||
if #discard_pile > 0 then
|
|
||||||
table.insert(points_of_interest, {
|
|
||||||
x=39 + 12,
|
|
||||||
y=80 + (#discard_pile - 1) * -0.25 + 12,
|
|
||||||
interest=discard_pile[#discard_pile]
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return points_of_interest
|
local elements={}
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
player_state_action = {
|
build_meld_ui(elements, cards_in_meld_draft, false)
|
||||||
update=function(point_of_interest)
|
build_draw_discard_ui(elements, { is_drawing=true })
|
||||||
if cards_in_hand:contains(point_of_interest.interest) then
|
build_hand_ui(elements, cards_in_hand, cards_in_meld_draft, false)
|
||||||
if cards_in_meld_draft:contains(point_of_interest.interest) then
|
|
||||||
table.remove(cards_in_meld_draft, cards_in_meld_draft:index_of(point_of_interest.interest))
|
return { page=elements }
|
||||||
|
end
|
||||||
|
|
||||||
|
function handler_player_action(action)
|
||||||
|
if cards_in_hand:contains(action) then
|
||||||
|
if cards_in_meld_draft:contains(action) then
|
||||||
|
table.remove(cards_in_meld_draft, cards_in_meld_draft:index_of(action))
|
||||||
else
|
else
|
||||||
table.insert(cards_in_meld_draft, point_of_interest.interest)
|
table.insert(cards_in_meld_draft, action)
|
||||||
cards_in_meld_draft:sort(rummy_hand_sort_comparison)
|
cards_in_meld_draft:sort(rummy_hand_sort_comparison)
|
||||||
end
|
end
|
||||||
elseif point_of_interest.interest=="New\nMeld" then
|
elseif action=="New\nMeld" then
|
||||||
if rummy_is_valid_meld(cards_in_meld_draft) then
|
if rummy_is_valid_meld(cards_in_meld_draft) then
|
||||||
for i,card in ipairs(cards_in_meld_draft) do
|
for i,card in ipairs(cards_in_meld_draft) do
|
||||||
table.remove(cards_in_hand, cards_in_hand:index_of(card))
|
table.remove(cards_in_hand, cards_in_hand:index_of(card))
|
||||||
|
@ -239,17 +312,17 @@ player_state_action = {
|
||||||
table.insert(melds_on_tabletop, cards_in_meld_draft)
|
table.insert(melds_on_tabletop, cards_in_meld_draft)
|
||||||
cards_in_meld_draft=CardStack:new()
|
cards_in_meld_draft=CardStack:new()
|
||||||
hovered = nil
|
hovered = nil
|
||||||
return player_state_secondary_action
|
return { redirect=handler_player_secondary_action }
|
||||||
end
|
end
|
||||||
elseif point_of_interest.interest=="Discard" then
|
elseif action=="Discard" then
|
||||||
if #cards_in_meld_draft==1 then
|
if #cards_in_meld_draft==1 then
|
||||||
table.remove(cards_in_hand, cards_in_hand:index_of(cards_in_meld_draft[1]))
|
table.remove(cards_in_hand, cards_in_hand:index_of(cards_in_meld_draft[1]))
|
||||||
table.insert(discard_pile, cards_in_meld_draft[1])
|
table.insert(discard_pile, cards_in_meld_draft[1])
|
||||||
cards_in_meld_draft=CardStack:new()
|
cards_in_meld_draft=CardStack:new()
|
||||||
hovered = nil
|
hovered = nil
|
||||||
return player_state_discard_confirm
|
return { redirect=handler_discard_confirm }
|
||||||
end
|
end
|
||||||
elseif table_index_of(melds_on_tabletop, point_of_interest.interest) then
|
elseif table_index_of(melds_on_tabletop, action) then
|
||||||
local meld=point_of_interest.interest
|
local meld=point_of_interest.interest
|
||||||
local meld_with_draft=meld:with(cards_in_meld_draft)
|
local meld_with_draft=meld:with(cards_in_meld_draft)
|
||||||
if rummy_is_valid_meld(meld_with_draft) then
|
if rummy_is_valid_meld(meld_with_draft) then
|
||||||
|
@ -261,71 +334,35 @@ player_state_action = {
|
||||||
cards_in_meld_draft=CardStack:new()
|
cards_in_meld_draft=CardStack:new()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return player_state_action
|
|
||||||
end,
|
|
||||||
get_points_of_interest=function()
|
|
||||||
local points_of_interest = {}
|
|
||||||
|
|
||||||
for i,card in ipairs(cards_in_hand) do
|
local elements={}
|
||||||
table.insert(points_of_interest, {
|
|
||||||
x=(i - 1) * 12 + 2 + 5,
|
build_meld_ui(elements, cards_in_meld_draft, true)
|
||||||
y=122,
|
build_draw_discard_ui(elements, {
|
||||||
interest=card
|
discard_action=(#cards_in_meld_draft==1 and "Discard" or nil),
|
||||||
})
|
})
|
||||||
end
|
build_hand_ui(elements, cards_in_hand, cards_in_meld_draft, true)
|
||||||
|
|
||||||
if rummy_is_valid_meld(cards_in_meld_draft) then
|
return { page=elements }
|
||||||
table.insert(points_of_interest, {
|
end
|
||||||
x=80 + 12,
|
|
||||||
y=17 + 6,
|
|
||||||
interest="New\nMeld"
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if #cards_in_meld_draft==1 then
|
function handler_player_secondary_action(action)
|
||||||
table.insert(points_of_interest, {
|
if cards_in_hand:contains(action) then
|
||||||
x=39,
|
if cards_in_meld_draft:contains(action) then
|
||||||
y=80 + (#discard_pile - 1) * -0.25,
|
table.remove(cards_in_meld_draft, cards_in_meld_draft:index_of(action))
|
||||||
interest="Discard"
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if #cards_in_meld_draft>0 then
|
|
||||||
for i,meld in ipairs(melds_on_tabletop) do
|
|
||||||
local meld_with_draft=meld:with(cards_in_meld_draft)
|
|
||||||
if rummy_is_valid_meld(meld_with_draft) then
|
|
||||||
table.insert(points_of_interest, {
|
|
||||||
x=i * 36,
|
|
||||||
y=10,
|
|
||||||
interest=meld
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return points_of_interest
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
-- In this state the player may only lay off a card or end their turn
|
|
||||||
player_state_secondary_action = {
|
|
||||||
update=function(point_of_interest)
|
|
||||||
if cards_in_hand:contains(point_of_interest.interest) then
|
|
||||||
if cards_in_meld_draft:contains(point_of_interest.interest) then
|
|
||||||
table.remove(cards_in_meld_draft, cards_in_meld_draft:index_of(point_of_interest.interest))
|
|
||||||
else
|
else
|
||||||
table.insert(cards_in_meld_draft, point_of_interest.interest)
|
table.insert(cards_in_meld_draft, action)
|
||||||
cards_in_meld_draft:sort(rummy_hand_sort_comparison)
|
cards_in_meld_draft:sort(rummy_hand_sort_comparison)
|
||||||
end
|
end
|
||||||
elseif point_of_interest.interest=="Discard" then
|
elseif action=="Discard" then
|
||||||
if #cards_in_meld_draft==1 then
|
if #cards_in_meld_draft==1 then
|
||||||
table.remove(cards_in_hand, cards_in_hand:index_of(cards_in_meld_draft[1]))
|
table.remove(cards_in_hand, cards_in_hand:index_of(cards_in_meld_draft[1]))
|
||||||
table.insert(discard_pile, cards_in_meld_draft[1])
|
table.insert(discard_pile, cards_in_meld_draft[1])
|
||||||
cards_in_meld_draft=CardStack:new()
|
cards_in_meld_draft=CardStack:new()
|
||||||
hovered = nil
|
hovered = nil
|
||||||
return player_state_discard_confirm
|
return { redirect=handler_discard_confirm }
|
||||||
end
|
end
|
||||||
elseif table_index_of(melds_on_tabletop, point_of_interest.interest) then
|
elseif table_index_of(melds_on_tabletop, action) then
|
||||||
local meld=point_of_interest.interest
|
local meld=point_of_interest.interest
|
||||||
local meld_with_draft=meld:with(cards_in_meld_draft)
|
local meld_with_draft=meld:with(cards_in_meld_draft)
|
||||||
if rummy_is_valid_meld(meld_with_draft) then
|
if rummy_is_valid_meld(meld_with_draft) then
|
||||||
|
@ -337,73 +374,33 @@ player_state_secondary_action = {
|
||||||
cards_in_meld_draft=CardStack:new()
|
cards_in_meld_draft=CardStack:new()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return player_state_secondary_action
|
|
||||||
end,
|
|
||||||
get_points_of_interest=function()
|
|
||||||
local points_of_interest = {}
|
|
||||||
|
|
||||||
for i,card in ipairs(cards_in_hand) do
|
local elements={}
|
||||||
table.insert(points_of_interest, {
|
|
||||||
x=(i - 1) * 12 + 2 + 5,
|
build_meld_ui(elements, cards_in_meld_draft, false)
|
||||||
y=122,
|
build_draw_discard_ui(elements, {
|
||||||
interest=card
|
discard_action=(#cards_in_meld_draft==1 and "Discard" or nil),
|
||||||
})
|
})
|
||||||
end
|
build_hand_ui(elements, cards_in_hand, cards_in_meld_draft, true)
|
||||||
|
|
||||||
if #cards_in_meld_draft==1 then
|
return { page=elements }
|
||||||
table.insert(points_of_interest, {
|
end
|
||||||
x=39,
|
|
||||||
y=80 + (#discard_pile - 1) * -0.25,
|
|
||||||
interest="Discard"
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if #cards_in_meld_draft>0 then
|
function handler_discard_confirm(action)
|
||||||
for i,meld in ipairs(melds_on_tabletop) do
|
if action=="End\nTurn" then
|
||||||
local meld_with_draft=meld:with(cards_in_meld_draft)
|
|
||||||
if rummy_is_valid_meld(meld_with_draft) then
|
|
||||||
table.insert(points_of_interest, {
|
|
||||||
x=i * 36,
|
|
||||||
y=10,
|
|
||||||
interest=meld
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return points_of_interest
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
player_state_discard_confirm = {
|
|
||||||
update=function(point_of_interest)
|
|
||||||
if point_of_interest.interest=="End\nTurn" then
|
|
||||||
hovered = nil
|
hovered = nil
|
||||||
return player_state_draw_card
|
return { redirect=handler_draw_card }
|
||||||
end
|
end
|
||||||
|
|
||||||
return player_state_discard_confirm
|
local elements={}
|
||||||
end,
|
|
||||||
get_points_of_interest=function()
|
|
||||||
local points_of_interest = {}
|
|
||||||
|
|
||||||
table.insert(points_of_interest, {
|
build_meld_ui(elements, cards_in_meld_draft, false)
|
||||||
x=80 + 12,
|
build_draw_discard_ui(elements, {
|
||||||
y=87 + 6,
|
end_turn_action="End\nTurn",
|
||||||
interest="End\nTurn"
|
|
||||||
})
|
})
|
||||||
|
build_hand_ui(elements, cards_in_hand, cards_in_meld_draft, false)
|
||||||
|
|
||||||
return points_of_interest
|
return { page=elements }
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_an_interest(points_of_interest,interest_sought)
|
|
||||||
for i,point in ipairs(points_of_interest) do
|
|
||||||
if point.interest==interest_sought then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function distance_to_point_of_interest(start,dir,point_of_interest)
|
function distance_to_point_of_interest(start,dir,point_of_interest)
|
||||||
|
@ -559,46 +556,59 @@ function CardStack:with(other)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Sprite={}
|
||||||
|
Sprite.__index=Sprite
|
||||||
|
function Sprite:new(obj)
|
||||||
|
local o = obj or {}
|
||||||
|
setmetatable(o, Sprite)
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
-- Card rendering stuff
|
-- Card rendering stuff
|
||||||
suit_icon={34,35,33,36}
|
suit_icon={34,35,33,36}
|
||||||
suit_color={0,0,2,2}
|
suit_color={0,0,2,2}
|
||||||
suit_names={'clubs','spades','hearts','diamonds'}
|
suit_names={'clubs','spades','hearts','diamonds'}
|
||||||
rank_symbols={'A','2','3','4','5','6','7','8','9','10','J','Q','K'}
|
rank_symbols={'A','2','3','4','5','6','7','8','9','10','J','Q','K'}
|
||||||
Card = {
|
Card = {
|
||||||
sprite={
|
sprite=Sprite:new({
|
||||||
sid=5,
|
sid=5,
|
||||||
tw=3,
|
tw=3,
|
||||||
th=3,
|
th=3,
|
||||||
colorkey=14
|
colorkey=14
|
||||||
},
|
}),
|
||||||
spr_hilight={
|
spr_hilight=Sprite:new({
|
||||||
sid=8,
|
sid=8,
|
||||||
tw=3,
|
tw=3,
|
||||||
th=3,
|
th=3,
|
||||||
colorkey=14
|
colorkey=14
|
||||||
},
|
}),
|
||||||
spr_selected={
|
spr_selected=Sprite:new({
|
||||||
sid=11,
|
sid=11,
|
||||||
tw=3,
|
tw=3,
|
||||||
th=3,
|
th=3,
|
||||||
colorkey=14
|
colorkey=14
|
||||||
},
|
}),
|
||||||
spr_hidden={
|
spr_hidden=Sprite:new({
|
||||||
sid=56,
|
sid=56,
|
||||||
tw=3,
|
tw=3,
|
||||||
th=3,
|
th=3,
|
||||||
colorkey=14
|
colorkey=14
|
||||||
},
|
}),
|
||||||
}
|
}
|
||||||
|
Card.__index = Card
|
||||||
function Card:new(suit, rank)
|
function Card:new(suit, rank)
|
||||||
local card = {
|
local card = {
|
||||||
suit=suit,
|
suit=suit,
|
||||||
rank=rank,
|
rank=rank,
|
||||||
}
|
}
|
||||||
setmetatable(card, { __index=Card })
|
setmetatable(card, Card)
|
||||||
return card
|
return card
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Card:__tostring(suit, rank)
|
||||||
|
return "<"..rank_symbols[self.rank].." of "..suit_names[self.suit]..">"
|
||||||
|
end
|
||||||
|
|
||||||
function Card:render(x, y, hidden, sel_state)
|
function Card:render(x, y, hidden, sel_state)
|
||||||
if hidden then
|
if hidden then
|
||||||
spr(self.spr_hidden.sid,
|
spr(self.spr_hidden.sid,
|
||||||
|
|
Loading…
Reference in New Issue