... I wasn't actually calling the right generator

This commit is contained in:
Pyrex 2024-02-08 17:04:33 -08:00
parent ef1c014575
commit 00ed414b1a
6 changed files with 66 additions and 68 deletions

View File

@ -44,63 +44,23 @@ function board:init(ruleset)
end end
function board:deal() function board:deal()
local deal=deal(self.ruleset)
local n_usable_slots=self.ruleset.n_slots - 1 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 for i=1,#self.ruleset.deck.aces do
local well=self.wells[i] local well=self.wells[i]
local ace=self.ruleset.deck.aces[i] local ace=self.ruleset.deck.aces[i]
well:add(ace) -- temporarily, so would_accept will work well:add(ace) -- temporarily, so would_accept will work
self:animate_move_ace_to_well(ace,i) self:animate_move_ace_to_well(ace,i)
available[ace]=false
end end
local eligible_bottom_row={} local rows=#deal[1]
for card=1,#self.ruleset.deck.cards do for y=1,rows do
local skip for x=1,#deal do
if not available[card] then local outx=x
skip=true if (x>n_usable_slots\2) outx+=1
else self:animate_move_new_card_to_slot(deal[x][y],outx)
for w in all(self.wells) do
if (w:would_accept(card)) skip=true break
end
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
end end

View File

@ -33,26 +33,15 @@ function deal(ruleset)
local function find_home(card,allow_too_tall) local function find_home(card,allow_too_tall)
assert(card!=0) assert(card!=0)
local acceptors={} local acceptors={}
local start_points={}
for s=0,#slots do for s=0,#slots do
local n=#slots[s] local n=#slots[s]
if s==exclude then if ((allow_too_tall and accepts(pek(slots[s]),card)) or n<max_height[s]) add(acceptors,s)
-- 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
else
if (accepts(pek(slots[s]),card)) add(acceptors,s)
if (n<max_height[s]) add(start_points,s)
end
end end
local acceptor=rnd(acceptors) local a=rnd(acceptors)
local start_point=rnd(start_points) assert(a)
if (acceptor and rnd()>odds) acceptor=nil add(slots[a],card)
local a=acceptor or start_point or source
if (a) add(slots[a],card) return true
end end
local original_pops=#pops local original_pops=#pops
@ -67,7 +56,7 @@ 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(card,false)) return find_home(card,false)
end end
end end
@ -143,5 +132,6 @@ function deal(ruleset)
while true do while true do
local d=deal1() local d=deal1()
if (d) return d if (d) return d
print("retrying")
end end
end end

View File

@ -5,11 +5,19 @@ __lua__
#include animator.lua #include animator.lua
#include board.lua #include board.lua
#include board_animations.lua #include board_animations.lua
#include dealer.lua
#include cursor.lua #include cursor.lua
#include layout.lua #include layout.lua
#include ruleset.lua #include ruleset.lua
#include progression.lua #include progression.lua
#include main.lua #include main.lua
--[[
srand(2)
for i=1,10 do
print(tostr(rnd(),2))
end
stop()]]
__gfx__ __gfx__
00000000000000000000000000000000777770000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000777770000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000007000000777000000070000700070000707070000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000007000000777000000070000700070000707070000000000000000000000000000000000000000000000000000000000000000000000000000000000

View File

@ -32,17 +32,20 @@ function ruleset:init(
local usable_slots = n_slots - 1 local usable_slots = n_slots - 1
assert(usable_slots%2==0) 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 -- 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
self.n_total_cards=n_total_cards
self.n_usable_cards=n_usable_cards
-- deal has to be symmetrical -- 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 -- these cards would be instantly moved to the wells and
-- therefore cannot be in the bottom row -- therefore cannot be in the bottom row
local instantly_placed_cards = self.n_suits + 2 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:generate_deck() self:generate_deck()
self:generate_layouts() self:generate_layouts()
@ -55,6 +58,7 @@ function ruleset:generate_deck()
aces={}, aces={},
suits={}, suits={},
cards={}, cards={},
instantly_accepted={},
rank_name="a23456789tjqk" rank_name="a23456789tjqk"
} }
self.deck=deck self.deck=deck
@ -67,12 +71,14 @@ function ruleset:generate_deck()
for rank=1,self.n_cards_per_suit do for rank=1,self.n_cards_per_suit do
add(deck.cards,{suit=suit,rank=rank}) add(deck.cards,{suit=suit,rank=rank})
if (rank==1) add(deck.aces,#deck.cards) if (rank==1) add(deck.aces,#deck.cards)
if (rank==2) deck.instantly_accepted[#deck.cards]=true
end end
end end
-- arcana -- arcana
for rank=0,self.n_arcana-1 do for rank=0,self.n_arcana-1 do
add(deck.cards,{suit="a",rank=rank}) add(deck.cards,{suit="a",rank=rank})
if (rank==0 or rank==self.n_arcana-1) deck.instantly_accepted[#deck.cards]=true
end end
function deck:draw_card(x,y,c,shadow) function deck:draw_card(x,y,c,shadow)

View File

@ -1,4 +1,5 @@
use board::Board; use board::Board;
use pico_rng::PicoRng;
use ruleset::Ruleset; use ruleset::Ruleset;
use seen::Seen; use seen::Seen;
@ -6,12 +7,19 @@ use crate::smart_dealer::Deal;
mod board; mod board;
mod ruleset; mod ruleset;
mod pico_rng;
mod seen; mod seen;
mod smart_dealer; mod smart_dealer;
mod zobrist; mod zobrist;
fn main() { fn main() {
let mut rng = PicoRng::srand(0x20000);
for _ in 0..10 {
println!("{}", rng.rnd(0x10000));
}
return;
let ruleset = Ruleset { let ruleset = Ruleset {
n_slots: 11, n_slots: 11,
n_suits: 5, n_suits: 5,

View File

@ -0,0 +1,26 @@
pub struct PicoRng {
hi: u32,
lo: u32
}
impl PicoRng {
// https://www.lexaloffle.com/bbs/?tid=51113
pub fn srand(seed: u32) -> PicoRng {
let mut rng = if seed == 0 {
PicoRng { hi: 0x60009755, lo: 0xdeadbeef }
} else {
PicoRng { hi: seed ^ 0xbead29ba, lo: seed }
};
for _ in 0..0x20 {
rng.rnd(0x10000);
}
return rng
}
pub fn rnd(&mut self, n: u32) -> u32 {
self.hi = self.hi.rotate_left(0x10).wrapping_add(self.lo);
self.lo += self.hi;
return self.hi % n
}
}