120 lines
2.5 KiB
Rust
120 lines
2.5 KiB
Rust
use board::Board;
|
|
use pico_rng::PicoRng;
|
|
use ruleset::Ruleset;
|
|
use seen::Seen;
|
|
|
|
use crate::smart_dealer::Deal;
|
|
|
|
mod board;
|
|
mod ruleset;
|
|
mod pico_rng;
|
|
mod seen;
|
|
mod smart_dealer;
|
|
mod zobrist;
|
|
|
|
|
|
fn main() {
|
|
let mut rng = PicoRng::srand(0x20000);
|
|
for _ in 0..10 {
|
|
println!("{}", rng.rnd(0x10000));
|
|
}
|
|
return;
|
|
|
|
let ruleset = Ruleset {
|
|
n_slots: 11,
|
|
n_suits: 5,
|
|
n_cards_per_suit: 10,
|
|
n_arcana: 25
|
|
};
|
|
/*
|
|
let ruleset = Ruleset {
|
|
n_slots: 11,
|
|
n_suits: 4,
|
|
n_cards_per_suit: 13,
|
|
n_arcana: 22
|
|
};
|
|
*/
|
|
/*
|
|
let ruleset = Ruleset {
|
|
n_slots: 5,
|
|
n_suits: 1,
|
|
n_cards_per_suit: 9,
|
|
n_arcana: 0
|
|
};
|
|
*/
|
|
/*
|
|
let ruleset = Ruleset {
|
|
n_slots: 7,
|
|
n_suits: 2,
|
|
n_cards_per_suit: 9,
|
|
n_arcana: 8
|
|
};
|
|
*/
|
|
/*
|
|
let ruleset = Ruleset {
|
|
n_slots: 9,
|
|
n_suits: 3,
|
|
n_cards_per_suit: 11,
|
|
n_arcana: 18
|
|
};
|
|
*/
|
|
let setup = ruleset.compile().expect("compilation should succeed");
|
|
/*
|
|
for _ in 0..10000 {
|
|
Deal::deal(&setup, &mut rand::thread_rng());
|
|
}
|
|
*/
|
|
|
|
let mut winnable = 0;
|
|
let mut total = 0;
|
|
loop {
|
|
let mut board = Board::new(&setup);
|
|
board.deal(Deal::deal(&setup, &mut rand::thread_rng()));
|
|
board.display();
|
|
|
|
if is_winnable(board) {
|
|
winnable += 1;
|
|
}
|
|
total += 1;
|
|
println!("winnable: {}/{} ({}%)", winnable, total, (100.0 * winnable as f32)/(total as f32));
|
|
}
|
|
|
|
// println!("Legal moves: {:#?}", board.legal_moves());
|
|
|
|
}
|
|
|
|
fn is_winnable(mut board: Board<'_>) -> bool {
|
|
let mut seen = Seen::new();
|
|
|
|
explore(0, &mut board, &mut seen)
|
|
}
|
|
|
|
fn explore(depth: usize, board: &mut Board<'_>, seen: &mut Seen) -> bool {
|
|
if depth > 200 {
|
|
return false;
|
|
}
|
|
|
|
if seen.contains(board.zobrist_key()) {
|
|
return false
|
|
}
|
|
seen.add(board.zobrist_key());
|
|
|
|
if board.is_won() {
|
|
board.display();
|
|
return true
|
|
}
|
|
|
|
for m in board.legal_moves() {
|
|
let hash_1 = board.zobrist_key();
|
|
board.perform(m);
|
|
// println!("try: {:X?} {:?}", board.zobrist_key(), m);
|
|
if explore(depth + 1, board, seen) {
|
|
return true;
|
|
}
|
|
// println!("undo: {:X?} {:?}", board.zobrist_key(), m);
|
|
board.undo();
|
|
let hash_2 = board.zobrist_key();
|
|
assert_eq!(hash_1, hash_2)
|
|
}
|
|
return false;
|
|
} |