use fickle::fickle; use ncpig::prelude::*; use ncpig_testing::number_claim::*; use rand::rngs::ThreadRng; use rand::seq::index; #[test] fn two_player_number_claim_no_pruning() -> anyhow::Result<()> { // env_logger::init(); let game: NumberClaim<2, 3> = NumberClaim::new([4, 7, 10])?; let mut state = NumberClaimState::default(); let search = MaxN::default(); let mut expected_moves = vec![4, 10, 7]; while !game.is_complete(&state)? { let action = search.choose_action(&game, &state)?.unwrap(); state = game.do_action(&action, state)?; if let Some(expected) = expected_moves.pop() { assert_eq!(action, expected); } } assert_eq!(game.score(&0, &state)?, 19); assert_eq!(game.score(&1, &state)?, 11); Ok(()) } #[test] fn three_player_number_claim_no_pruning() -> anyhow::Result<()> { // env_logger::init(); let game: NumberClaim<3, 6> = NumberClaim::new([4, 7, 10, 12, 13, 18])?; let mut state = NumberClaimState::default(); let search = MaxN::default(); let mut expected_moves = vec![4, 10, 12, 7, 18, 13]; while !game.is_complete(&state)? { let action = search.choose_action(&game, &state)?.unwrap(); state = game.do_action(&action, state)?; if let Some(expected) = expected_moves.pop() { assert_eq!(action, expected); } } assert_eq!(game.score(&0, &state)?, 39); assert_eq!(game.score(&1, &state)?, 30); assert_eq!(game.score(&2, &state)?, 19); Ok(()) } #[test] fn two_player_number_claim_with_pruning() -> anyhow::Result<()> { // env_logger::init(); let game: NumberClaim<2, 3> = NumberClaim::new([4, 7, 10])?; let mut state = NumberClaimState::default(); let search = MaxN::builder().pruning(30).build(); let mut expected_moves = vec![4, 10, 7]; while !game.is_complete(&state)? { let action = search.choose_action(&game, &state)?.unwrap(); state = game.do_action(&action, state)?; if let Some(expected) = expected_moves.pop() { assert_eq!(action, expected); } } assert_eq!(game.score(&0, &state)?, 19); assert_eq!(game.score(&1, &state)?, 11); Ok(()) } #[test] fn three_player_number_claim_with_pruning() -> anyhow::Result<()> { // env_logger::init(); let game: NumberClaim<3, 6> = NumberClaim::new([4, 7, 10, 12, 13, 18])?; let mut state = NumberClaimState::default(); let search = MaxN::builder().pruning(91).build(); let mut expected_moves = vec![4, 10, 12, 7, 18, 13]; while !game.is_complete(&state)? { let action = search.choose_action(&game, &state)?.unwrap(); state = game.do_action(&action, state)?; if let Some(expected) = expected_moves.pop() { assert_eq!(action, expected); } } assert_eq!(game.score(&0, &state)?, 39); assert_eq!(game.score(&1, &state)?, 30); assert_eq!(game.score(&2, &state)?, 19); Ok(()) } #[test] #[fickle] fn maxn_beats_random_number_claim_no_pruning() -> 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 maxn = MaxN::default(); let random = Random::new(); let competition = Competition::new(&game, [&random, &maxn], true); state = competition.play(state)?; let scores = game .players() .iter() .map(|p| game.score(p, &state)) .collect::, _>>()?; assert!(scores[1] > scores[0]); Ok(()) } #[test] #[fickle] fn maxn_beats_random_number_claim_with_pruning() -> 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 maxn = MaxN::builder().pruning(game.max_points()).build(); let random = Random::new(); let competition = Competition::new(&game, [&random, &maxn], true); state = competition.play(state)?; let scores = game .players() .iter() .map(|p| game.score(p, &state)) .collect::, _>>()?; assert!(scores[1] > scores[0]); Ok(()) } #[test] #[fickle] fn heuristic_maxn_beats_random_number_claim_no_pruning() -> anyhow::Result<()> { // env_logger::init(); let mut rng = ThreadRng::default(); let pool = index::sample(&mut rng, 1000, 20) .into_iter() .map(|n| n as _); let game: NumberClaim<2, 20> = NumberClaim::new(pool)?; let mut state = NumberClaimState::default(); let maxn = MaxN::builder().max_depth(3).build(); let random = Random::new(); let competition = Competition::new(&game, [&random, &maxn], true); state = competition.play(state)?; let scores = game .players() .iter() .map(|p| game.score(p, &state)) .collect::, _>>()?; assert!(scores[1] > scores[0]); Ok(()) } #[test] #[fickle] fn heuristic_maxn_beats_random_number_claim_with_pruning() -> anyhow::Result<()> { // env_logger::init(); let mut rng = ThreadRng::default(); let pool = index::sample(&mut rng, 1000, 20) .into_iter() .map(|n| n as _); let game: NumberClaim<2, 20> = NumberClaim::new(pool)?; let mut state = NumberClaimState::default(); let maxn = MaxN::builder() .pruning(game.max_points()) .max_depth(3) .build(); let random = Random::new(); let competition = Competition::new(&game, [&random, &maxn], true); state = competition.play(state)?; let scores = game .players() .iter() .map(|p| game.score(p, &state)) .collect::, _>>()?; assert!(scores[1] > scores[0]); Ok(()) }