implement color and rank touching methods for variants

This commit is contained in:
Maximilian Keßler 2023-05-13 12:33:58 +02:00
parent 7d8e03fca0
commit a5310f8885
Signed by: max
GPG key ID: BCC5A619923C0BA5

View file

@ -50,6 +50,24 @@ class Suit:
self.colors = colors self.colors = colors
def rank_touches(self, card_rank: int, clue_rank: int) -> bool:
match self.rank_clues:
case ClueBehaviour.none:
return False
case ClueBehaviour.default:
return card_rank == clue_rank
case ClueBehaviour.all:
return True
def color_touches(self, clue_color: int) -> bool:
match self.color_clues:
case ClueBehaviour.none:
return False
case ClueBehaviour.default:
return clue_color in self.colors
case ClueBehaviour.all:
return True
def __str__(self): def __str__(self):
return self.name return self.name
@ -83,21 +101,21 @@ class Variant:
self.name = name self.name = name
self.clue_starved = clue_starved self.clue_starved = clue_starved
self.throw_it_in_a_hole = throw_it_in_a_hole self.throw_it_in_a_hole = throw_it_in_a_hole
self.alternating_clues = alternating_clues self.alternating_clues = alternating_clues # TODO: has to be somehow supported by game itself
self.synesthesia = synesthesia self.synesthesia = synesthesia #
self.chimneys = chimneys self.chimneys = chimneys #
self.funnels = funnels self.funnels = funnels #
self.no_color_clues = no_color_clues self.no_color_clues = no_color_clues #
self.no_rank_clues = no_rank_clues self.no_rank_clues = no_rank_clues #
self.empty_color_clues = empty_color_clues self.empty_color_clues = empty_color_clues #
self.empty_rank_clues = empty_rank_clues self.empty_rank_clues = empty_rank_clues #
self.odds_and_evens = odds_and_evens self.odds_and_evens = odds_and_evens #
self.up_or_down = up_or_down self.up_or_down = up_or_down # TODO: currently not supported
self.critical_fours = critical_fours self.critical_fours = critical_fours
self.num_suits = len(suits) self.num_suits = len(suits)
self.special_rank = special_rank self.special_rank = special_rank #
self.special_rank_ranks = special_rank_ranks self.special_rank_ranks = special_rank_ranks #
self.special_rank_colors = special_rank_colors self.special_rank_colors = special_rank_colors #
self.special_deceptive = special_deceptive self.special_deceptive = special_deceptive
self.suits = suits self.suits = suits
@ -123,8 +141,76 @@ class Variant:
self.num_colors = len(self.colors) self.num_colors = len(self.colors)
def _preprocess_rank(self, value: int) -> List[int]:
if self.empty_rank_clues:
return []
if self.chimneys:
return [rank for rank in self.ranks if rank >= value]
if self.funnels:
return [rank for rank in self.ranks if rank <= value]
if self.odds_and_evens:
return [rank for rank in self.ranks if (rank - value) % 2 == 0]
return [value]
def _synesthesia_ranks(self, color_value: int) -> List[int]:
return [rank for rank in self.ranks if (rank - color_value) % len(self.colors) == 0]
def rank_touches(self, card: DeckCard, value: int): def rank_touches(self, card: DeckCard, value: int):
pass assert 0 <= card.suitIndex < self.num_suits,\
f"Unexpected card {card}, suitIndex {card.suitIndex} out of bounds for {self.num_suits} suits."
assert not self.no_rank_clues, "Cluing rank not allowed in this variant."
assert value in self.ranks, f"Cluing value {value} not allowed in this variant."
if self.special_rank is not None and self.special_rank_ranks != ClueBehaviour.default:
suit = self.suits[card.suitIndex]
match suit.rank_clues:
case ClueBehaviour.none:
return False
case ClueBehaviour.default:
match self.special_rank_ranks:
case ClueBehaviour.none:
return False
case ClueBehaviour.default:
assert False, "Programming error"
case ClueBehaviour.all:
return True
case ClueBehaviour.all:
return True
ranks = self._preprocess_rank(value)
return any(self.suits[card.suitIndex].rank_touches(card.rank, rank) for rank in ranks)
def color_touches(self, card: DeckCard, value: int):
assert 0 <= card.suitIndex < self.num_suits, \
f"Unexpected card {card}, suitIndex {card.suitIndex} out of bounds for {self.num_suits} suits."
assert not self.no_color_clues, "Cluing color not allowed in this variant."
assert 0 <= value < len(self.colors), f"Color clue with index {value} does not exist in this variant."
if self.special_rank is not None and self.special_rank_colors != ClueBehaviour.default:
suit = self.suits[card.suitIndex]
match suit.color_clues:
case ClueBehaviour.none:
return False
case ClueBehaviour.default:
match self.special_rank_colors:
case ClueBehaviour.none:
return False
case ClueBehaviour.default:
assert False, "Programming error"
case ClueBehaviour.all:
return True
case ClueBehaviour.all:
return True
if self.empty_color_clues:
return False
if self.synesthesia and any(self.rank_touches(card, rank_val) for rank_val in self._synesthesia_ranks(value)):
return True
suit = self.suits[card.suitIndex]
if suit.prism and value == ((card.rank - 1) % len(self.colors)):
return True
return suit.color_touches(self.colors[value])
@staticmethod @staticmethod
def from_db(var_id): def from_db(var_id):