use core::num::NonZero; use crate::{ diedto::DiedTo, game::{Game, GameSettings, OrRandom, SetupRole, night::NightChange}, game_test::{ActionResultExt, GameExt, gen_players}, message::night::{ActionPrompt, ActionPromptTitle}, role::{Alignment, RoleTitle}, }; #[allow(unused)] use pretty_assertions::{assert_eq, assert_ne, assert_str_eq}; #[test] fn redeemed_scapegoat_role_changes() { let players = gen_players(1..10); let scapegoat_player_id = players[0].player_id.clone(); let seer_player_id = players[1].player_id.clone(); let wolf_player_id = players[2].player_id.clone(); let wolf_target_2_player_id = players[3].player_id.clone(); let mut settings = GameSettings::default(); { let scapegoat_slot = settings.new_slot(RoleTitle::Scapegoat); let mut scapegoat_slot = settings .slots() .iter() .find(|s| s.slot_id == scapegoat_slot) .unwrap() .clone(); scapegoat_slot.role = SetupRole::Scapegoat { redeemed: OrRandom::Determined(true), }; scapegoat_slot.assign_to = Some(scapegoat_player_id.clone()); settings.update_slot(scapegoat_slot); } { let mut slot = settings .slots() .iter() .find(|s| matches!(s.role, SetupRole::Werewolf)) .unwrap() .clone(); slot.assign_to = Some(wolf_player_id.clone()); settings.update_slot(slot); } { let slot = settings.new_slot(RoleTitle::Seer); let mut slot = settings .slots() .iter() .find(|s| s.slot_id == slot) .unwrap() .clone(); slot.assign_to = Some(seer_player_id.clone()); settings.update_slot(slot); } for _ in 0..6 { settings.new_slot(RoleTitle::Villager); } let mut game = Game::new(&players, settings).unwrap(); game.r#continue().r#continue(); assert_eq!(game.next().title(), ActionPromptTitle::WolvesIntro); game.r#continue().sleep(); assert_eq!(game.next().title(), ActionPromptTitle::Seer); let wolf_char_id = game .village() .characters() .into_iter() .find(|c| c.player_id() == wolf_player_id) .unwrap() .character_id() .clone(); game.mark_and_check(wolf_char_id); assert_eq!(game.r#continue().seer(), Alignment::Wolves); game.next_expect_day(); assert_eq!(game.execute().title(), ActionPromptTitle::CoverOfDarkness); game.r#continue().r#continue(); assert_eq!(game.next().title(), ActionPromptTitle::WolfPackKill); let seer = game .village() .characters() .into_iter() .find(|c| c.player_id() == seer_player_id) .unwrap() .character_id() .clone(); game.mark_and_check(seer); game.r#continue().sleep(); assert_eq!(game.next().title(), ActionPromptTitle::Seer); game.mark_and_check(wolf_char_id); assert_eq!(game.r#continue().seer(), Alignment::Wolves); game.next_expect_day(); assert_eq!( *game .village() .character_by_id(seer) .unwrap() .died_to() .unwrap(), DiedTo::Wolfpack { killing_wolf: wolf_char_id.clone(), night: NonZero::new(1).unwrap() } ); assert_eq!(game.execute().title(), ActionPromptTitle::CoverOfDarkness); game.r#continue().r#continue(); assert_eq!(game.next().title(), ActionPromptTitle::WolfPackKill); let wolf_target_2 = game .village() .characters() .iter() .find(|c| c.player_id() == wolf_target_2_player_id) .unwrap() .character_id() .clone(); game.mark_and_check(wolf_target_2); game.r#continue().sleep(); let scapegoat = game .village() .characters() .into_iter() .find(|c| c.player_id() == scapegoat_player_id) .unwrap() .clone(); assert_eq!( game.next(), ActionPrompt::RoleChange { character_id: scapegoat.identity(), new_role: RoleTitle::Seer } ); game.r#continue().sleep(); match game.game_state() { crate::game::GameState::Night { night } => night .changes() .iter() .find(|c| match c { NightChange::RoleChange(char, role) => { char == &scapegoat.character_id() && role == &RoleTitle::Seer } _ => false, }) .expect("no role change"), _ => unreachable!(), }; game.next_expect_day(); let day_scapegoat = game .village() .character_by_id(scapegoat.character_id()) .unwrap(); assert_eq!(day_scapegoat.role().title(), RoleTitle::Seer); }