Spaces:
Running on Zero
Running on Zero
File size: 3,851 Bytes
c670567 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | from mafia.engine.reducers import (
cast_vote,
create_game,
resolve_night,
start_discussion,
start_vote,
submit_night_action,
)
from mafia.engine.state import Phase, Role, Team
from mafia.ui.session import GameSession, advance_ai
def test_create_game_has_classic_role_counts():
state = create_game(seed=42)
counts = {}
for player in state.players.values():
counts[player.role] = counts.get(player.role, 0) + 1
assert counts == {
Role.MAFIA: 2,
Role.DETECTIVE: 1,
Role.DOCTOR: 1,
Role.VILLAGER: 3,
}
assert len(state.players) == 7
assert state.phase == Phase.NIGHT
def test_doctor_save_prevents_night_kill():
state = create_game(seed=10)
mafia = next(pid for pid, p in state.players.items() if p.role == Role.MAFIA)
doctor = next(pid for pid, p in state.players.items() if p.role == Role.DOCTOR)
target = next(pid for pid, p in state.players.items() if p.team == Team.TOWN and pid != doctor)
assert submit_night_action(state, mafia, "kill", target)
assert submit_night_action(state, doctor, "protect", target)
resolve_night(state)
assert state.players[target].alive
assert state.phase == Phase.DAWN
def test_doctor_cannot_protect_same_target_twice_in_a_row():
state = create_game(seed=10)
doctor = next(pid for pid, p in state.players.items() if p.role == Role.DOCTOR)
target = next(pid for pid, p in state.players.items() if p.team == Team.TOWN and pid != doctor)
assert submit_night_action(state, doctor, "protect", target)
state.night_actions.doctor_protects.clear()
assert not submit_night_action(state, doctor, "protect", target)
def test_doctor_can_protect_self_but_not_twice_in_a_row():
state = create_game(seed=10)
doctor = next(pid for pid, p in state.players.items() if p.role == Role.DOCTOR)
assert submit_night_action(state, doctor, "protect", doctor)
state.night_actions.doctor_protects.clear()
assert not submit_night_action(state, doctor, "protect", doctor)
def test_detective_gets_private_alignment_result():
state = create_game(seed=14)
detective = next(pid for pid, p in state.players.items() if p.role == Role.DETECTIVE)
mafia = next(pid for pid, p in state.players.items() if p.role == Role.MAFIA)
assert submit_night_action(state, detective, "check", mafia)
resolve_night(state)
assert state.players[detective].private_memory["investigations"][mafia] is True
def test_vote_eliminates_plurality_target():
state = create_game(seed=3)
resolve_night(state)
start_discussion(state)
state.phase = Phase.VOTE
alive = state.alive_players()
target = alive[-1]
for voter in alive[:-1]:
cast_vote(state, voter, target)
assert not state.players[target].alive
assert target in state.eliminated_order
def test_mafia_night_disagreement_still_resolves_team_kill():
state = create_game(seed=42)
mafia = [pid for pid, player in state.players.items() if player.role == Role.MAFIA]
targets = [pid for pid, player in state.players.items() if player.team == Team.TOWN]
assert len(mafia) == 2
assert submit_night_action(state, mafia[0], "kill", targets[0])
assert submit_night_action(state, mafia[1], "kill", targets[1])
resolve_night(state)
assert len([pid for pid in targets if not state.players[pid].alive]) == 1
assert any(event.type == "mafia_consensus" for event in state.events)
def test_vote_phase_waits_for_living_human_vote_before_ai_votes():
state = create_game(seed=33)
resolve_night(state)
start_discussion(state)
start_vote(state)
session = GameSession(state=state)
advance_ai(session, max_steps=3)
assert state.phase == Phase.VOTE
assert state.human_player_id not in state.locked_votes
assert not state.votes
|