Try another smart dealer implementation
This commit is contained in:
parent
dbd9c600c8
commit
e4e6887e64
56
board.lua
56
board.lua
@ -44,64 +44,24 @@ function board:init(ruleset)
|
||||
end
|
||||
|
||||
function board:deal()
|
||||
local deal=deal(self.ruleset)
|
||||
local n_usable_slots=self.ruleset.n_slots - 1
|
||||
-- first, pull the aces
|
||||
local available={}
|
||||
for card=1,#self.ruleset.deck.cards do
|
||||
available[card]=true
|
||||
end
|
||||
|
||||
for i=1,#self.ruleset.deck.aces do
|
||||
local well=self.wells[i]
|
||||
local ace=self.ruleset.deck.aces[i]
|
||||
well:add(ace) -- temporarily, so would_accept will work
|
||||
self:animate_move_ace_to_well(ace,i)
|
||||
available[ace]=false
|
||||
end
|
||||
|
||||
local eligible_bottom_row={}
|
||||
for card=1,#self.ruleset.deck.cards do
|
||||
local skip
|
||||
if not available[card] then
|
||||
skip=true
|
||||
else
|
||||
for w in all(self.wells) do
|
||||
if (w:would_accept(card)) skip=true break
|
||||
local rows=#deal[1]
|
||||
for y=1,rows do
|
||||
for x=1,#deal do
|
||||
local outx=x
|
||||
if (x>n_usable_slots\2) outx+=1
|
||||
self:animate_move_new_card_to_slot(deal[x][y],outx)
|
||||
end
|
||||
end
|
||||
if (not skip) add(eligible_bottom_row,card)
|
||||
end
|
||||
|
||||
-- let the animation install the aces for real
|
||||
for w in all(self.wells) do
|
||||
w:clear()
|
||||
end
|
||||
|
||||
function i_to_slot(i)
|
||||
if (i<n_usable_slots\2) return i+1
|
||||
return i+2
|
||||
end
|
||||
|
||||
local bottom_row={}
|
||||
shuf(eligible_bottom_row)
|
||||
for i=1,n_usable_slots do
|
||||
local card=eligible_bottom_row[i]
|
||||
add(bottom_row,card)
|
||||
available[card]=false
|
||||
end
|
||||
|
||||
eligible={}
|
||||
for card=1,#self.ruleset.deck.cards do
|
||||
if (available[card]) add(eligible,card)
|
||||
end
|
||||
shuf(eligible)
|
||||
for card in all(bottom_row) do
|
||||
add(eligible,card)
|
||||
end
|
||||
for i=1,#eligible do
|
||||
local ix=i_to_slot((i-1)%n_usable_slots)
|
||||
local slot=self.slots[ix]
|
||||
self:animate_move_new_card_to_slot(eligible[i],ix)
|
||||
end
|
||||
end
|
||||
|
||||
function board:on_idle()
|
||||
|
33
dealer.lua
33
dealer.lua
@ -30,7 +30,7 @@ function deal(ruleset)
|
||||
if (card and accepts(lst[#lst-1],card)) return pop(lst)
|
||||
end
|
||||
|
||||
local function find_home(odds,card,source,exclude)
|
||||
local function find_home(prefer_acceptor,card,source,exclude,ignore_acceptorhood)
|
||||
assert(card!=0)
|
||||
local acceptors={}
|
||||
local start_points={}
|
||||
@ -41,17 +41,20 @@ function deal(ruleset)
|
||||
-- don't place it here ever
|
||||
elseif ruleset.deck.instantly_accepted[card] and n==max_height[s]-1 then
|
||||
-- can't place an instantly accepted card at the bottom of a slot
|
||||
elseif not ignore_acceptorhood and accepts(pek(slots[s]),card) then
|
||||
add(acceptors,s)
|
||||
elseif n<max_height[s] then
|
||||
add(start_points,s)
|
||||
end
|
||||
end
|
||||
|
||||
local a
|
||||
if prefer_acceptor then
|
||||
a=rnd(acceptors) or rnd(start_points) or source
|
||||
else
|
||||
if (accepts(pek(slots[s]),card)) add(acceptors,s)
|
||||
if (n<max_height[s]) add(start_points,s)
|
||||
end
|
||||
a=rnd(start_points) or rnd(acceptors) or source
|
||||
end
|
||||
|
||||
local acceptor=rnd(acceptors)
|
||||
local start_point=rnd(start_points)
|
||||
if (acceptor and rnd()>odds) acceptor=nil
|
||||
|
||||
local a=acceptor or start_point or source
|
||||
if (a) add(slots[a],card) return true
|
||||
end
|
||||
|
||||
@ -65,22 +68,18 @@ function deal(ruleset)
|
||||
if w <= ruleset.n_suits then
|
||||
local c=pop(slots[0])
|
||||
assert(c!=0)
|
||||
if (c and not find_home(1.0,c,nil,0)) return
|
||||
if (c and not find_home(false,c,nil,0)) return
|
||||
exclude = 0
|
||||
end
|
||||
|
||||
local card=pop(wells[w])
|
||||
assert(card!=0)
|
||||
if (not find_home(1.0,card,nil,exclude)) return
|
||||
if (not find_home(true,card,nil,exclude)) return
|
||||
|
||||
local n_moves=48
|
||||
for i=1,n_moves do
|
||||
local src=flr(rnd()*(#slots+1))
|
||||
local card=pop_accepted_card(slots[src])
|
||||
if card then
|
||||
local odds=0.0
|
||||
if (not find_home(odds,card,src,nil)) return
|
||||
end
|
||||
if (not find_home(false,card,src,nil)) return
|
||||
end
|
||||
end
|
||||
|
||||
@ -89,7 +88,7 @@ function deal(ruleset)
|
||||
for i=0,#slots do
|
||||
while #slots[i]>max_height[i] do
|
||||
local card=pop(slots[i])
|
||||
if (not find_home(0.0,card,nil,nil)) return
|
||||
if (not find_home(false,card,nil,nil,true)) return
|
||||
end
|
||||
end
|
||||
|
||||
|
1
main.p8
1
main.p8
@ -9,6 +9,7 @@ __lua__
|
||||
#include layout.lua
|
||||
#include ruleset.lua
|
||||
#include progression.lua
|
||||
#include dealer.lua
|
||||
#include main.lua
|
||||
__gfx__
|
||||
00000000070000007770000000700000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
|
13
ruleset.lua
13
ruleset.lua
@ -32,17 +32,19 @@ function ruleset:init(
|
||||
local usable_slots = n_slots - 1
|
||||
assert(usable_slots%2==0)
|
||||
|
||||
local total_n_cards = n_arcana + n_suits * n_cards_per_suit
|
||||
local n_total_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
|
||||
local n_usable_cards = n_total_cards - self.n_suits
|
||||
|
||||
-- deal has to be symmetrical
|
||||
assert(usable_n_cards % usable_slots == 0, usable_slots-(usable_n_cards%usable_slots))
|
||||
assert(n_usable_cards % usable_slots == 0, usable_slots-(n_usable_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)
|
||||
assert((n_total_cards-instantly_placed_cards)-usable_slots >= 0)
|
||||
|
||||
self.n_usable_cards = n_usable_cards
|
||||
|
||||
self:generate_deck()
|
||||
self:generate_layouts()
|
||||
@ -55,6 +57,7 @@ function ruleset:generate_deck()
|
||||
aces={},
|
||||
suits={},
|
||||
cards={},
|
||||
instantly_accepted={},
|
||||
rank_name="a23456789tjqk"
|
||||
}
|
||||
self.deck=deck
|
||||
@ -67,12 +70,14 @@ function ruleset:generate_deck()
|
||||
for rank=1,self.n_cards_per_suit do
|
||||
add(deck.cards,{suit=suit,rank=rank})
|
||||
if (rank==1) add(deck.aces,#deck.cards)
|
||||
if (rank==2) deck.instantly_accepted[#deck.cards]=true
|
||||
end
|
||||
end
|
||||
|
||||
-- arcana
|
||||
for rank=0,self.n_arcana-1 do
|
||||
add(deck.cards,{suit="a",rank=rank})
|
||||
if (rank==0 or rank==self.n_arcana-1) deck.instantly_accepted[#deck.cards]=true
|
||||
end
|
||||
|
||||
function deck:draw_card(x,y,c,shadow)
|
||||
|
Loading…
Reference in New Issue
Block a user