werewolves/werewolves-proto/src/game_test/aura/scapegoat.rs

326 lines
11 KiB
Rust

// Copyright (C) 2025 Emilis Bliūdžius
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#[allow(unused)]
use pretty_assertions::{assert_eq, assert_ne, assert_str_eq};
use crate::{
aura::{Aura, AuraTitle},
game::{Game, GameSettings, SetupRole},
game_test::{
ActionPromptTitleExt, ActionResultExt, GameExt, SettingsExt, gen_players, init_log,
},
message::night::{ActionPrompt, ActionPromptTitle},
player::RoleChange,
role::{Alignment, Killer, Role, RoleTitle},
};
#[test]
fn redeemable_scapegoat() {
init_log();
let players = gen_players(1..21);
let mut player_ids = players.iter().map(|p| p.player_id);
let seer = player_ids.next().unwrap();
let wolf = player_ids.next().unwrap();
let scapegoat = player_ids.next().unwrap();
let mut settings = GameSettings::empty();
settings.add_and_assign(SetupRole::Werewolf, wolf);
settings.add_and_assign(SetupRole::Seer, seer);
let mut scapegoat_slot = settings.add_and_assign(SetupRole::Villager, scapegoat);
scapegoat_slot.auras.push(AuraTitle::RedeemableScapegoat);
settings.update_slot(scapegoat_slot);
settings.fill_remaining_slots_with_villagers(players.len());
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().title().seer();
game.mark(game.character_by_player_id(scapegoat).character_id());
assert!(game.r#continue().seer().wolves());
game.r#continue().sleep();
game.next_expect_day();
assert_eq!(
game.character_by_player_id(scapegoat).auras(),
&[Aura::RedeemableScapegoat]
);
game.mark_for_execution(game.character_by_player_id(seer).character_id());
game.execute().title().wolf_pack_kill();
game.mark(game.living_villager_excl(scapegoat).character_id());
game.r#continue().sleep();
game.next_expect_day();
game.execute().title().wolf_pack_kill();
game.mark(game.living_villager_excl(scapegoat).character_id());
game.r#continue().sleep();
assert_eq!(
game.next(),
ActionPrompt::RoleChange {
character_id: game.character_by_player_id(scapegoat).identity(),
new_role: RoleTitle::Seer
}
);
game.r#continue().r#continue();
game.next().title().seer();
game.mark(game.character_by_player_id(wolf).character_id());
assert!(game.r#continue().seer().wolves());
game.r#continue().sleep();
game.next_expect_day();
let scapegoat = game.character_by_player_id(scapegoat);
assert_eq!(
scapegoat.role_changes(),
&[RoleChange {
role: Role::Villager,
new_role: RoleTitle::Seer,
changed_on_night: 2,
}]
);
assert_eq!(scapegoat.auras(), &[Aura::Scapegoat]);
assert_eq!(scapegoat.role(), &Role::Seer);
}
#[test]
fn inevitable_scapegoat_targeting_black_knight() {
init_log();
let players = gen_players(1..21);
let mut player_ids = players.iter().map(|p| p.player_id);
let seer = player_ids.next().unwrap();
let wolf = player_ids.next().unwrap();
let black_knight = player_ids.next().unwrap();
let mut settings = GameSettings::empty();
settings.add_and_assign(SetupRole::Werewolf, wolf);
settings.add_and_assign(SetupRole::BlackKnight, black_knight);
let mut seer_slot = settings.add_and_assign(SetupRole::Seer, seer);
seer_slot.auras.push(AuraTitle::InevitableScapegoat);
settings.update_slot(seer_slot);
settings.fill_remaining_slots_with_villagers(players.len());
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.character_by_player_id(seer).auras(),
&[Aura::InevitableScapegoat]
);
game.next().title().seer();
game.mark(game.character_by_player_id(black_knight).character_id());
assert!(game.r#continue().seer().wolves());
game.r#continue().sleep();
game.next_expect_day();
assert_eq!(
game.character_by_player_id(black_knight).auras(),
&[Aura::Scapegoat]
);
assert_eq!(game.character_by_player_id(seer).auras(), &[]);
game.execute().title().wolf_pack_kill();
let next_target = game.village().characters().into_iter().last().unwrap();
game.mark(
game.living_villager_excl(next_target.player_id())
.character_id(),
);
game.r#continue().sleep();
game.next().title().seer();
game.mark(next_target.character_id());
assert!(game.r#continue().seer().village());
game.r#continue().sleep();
game.next_expect_day();
assert_eq!(game.character_by_player_id(seer).auras(), &[]);
assert_eq!(
game.character_by_player_id(next_target.player_id()).auras(),
&[]
);
}
#[test]
fn vindictive_scapegoat() {
init_log();
let players = gen_players(1..21);
let mut player_ids = players.iter().map(|p| p.player_id);
let scapegoat = player_ids.next().unwrap();
let wolf = player_ids.next().unwrap();
let mut settings = GameSettings::empty();
settings.add_and_assign(SetupRole::Werewolf, wolf);
let mut scapegoat_slot = settings.add_and_assign(SetupRole::Villager, scapegoat);
scapegoat_slot.auras.push(AuraTitle::VindictiveScapegoat);
settings.update_slot(scapegoat_slot);
settings.fill_remaining_slots_with_villagers(players.len());
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.mark_for_execution(game.character_by_player_id(scapegoat).character_id());
game.execute().title().wolf_pack_kill();
game.mark_villager();
game.r#continue().sleep();
game.next_expect_day();
assert_eq!(game.character_by_player_id(scapegoat).auras(), &[]);
assert!(
game.village()
.characters()
.into_iter()
.filter(|c| c.alive() && c.is_village())
.any(|c| c.auras() == [Aura::Scapegoat])
);
}
#[test]
fn spiteful_scapegoat_chosen_by_adjudicator() {
init_log();
let players = gen_players(1..21);
let mut player_ids = players.iter().map(|p| p.player_id);
let seer = player_ids.next().unwrap();
let wolf = player_ids.next().unwrap();
let adjudicator = player_ids.next().unwrap();
let mut settings = GameSettings::empty();
settings.add_and_assign(SetupRole::Werewolf, wolf);
settings.add_and_assign(SetupRole::Adjudicator, adjudicator);
let mut seer_slot = settings.add_and_assign(SetupRole::Seer, seer);
seer_slot.auras.push(AuraTitle::SpitefulScapegoat);
settings.update_slot(seer_slot);
settings.fill_remaining_slots_with_villagers(players.len());
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.character_by_player_id(seer).auras(),
&[Aura::SpitefulScapegoat]
);
game.next().title().seer();
game.mark(game.character_by_player_id(adjudicator).character_id());
assert_eq!(game.r#continue().seer(), Alignment::Village);
game.r#continue().sleep();
game.next().title().adjudicator();
game.mark(game.character_by_player_id(seer).character_id());
assert_eq!(game.r#continue().adjudicator(), Killer::NotKiller);
game.r#continue().sleep();
game.next_expect_day();
assert_eq!(game.character_by_player_id(seer).auras(), &[]);
assert_eq!(
game.character_by_player_id(adjudicator).auras(),
&[Aura::Scapegoat]
);
game.execute().title().wolf_pack_kill();
game.mark_villager();
game.r#continue().sleep();
game.next().title().seer();
game.mark(game.character_by_player_id(adjudicator).character_id());
assert_eq!(game.r#continue().seer(), Alignment::Wolves);
game.r#continue().sleep();
game.next().title().adjudicator();
game.mark(game.character_by_player_id(seer).character_id());
assert_eq!(game.r#continue().adjudicator(), Killer::NotKiller);
game.r#continue().sleep();
game.next_expect_day();
}
#[test]
fn inevitable_scapegoat_chosen_by_adjudicator() {
init_log();
let players = gen_players(1..21);
let mut player_ids = players.iter().map(|p| p.player_id);
let seer = player_ids.next().unwrap();
let wolf = player_ids.next().unwrap();
let adjudicator = player_ids.next().unwrap();
let mut settings = GameSettings::empty();
settings.add_and_assign(SetupRole::Werewolf, wolf);
settings.add_and_assign(SetupRole::Adjudicator, adjudicator);
let mut seer_slot = settings.add_and_assign(SetupRole::Seer, seer);
seer_slot.auras.push(AuraTitle::InevitableScapegoat);
settings.update_slot(seer_slot);
settings.fill_remaining_slots_with_villagers(players.len());
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.character_by_player_id(seer).auras(),
&[Aura::InevitableScapegoat]
);
game.next().title().seer();
game.mark(game.character_by_player_id(adjudicator).character_id());
assert_eq!(game.r#continue().seer(), Alignment::Wolves);
game.r#continue().sleep();
game.next().title().adjudicator();
game.mark(game.character_by_player_id(seer).character_id());
assert_eq!(game.r#continue().adjudicator(), Killer::NotKiller);
game.r#continue().sleep();
game.next_expect_day();
assert_eq!(game.character_by_player_id(seer).auras(), &[]);
assert_eq!(
game.character_by_player_id(adjudicator).auras(),
&[Aura::Scapegoat]
);
game.execute().title().wolf_pack_kill();
game.mark_villager();
game.r#continue().sleep();
game.next().title().seer();
game.mark(game.character_by_player_id(adjudicator).character_id());
assert_eq!(game.r#continue().seer(), Alignment::Wolves);
game.r#continue().sleep();
game.next().title().adjudicator();
game.mark(game.character_by_player_id(seer).character_id());
assert_eq!(game.r#continue().adjudicator(), Killer::NotKiller);
game.r#continue().sleep();
game.next_expect_day();
}