|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
| 3 | +import functools |
3 | 4 | import logging
|
4 | 5 | import math
|
5 | 6 | import random
|
@@ -255,7 +256,7 @@ def build_deck(self, var: GameState, location: Location, visitors: set[User]) ->
|
255 | 256 | + ["empty-handed", "empty-handed"] * num_other)
|
256 | 257 | num_draws = 1
|
257 | 258 | elif location is Streets:
|
258 |
| - deck = (["evidence"] * 9 |
| 259 | + deck = (["evidence"] * 7 |
259 | 260 | + ["hunted", "evidence", "empty-handed"] * num_wolves
|
260 | 261 | + ["evidence", "evidence", "empty-handed"] * num_other)
|
261 | 262 | num_draws = 3
|
@@ -376,28 +377,27 @@ def on_night_kills(self, evt: Event, var: GameState):
|
376 | 377 | # give non-wolves a higher chance of gaining clues after exhausting all wolf evidence
|
377 | 378 | num_evidence += 1
|
378 | 379 | elif location is Streets and num_evidence == 3:
|
379 |
| - # refute fake evidence that the visitor may have collected, |
380 |
| - # in order of cursed -> villager (or vampire, if a cursed vig turned) and then vigilante -> vampire |
| 380 | + # refute fake evidence that the visitor may have collected |
381 | 381 | # if there's no fake evidence, fall back to giving a clue token
|
382 |
| - collected_any = False |
383 |
| - for wolf in self.collected_evidence[visitor]["wolf"]: |
384 |
| - collected_any = True |
385 |
| - if wolf in all_cursed and wolf not in self.collected_evidence[visitor]["villager"]: |
386 |
| - evidence_target = wolf |
387 |
| - break |
388 |
| - else: |
389 |
| - for vig in self.collected_evidence[visitor]["vigilante"]: |
390 |
| - collected_any = True |
391 |
| - if vig in all_vamps and vig not in self.collected_evidence[visitor]["vampire"]: |
392 |
| - evidence_target = vig |
| 382 | + collected = functools.reduce(lambda x, y: x | y, self.collected_evidence[visitor].values()) |
| 383 | + role_order = ("wolf", "villager", "vigilante") |
| 384 | + for role in role_order: |
| 385 | + for target in self.collected_evidence[visitor][role]: |
| 386 | + real_role = get_main_role(var, target) |
| 387 | + if real_role != role and target not in self.collected_evidence[visitor][real_role]: |
| 388 | + evidence_target = target |
393 | 389 | break
|
| 390 | + if evidence_target is not None: |
| 391 | + break |
| 392 | + |
394 | 393 | # no evidence to refute? give a special message indicating that
|
395 |
| - if collected_any and evidence_target is None and self.clue_pool > 0: |
| 394 | + if collected and evidence_target is None: |
396 | 395 | tokens = min(self.clue_pool, config.Main.get(f"gameplay.modes.pactbreaker.clue.{loc}"))
|
397 | 396 | self.clue_pool -= tokens
|
398 | 397 | self.clue_tokens[visitor] += tokens
|
399 | 398 | visitor.send(messages[f"pactbreaker_{loc}_special"].format(tokens))
|
400 |
| - break |
| 399 | + # process the next player since we've fully handled this one here |
| 400 | + continue |
401 | 401 | elif location is Streets:
|
402 | 402 | # streets is guaranteed to give a clue token each night (as long as clue tokens remain)
|
403 | 403 | num_evidence = 2
|
|
0 commit comments