import random from typing import List, Dict, Optional, Tuple from dataclasses import dataclass @dataclass class Card: id: int color: int shape: int fill: int count: int class SetGame: def __init__(self): self.deck = self._generate_deck() self.field = [] self.score = 0 self.game_over = False self._initialize_field() def _generate_deck(self) -> List[Card]: deck = [] card_id = 0 for color in [1, 2, 3]: for shape in [1, 2, 3]: for fill in [1, 2, 3]: for count in [1, 2, 3]: deck.append(Card( id=card_id, color=color, shape=shape, fill=fill, count=count )) card_id += 1 random.shuffle(deck) return deck def _initialize_field(self): for _ in range(12): if self.deck: self.field.append(self.deck.pop()) def get_field(self) -> List[Dict]: return [ { "id": card.id, "color": card.color, "shape": card.shape, "fill": card.fill, "count": card.count } for card in self.field ] def check_set(self, card_ids: List[int]) -> bool: if len(card_ids) != 3: return False cards = [card for card in self.field if card.id in card_ids] if len(cards) != 3: return False for attribute in ['color', 'shape', 'fill', 'count']: values = [getattr(card, attribute) for card in cards] unique_values = set(values) if len(unique_values) not in [1, 3]: return False return True def remove_cards(self, card_ids: List[int]): self.field = [card for card in self.field if card.id not in card_ids] while len(self.field) < 12 and self.deck: self.field.append(self.deck.pop()) if not self.deck and len(self.field) < 3: self.game_over = True def add_cards(self, count: int = 3): for _ in range(min(count, len(self.deck))): if self.deck: self.field.append(self.deck.pop()) def is_game_over(self) -> bool: return self.game_over def find_sets_on_field(self) -> List[List[int]]: sets = [] n = len(self.field) for i in range(n): for j in range(i + 1, n): for k in range(j + 1, n): if self.check_set([self.field[i].id, self.field[j].id, self.field[k].id]): sets.append([self.field[i].id, self.field[j].id, self.field[k].id]) return sets def get_deck_size(self) -> int: return len(self.deck)