Пример #1
0
 def __init__(self, context: Context):
     self.context = context
     self.clues = Clues(context)
     self.knowledge_table = KnowledgeTable(self.context.players,
                                           self.context.cards)
     self.brute_forcer = BruteForcer(self.clues, self.knowledge_table)
     self.deriver = Deriver(self.clues, self.knowledge_table)
Пример #2
0
class Watson:
    def __init__(self, context: Context):
        self.context = context
        self.clues = Clues(context)
        self.knowledge_table = KnowledgeTable(self.context.players,
                                              self.context.cards)
        self.brute_forcer = BruteForcer(self.clues, self.knowledge_table)
        self.deriver = Deriver(self.clues, self.knowledge_table)

    def add_knowledge(self, player: Player, card: Card, knowledge: Knowledge):
        self.clues.add_card(card, player)
        self.deriver.derive_from_new_knowledge(player, card, knowledge)
        self.brute_force_and_derive_from_findings()

    def add_rumour(self, rumour: Rumour) -> None:
        self.clues.add_rumour(rumour)
        self.deriver.derive_from_new_rumour(rumour)
        self.brute_force_and_derive_from_findings()

    def brute_force_and_derive_from_findings(self):
        for player in self.context.players:
            for card in self.context.cards:
                if self.knowledge_table.get(player, card) == Knowledge.MAYBE:
                    knowledge = self.brute_forcer.brute_force_on_card(
                        player, card)
                    if knowledge != Knowledge.MAYBE:
                        self.deriver.derive_from_new_knowledge(
                            player, card, knowledge)

    def add_info_from_clues(self, clues: Clues):
        self._add_cards_from_clues(clues)
        self._add_rumours_from_clues(clues)
        self.brute_force_and_derive_from_findings()

    def _add_cards_from_clues(self, clues):
        for player, cards in clues.cards_seen.items():
            for card in cards:
                self.clues.add_card(card, player)
                self.deriver.derive_from_new_knowledge(player, card,
                                                       Knowledge.TRUE)

    def _add_rumours_from_clues(self, clues):
        for rumour in clues.get_rumours():
            self.clues.add_rumour(rumour)
            self.deriver.derive_from_new_rumour(rumour)

    def display_state(self) -> str:
        formatter = KnowledgeTableFormatter()
        return formatter.format_knowledge_table(self.knowledge_table)

    def get_knowledge_table(self) -> KnowledgeTable:
        return self.knowledge_table

    def get_context(self) -> Context:
        return self.context

    def get_clues(self) -> Clues:
        return self.clues
Пример #3
0
    def setUp(self) -> None:
        context = context_fixture
        self.empty_solution_finder = SolutionFinder(Clues(context),
                                                    KnowledgeTable(context.players, context.cards))

        knowledge_table = KnowledgeTable(context.players, context.cards)
        tom_cards = [Cards.BLAAUWVANDRAET, Cards.BUBBELBAD, Cards.BIJL, Cards.HALTER]
        menno_cards = [Cards.ROODHART, Cards.ZITKAMER, Cards.KNUPPEL, Cards.GASTENVERBLIJF]
        michiel_cards = [Cards.DEWIT, Cards.THEATER, Cards.TOUW]
        for card in tom_cards:
            knowledge_table.set(tom, card, Knowledge.TRUE)
        for card in menno_cards:
            knowledge_table.set(menno, card, Knowledge.TRUE)
        for card in michiel_cards:
            knowledge_table.set(michiel, card, Knowledge.TRUE)
        self.half_full_solution_finder = SolutionFinder(Clues(context), knowledge_table)
Пример #4
0
    def format_category_table(self, category: Category, knowledge_table: KnowledgeTable):
        players = knowledge_table.players
        category_cards = [card for card in knowledge_table.cards if card.category == category]
        category_cards.sort(key=lambda card: card.name)

        table = TableFormatter(len(category_cards) + 1, len(players) + 1)
        # Set the player names in the table
        for p in range(len(players)):
            table.set(0, p + 1, players[p].name)
        # Set the card names in the table
        for c in range(len(category_cards)):
            table.set(c + 1, 0, category_cards[c].name)
        # fill the table
        for card_i in range(len(category_cards)):
            for player_i in range(len(players)):
                card = category_cards[card_i]
                player = players[player_i]
                s = knowledge_to_str(knowledge_table.get(player, card))
                table.set(card_i + 1, player_i + 1, s)
        return table.to_string()
Пример #5
0
def check_knowledge(knowledge_table: KnowledgeTable,
                    clues: Clues,
                    new_player_hands: Dict[Player, List[Card]] = None) -> bool:

    player_hands, murder_cards, free_cards = knowledge_table.current_player_hands(
    )

    for cat in Category:
        if len([c.category for c in murder_cards if c.category is cat]) > 1:
            return False

    players = clues.context.players
    for player in players:
        if new_player_hands is not None:
            player_hands[player] += new_player_hands[player]
            player_hands[player] = list(set(
                player_hands[player]))  # To get unique elements from list
            for card in new_player_hands[player]:
                if card in free_cards:
                    free_cards.remove(card)
        if len(player_hands[player]) > player.cardAmount:
            return False

    for rumour in clues.rumours:
        rumour_cards = rumour.rumour_cards
        for replier, knowledge in rumour.replies:
            has_rumour_card = set(rumour_cards).isdisjoint(
                player_hands[replier])
            if knowledge == Knowledge.FALSE:
                # Replier should not have any of the rumoured cards
                if not has_rumour_card:
                    return False
            elif knowledge == Knowledge.TRUE:
                # Replier should have any of the rumoured cards
                if replier.cardAmount == len(
                        player_hands[replier]) and has_rumour_card:
                    return False
                if set(rumour_cards).isdisjoint(
                        free_cards) and has_rumour_card:
                    return False
    return True
    def test_format_knowledge_table(self):
        context = context_fixture
        knowledge_table = KnowledgeTable(context.players, context.cards)
        knowledge_table.set(knowledge_table.players[0], Cards.EETKAMER,
                            Knowledge.FALSE)
        knowledge_table.set(knowledge_table.players[2], Cards.ROODHART,
                            Knowledge.TRUE)

        printer = KnowledgeTableFormatter()
        result = printer.format_knowledge_table(knowledge_table)

        expected = '\n'.join([
            "                   Tom    Menno  Michiel",
            "Blaauw van Draet    .       .       .   ",
            "          De Wit    .       .       .   ",
            "      Groenewoud    .       .       .   ",
            "          Pimpel    .       .       .   ",
            "        Roodhart    .       .       v   ",
            "",
            "            Tom    Menno  Michiel",
            "     Bijl    .       .       .   ",
            "   Halter    .       .       .   ",
            "Kandelaar    .       .       .   ",
            "  Knuppel    .       .       .   ",
            "      Mes    .       .       .   ",
            "  Pistool    .       .       .   ",
            "     Touw    .       .       .   ",
            "   Vergif    .       .       .   ",
            "",
            "                 Tom    Menno  Michiel",
            "     Bubbelbad    .       .       .   ",
            "      Eetkamer    x       .       .   ",
            "Gastenverblijf    .       .       .   ",
            "           Hal    .       .       .   ",
            "        Keuken    .       .       .   ",
            "       Theater    .       .       .   ",
            "     Werkkamer    .       .       .   ",
            "      Zitkamer    .       .       .   ",
        ])
        self.assertEqual(result, expected)
Пример #7
0
 def setUp(self) -> None:
     clues = Clues(context_fixture)
     self.context = clues.get_context()
     self.empty_knowledge_table = KnowledgeTable(self.context.players,
                                                 self.context.cards)
     self.empty_deriver = Deriver(clues, self.empty_knowledge_table)
Пример #8
0
 def setUp(self) -> None:
     self.knowledge_table = KnowledgeTable(context_fixture.players,
                                           context_fixture.cards)
     self.clues = Clues(context_fixture)
     self.empty_brute_forcer = BruteForcer(self.clues, self.knowledge_table)
Пример #9
0
 def setUp(self):
     self.context = context_fixture
     self.some_player = tom
     self.knowledge_table = KnowledgeTable(self.context.players, self.context.cards)
Пример #10
0
class TestKnowledgeTable(TestCase):
    def setUp(self):
        self.context = context_fixture
        self.some_player = tom
        self.knowledge_table = KnowledgeTable(self.context.players, self.context.cards)

    def test_new_knowledge_table(self):
        for player in self.context.players:
            for card in self.context.cards:
                self.assertEqual(self.knowledge_table.get(player, card), Knowledge.MAYBE)

    def test_set(self):
        self.knowledge_table.set(self.some_player, Cards.KNUPPEL, Knowledge.TRUE)
        self.assertEqual(
            self.knowledge_table.get(self.some_player, Cards.KNUPPEL),
            Knowledge.TRUE
        )

    def test_invalid_set(self):
        self.knowledge_table.set(self.some_player, Cards.KNUPPEL, Knowledge.TRUE)
        with self.assertRaises(ValueError):
            self.knowledge_table.set(self.some_player, Cards.KNUPPEL, Knowledge.FALSE)

    def test_set_forcefully(self):
        self.knowledge_table.set(self.some_player, Cards.KNUPPEL, Knowledge.TRUE)
        self.knowledge_table.set_forcefully(self.some_player, Cards.KNUPPEL, Knowledge.FALSE)

    def test_current_player_hands(self):
        knowledge_table = self.knowledge_table

        for player in self.context.players:
            knowledge_table.set(player, Cards.KNUPPEL, Knowledge.FALSE)

        knowledge_table.set(self.some_player, Cards.TOUW, Knowledge.TRUE)

        player_hands, murderer_cards, free_cards = knowledge_table.current_player_hands()

        self.assertIn(Cards.KNUPPEL, murderer_cards)
        self.assertIn(Cards.TOUW, player_hands[self.some_player])
        self.assertIn(Cards.PIMPEL, free_cards)