Improve lua dealer
This commit is contained in:
parent
a936329a55
commit
3d6e171caa
45
dealer.lua
45
dealer.lua
@ -30,7 +30,7 @@ function deal(ruleset)
|
|||||||
if (card and accepts(lst[#lst-1],card)) return pop(lst)
|
if (card and accepts(lst[#lst-1],card)) return pop(lst)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function find_home(odds,card,source,exclude)
|
local function find_home(card,allow_too_tall)
|
||||||
assert(card!=0)
|
assert(card!=0)
|
||||||
local acceptors={}
|
local acceptors={}
|
||||||
local start_points={}
|
local start_points={}
|
||||||
@ -57,31 +57,9 @@ function deal(ruleset)
|
|||||||
|
|
||||||
local original_pops=#pops
|
local original_pops=#pops
|
||||||
while #pops>0 do
|
while #pops>0 do
|
||||||
local w=deli(pops)
|
local w=pop(pops)
|
||||||
assert(w!=0)
|
|
||||||
local exclude
|
|
||||||
|
|
||||||
-- unblock aux slot if this is not arcana
|
|
||||||
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
|
|
||||||
exclude = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local card=pop(wells[w])
|
local card=pop(wells[w])
|
||||||
assert(card!=0)
|
find_home(card,true)
|
||||||
if (not find_home(1.0,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
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- fix any stacks that are too tall
|
-- fix any stacks that are too tall
|
||||||
@ -89,14 +67,27 @@ function deal(ruleset)
|
|||||||
for i=0,#slots do
|
for i=0,#slots do
|
||||||
while #slots[i]>max_height[i] do
|
while #slots[i]>max_height[i] do
|
||||||
local card=pop(slots[i])
|
local card=pop(slots[i])
|
||||||
if (not find_home(0.0,card,nil,nil)) return
|
if (not find_home(card,false)) return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get rid of auxiliary slot
|
-- get rid of auxiliary slot
|
||||||
slots[0]=nil
|
slots[0]=nil
|
||||||
|
local shuffles=1
|
||||||
|
local actual_shuffles=1
|
||||||
|
for s=1,#slots do
|
||||||
|
local extra_shuf=shuffles+1
|
||||||
|
while (ruleset.deck.instantly_accepted[pek(slots[s])]) do
|
||||||
|
shuf(slots[s])
|
||||||
|
shuffles=extra_shuf
|
||||||
|
actual_shuffles+=1
|
||||||
|
if (actual_shuffles>=5) return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for i=shuffles,2 do
|
||||||
|
shuf(rnd(slots))
|
||||||
|
end
|
||||||
for s=1,#slots do
|
for s=1,#slots do
|
||||||
if (ruleset.deck.instantly_accepted[pek(slots[s])]) return
|
|
||||||
assert(#slots[s]==tower_height)
|
assert(#slots[s]==tower_height)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ impl Deal {
|
|||||||
while let Some((w, n)) = pops.pop() {
|
while let Some((w, n)) = pops.pop() {
|
||||||
for _ in 0..n {
|
for _ in 0..n {
|
||||||
let card = wells[w].pop().expect("card must be present");
|
let card = wells[w].pop().expect("card must be present");
|
||||||
Self::find_home(setup, rng, card, None, None, &mut slots, &max_height, true);
|
Self::find_home(setup, rng, card, &mut slots, &max_height, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ impl Deal {
|
|||||||
for i in 0..slots.len() {
|
for i in 0..slots.len() {
|
||||||
while slots[i].len() > max_height[i] {
|
while slots[i].len() > max_height[i] {
|
||||||
let card = slots[i].pop().expect("must be a card");
|
let card = slots[i].pop().expect("must be a card");
|
||||||
Self::find_home(setup, rng, card, None, None, &mut slots, &max_height, false);
|
Self::find_home(setup, rng, card, &mut slots, &max_height, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,28 +127,21 @@ impl Deal {
|
|||||||
rle
|
rle
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_home(setup: &Setup, rng: &mut impl Rng, card: Card, source: Option<usize>, exclude: Option<usize>, slots: &mut [Vec<Card>], max_height: &[usize], allow_too_tall: bool) {
|
fn find_home(setup: &Setup, rng: &mut impl Rng, card: Card, slots: &mut [Vec<Card>], max_height: &[usize], allow_too_tall: bool) {
|
||||||
// if a card is sitting on an acceptor, it could have been moved there
|
// if a card is sitting on an acceptor, it could have been moved there
|
||||||
// from somewhere else
|
// from somewhere else
|
||||||
let mut acceptors = vec![];
|
let mut acceptors = vec![];
|
||||||
|
|
||||||
for s in 0..slots.len() {
|
for s in 0..slots.len() {
|
||||||
if Some(s) == exclude {
|
if (allow_too_tall && accepts(setup, slots[s].last().cloned(), card)) ||
|
||||||
// don't place it here, ever
|
slots[s].len() < max_height[s] {
|
||||||
} else if false { // slots[s].len() == max_height[s] - 1 && setup.deck.instantly_accepted.contains(&card) {
|
|
||||||
// can't place an instantly accepted card at the bottom of a slot
|
|
||||||
} else {
|
|
||||||
if allow_too_tall && accepts(setup, slots[s].last().cloned(), card) {
|
|
||||||
acceptors.push(s);
|
acceptors.push(s);
|
||||||
} else if slots[s].len() < max_height[s] {
|
|
||||||
acceptors.push(s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let acceptor = acceptors.choose(rng).cloned();
|
let acceptor = acceptors.choose(rng).cloned();
|
||||||
|
|
||||||
if let Some(a) = acceptor.or(source) {
|
if let Some(a) = acceptor {
|
||||||
slots[a].push(card);
|
slots[a].push(card);
|
||||||
} else {
|
} else {
|
||||||
panic!("should never happen")
|
panic!("should never happen")
|
||||||
|
Loading…
Reference in New Issue
Block a user