237 lines
7.2 KiB
Rust
237 lines
7.2 KiB
Rust
#[allow(unused)]
|
|
use pretty_assertions::{assert_eq, assert_ne, assert_str_eq};
|
|
|
|
use crate::{
|
|
character::CharacterId,
|
|
game::{Game, GameSettings, SetupRole},
|
|
game_test::{
|
|
ActionPromptTitleExt, ActionResultExt, GameExt, ServerToHostMessageExt, SettingsExt,
|
|
gen_players, init_log,
|
|
},
|
|
message::{
|
|
host::{HostDayMessage, HostGameMessage, HostNightMessage, ServerToHostMessage},
|
|
night::{ActionPrompt, ActionPromptTitle, ActionResponse, ActionResult},
|
|
},
|
|
role::RoleTitle,
|
|
};
|
|
|
|
#[test]
|
|
fn protect_stops_shapeshift() {
|
|
init_log();
|
|
let players = gen_players(1..10);
|
|
let mut settings = GameSettings::default();
|
|
settings.new_slot(RoleTitle::Shapeshifter);
|
|
settings.new_slot(RoleTitle::Protector);
|
|
for _ in 0..7 {
|
|
settings.new_slot(RoleTitle::Villager);
|
|
}
|
|
if let Some(slot) = settings
|
|
.slots()
|
|
.iter()
|
|
.find(|s| matches!(s.role, SetupRole::Werewolf))
|
|
{
|
|
settings.remove_slot(slot.slot_id);
|
|
}
|
|
let mut game = Game::new(&players, settings).unwrap();
|
|
assert_eq!(
|
|
game.process(HostGameMessage::Night(HostNightMessage::ActionResponse(
|
|
ActionResponse::Continue,
|
|
)))
|
|
.unwrap(),
|
|
ServerToHostMessage::ActionResult(None, ActionResult::Continue)
|
|
);
|
|
assert!(matches!(
|
|
game.process(HostGameMessage::Night(HostNightMessage::Next))
|
|
.unwrap(),
|
|
ServerToHostMessage::ActionPrompt(ActionPrompt::WolvesIntro { wolves: _ })
|
|
));
|
|
assert_eq!(
|
|
game.process(HostGameMessage::Night(HostNightMessage::ActionResponse(
|
|
ActionResponse::Continue
|
|
)))
|
|
.unwrap(),
|
|
ServerToHostMessage::ActionResult(None, ActionResult::GoBackToSleep),
|
|
);
|
|
assert!(matches!(
|
|
game.process(HostGameMessage::Night(HostNightMessage::Next))
|
|
.unwrap(),
|
|
ServerToHostMessage::Daytime {
|
|
characters: _,
|
|
marked: _,
|
|
day: _,
|
|
}
|
|
));
|
|
|
|
let execution_target = game
|
|
.village()
|
|
.characters()
|
|
.into_iter()
|
|
.find(|v| v.is_village() && !matches!(v.role().title(), RoleTitle::Protector))
|
|
.unwrap()
|
|
.character_id();
|
|
match game
|
|
.process(HostGameMessage::Day(HostDayMessage::MarkForExecution(
|
|
execution_target,
|
|
)))
|
|
.unwrap()
|
|
{
|
|
ServerToHostMessage::Daytime {
|
|
characters: _,
|
|
marked,
|
|
day: _,
|
|
} => assert_eq!(marked.to_vec(), vec![execution_target]),
|
|
resp => panic!("unexpected server message: {resp:#?}"),
|
|
}
|
|
|
|
assert_eq!(
|
|
game.process(HostGameMessage::Day(HostDayMessage::Execute))
|
|
.unwrap()
|
|
.prompt()
|
|
.title(),
|
|
ActionPromptTitle::CoverOfDarkness
|
|
);
|
|
game.r#continue().r#continue();
|
|
|
|
let (prot_and_wolf_target, prot_char_id) = match game
|
|
.process(HostGameMessage::Night(HostNightMessage::Next))
|
|
.unwrap()
|
|
{
|
|
ServerToHostMessage::ActionPrompt(ActionPrompt::Protector {
|
|
character_id: prot_char_id,
|
|
targets,
|
|
marked: None,
|
|
}) => (
|
|
targets
|
|
.into_iter()
|
|
.map(|c| game.village().character_by_id(c.character_id).unwrap())
|
|
.find(|c| c.is_village())
|
|
.unwrap()
|
|
.character_id(),
|
|
prot_char_id,
|
|
),
|
|
_ => panic!("first n2 prompt isn't protector"),
|
|
};
|
|
let target = game
|
|
.village()
|
|
.character_by_id(prot_and_wolf_target)
|
|
.unwrap()
|
|
.clone();
|
|
log::info!("target: {target:#?}");
|
|
|
|
match game
|
|
.process(HostGameMessage::Night(HostNightMessage::ActionResponse(
|
|
ActionResponse::MarkTarget(prot_and_wolf_target),
|
|
)))
|
|
.unwrap()
|
|
{
|
|
ServerToHostMessage::ActionPrompt(ActionPrompt::Protector {
|
|
marked: Some(mark), ..
|
|
}) => assert_eq!(mark, prot_and_wolf_target, "marked target"),
|
|
resp => panic!("unexpected response: {resp:?}"),
|
|
}
|
|
|
|
game.r#continue().sleep();
|
|
|
|
assert_eq!(game.next().title(), ActionPromptTitle::WolfPackKill);
|
|
|
|
game.mark_and_check(prot_and_wolf_target);
|
|
game.r#continue().r#continue();
|
|
|
|
assert_eq!(game.next().title(), ActionPromptTitle::Shapeshifter,);
|
|
|
|
game.response(ActionResponse::Shapeshift);
|
|
|
|
game.next_expect_day();
|
|
|
|
let target = game
|
|
.village()
|
|
.character_by_id(target.character_id())
|
|
.unwrap();
|
|
assert!(target.is_village());
|
|
assert!(target.alive());
|
|
|
|
let prot = game
|
|
.village()
|
|
.character_by_id(prot_char_id.character_id)
|
|
.unwrap();
|
|
assert!(prot.is_village());
|
|
assert!(prot.alive());
|
|
assert_eq!(prot.role().title(), RoleTitle::Protector);
|
|
}
|
|
|
|
#[test]
|
|
fn only_1_shapeshift_prompt_if_first_shifts() {
|
|
let players = gen_players(1..10);
|
|
let mut settings = GameSettings::default();
|
|
settings.new_slot(RoleTitle::Shapeshifter);
|
|
settings.new_slot(RoleTitle::Shapeshifter);
|
|
for _ in 0..7 {
|
|
settings.new_slot(RoleTitle::Villager);
|
|
}
|
|
if let Some(slot) = settings
|
|
.slots()
|
|
.iter()
|
|
.find(|s| matches!(s.role, SetupRole::Werewolf))
|
|
{
|
|
settings.remove_slot(slot.slot_id);
|
|
}
|
|
let mut game = Game::new(&players, settings).unwrap();
|
|
game.r#continue().r#continue();
|
|
assert_eq!(game.next().title(), ActionPromptTitle::WolvesIntro);
|
|
game.r#continue().sleep();
|
|
game.next_expect_day();
|
|
let target = game
|
|
.village()
|
|
.characters()
|
|
.into_iter()
|
|
.find_map(|c| c.is_village().then_some(c.character_id()))
|
|
.unwrap();
|
|
let (_, marked, _) = game.mark_for_execution(target);
|
|
let (marked, target_list): (&[CharacterId], &[CharacterId]) = (&marked, &[target]);
|
|
assert_eq!(target_list, marked);
|
|
|
|
assert_eq!(game.execute().title(), ActionPromptTitle::WolfPackKill);
|
|
let target = game
|
|
.village()
|
|
.characters()
|
|
.into_iter()
|
|
.find_map(|c| (c.is_village() && c.alive()).then_some(c.character_id()))
|
|
.unwrap();
|
|
|
|
game.mark_and_check(target);
|
|
game.r#continue().r#continue();
|
|
assert_eq!(game.next().title(), ActionPromptTitle::Shapeshifter);
|
|
game.response(ActionResponse::Shapeshift).r#continue();
|
|
assert_eq!(game.next().title(), ActionPromptTitle::RoleChange);
|
|
game.r#continue().sleep();
|
|
|
|
game.next_expect_day();
|
|
}
|
|
|
|
#[test]
|
|
fn i_would_simply_refuse() {
|
|
let players = gen_players(1..21);
|
|
let shapeshifter_player_id = players[0].player_id;
|
|
let wolf_player_id = players[1].player_id;
|
|
let mut settings = GameSettings::empty();
|
|
settings.add_and_assign(SetupRole::Shapeshifter, shapeshifter_player_id);
|
|
settings.add_and_assign(SetupRole::Werewolf, wolf_player_id);
|
|
settings.fill_remaining_slots_with_villagers(20);
|
|
let mut game = Game::new(&players, settings).unwrap();
|
|
game.r#continue().r#continue();
|
|
assert_eq!(game.next().title(), ActionPromptTitle::WolvesIntro);
|
|
game.r#continue().sleep();
|
|
|
|
game.next_expect_day();
|
|
|
|
game.execute().title().wolf_pack_kill();
|
|
let ss_target = game.living_villager();
|
|
game.mark(ss_target.character_id());
|
|
game.r#continue().r#continue();
|
|
|
|
game.next().title().shapeshifter();
|
|
game.r#continue().sleep();
|
|
|
|
game.next_expect_day();
|
|
}
|