use fickle::fickle; use ncpig::prelude::*; use ncpig_testing::number_claim::*; use ncpig_testing::tic_tac_toe::*; use rand::rngs::ThreadRng; use rand::seq::index; #[test] fn takes_winning_move_number_claim() -> anyhow::Result<()> { // env_logger::init(); let game: NumberClaim<2, 4> = NumberClaim::new([7, 6, 5, 1])?; let state = NumberClaimState::new( [[Some(7), None, None, None], [Some(5), None, None, None]], Some(1), ); let search = MonteCarloTreeSearch::builder().build::(); let action = search.choose_action(&game, &state)?.unwrap(); assert_eq!(action, 6); Ok(()) } #[test] fn takes_winning_move_tic_tac_toe() -> anyhow::Result<()> { // env_logger::init(); let game = TicTacToe; let state = TicTacToeState::new( [ [None, Some(TicTacToePlayer::O), Some(TicTacToePlayer::O)], [Some(TicTacToePlayer::X), Some(TicTacToePlayer::X), None], [None, None, None], ], TicTacToePlayer::X, ); let search = MonteCarloTreeSearch::builder().build::(); let action = search.choose_action(&game, &state)?.unwrap(); assert_eq!(action, "mr".parse()?); Ok(()) } #[test] #[fickle] fn beats_random_number_claim() -> anyhow::Result<()> { // env_logger::init(); let mut rng = ThreadRng::default(); let pool = index::sample(&mut rng, 100, 10).into_iter().map(|n| n as _); let game: NumberClaim<2, 10> = NumberClaim::new(pool)?; let mut state = NumberClaimState::default(); let mcts = MonteCarloTreeSearch::builder() .backpropagation(WinRate) .final_scorer(PayoutValue) .build::(); let random = Random::new(); let competition = Competition::new(&game, [&random, &mcts], true); state = competition.play(state)?; let scores = game .players() .iter() .map(|p| game.score(p, &state)) .collect::, _>>()?; assert!( scores[1] > scores[0], "random = {}; mcts = {}", scores[0], scores[1] ); Ok(()) } #[test] #[fickle] fn beats_random_tic_tac_toe() -> anyhow::Result<()> { // env_logger::init(); let game = TicTacToe; let mut state = TicTacToeState::default(); let mcts = MonteCarloTreeSearch::builder() .backpropagation(WinRate) .final_scorer(PayoutValue) .build::(); let random = Random::new(); let competition = Competition::new(&game, [&random, &mcts], true); state = competition.play(state)?; let scores = game .players() .iter() .map(|p| game.score(p, &state)) .collect::, _>>()?; assert!( scores[1] > scores[0], "random = {}; mcts = {}", scores[0], scores[1] ); Ok(()) }