guardian: self guard is no longer an option

This commit is contained in:
emilis 2025-11-30 14:44:06 +00:00
parent 3388894504
commit 0bd54a517d
No known key found for this signature in database
2 changed files with 63 additions and 2 deletions

View File

@ -504,7 +504,11 @@ impl Character {
} => prompts.push(ActionPrompt::Guardian {
character_id: self.identity(),
previous: Some(PreviousGuardianAction::Protect(prev_target.clone())),
living_players: village.living_players(),
living_players: if prev_target.character_id == self.identity.character_id {
village.living_players_excluding(prev_target.character_id)
} else {
village.living_players()
},
marked: None,
}),
Role::Guardian {

View File

@ -26,7 +26,7 @@ use crate::{
},
message::{
host::{HostGameMessage, HostNightMessage},
night::{ActionPromptTitle, ActionResponse},
night::{ActionPrompt, ActionPromptTitle, ActionResponse},
},
role::{PreviousGuardianAction, Role, RoleTitle},
};
@ -271,3 +271,60 @@ fn protects_from_militia() {
}
);
}
#[test]
fn cant_self_guard() {
init_log();
let players = gen_players(1..21);
let mut player_ids = players.iter().map(|p| p.player_id);
let guardian = player_ids.next().unwrap();
let wolf = player_ids.next().unwrap();
let mut settings = GameSettings::empty();
settings.add_and_assign(SetupRole::Guardian, guardian);
settings.add_and_assign(SetupRole::Werewolf, wolf);
settings.fill_remaining_slots_with_villagers(20);
let mut game = Game::new(&players, settings).unwrap();
game.r#continue().r#continue();
game.next().title().wolves_intro();
game.r#continue().sleep();
game.next_expect_day();
game.execute().title().guardian();
game.mark(game.character_by_player_id(guardian).character_id());
game.r#continue().sleep();
game.next().title().wolf_pack_kill();
game.mark(game.character_by_player_id(guardian).character_id());
game.r#continue().sleep();
game.next_expect_day();
assert_eq!(
game.character_by_player_id(guardian).died_to().cloned(),
None
);
assert_eq!(
game.character_by_player_id(guardian)
.role()
.guardian_ref()
.unwrap()
.last_protected
.clone(),
Some(PreviousGuardianAction::Protect(
game.character_by_player_id(guardian).identity()
))
);
match game.execute() {
ActionPrompt::Guardian {
character_id,
previous: Some(PreviousGuardianAction::Protect(prev_protect)),
living_players,
..
} => {
assert_eq!(character_id, prev_protect);
assert!(!living_players.contains(&character_id));
}
prompt => panic!("expected guardian prompt, got {prompt:?}"),
}
}