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;
}