diff --git a/agents/basic_agent.py b/agents/basic_agent.py new file mode 100644 index 0000000..18617d7 --- /dev/null +++ b/agents/basic_agent.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +from typing import List, Optional, TYPE_CHECKING + +from game.agent import Agent +from util.cards import get_played_value +from game.table import Table +from game.player import Player + +if TYPE_CHECKING: + from game.card import Card + + +class BasicAgent(Agent): + def __init__(self): + super().__init__(Player()) + + def make_move(self, table: Table) -> None: + """ + Agent makes a move based on the fact that the hand played has the lowest possible value. + """ + possible_moves: List[List[Card]] = self.player.get_all_possible_moves(table) + + smallest_move = possible_moves[0] + smallest_move_value: Optional[int] = get_played_value(smallest_move) + for move in possible_moves: + move_value: Optional[int] = get_played_value(move) + if move_value and (not smallest_move_value or move_value > smallest_move_value): + smallest_move_value = move_value + smallest_move = move + table.try_move(self, smallest_move) + + def get_preferred_card_order(self, table: Table) -> List[Card]: + """ + Returns the preferred cards to exchange in the beginning of a round in descending value order. + """ + possible_cards = list(set(table.deck.card_stack) - set(self.player.hand)) + return sorted(possible_cards, reverse=True) diff --git a/agents/random_agent.py b/agents/random_agent.py index 5057eab..4c804c1 100644 --- a/agents/random_agent.py +++ b/agents/random_agent.py @@ -1,9 +1,11 @@ +from __future__ import annotations + import random +from typing import List, TYPE_CHECKING from game.agent import Agent from game.table import Table from game.player import Player -from typing import List, TYPE_CHECKING if TYPE_CHECKING: from game.card import Card diff --git a/game/card.py b/game/card.py index 4658a73..85f8ca4 100644 --- a/game/card.py +++ b/game/card.py @@ -62,3 +62,9 @@ def __gt__(self, other): def __ge__(self, other): return self > other or self == other + + def __hash__(self): + return hash(self.suit.get_color()) + hash(self.value) + + def __repr__(self): + return self.name diff --git a/game/player.py b/game/player.py index bf4a9f3..b1df02d 100644 --- a/game/player.py +++ b/game/player.py @@ -17,7 +17,7 @@ def __init__(self): Player._player_id += 1 def get_all_possible_moves(self, table: Table) -> List[List[Card]]: - possible_moves = [[]] + possible_moves = [[]] if table.played_cards else [] for amount_of_cards in range(len(table.last_move()[0]) if table.last_move() else 1, len(self.hand) + 1): for potential_move in combinations(self.hand, amount_of_cards): if table.game.valid_move(list(potential_move)): diff --git a/game/president.py b/game/president.py index e12912d..c10f74b 100644 --- a/game/president.py +++ b/game/president.py @@ -139,7 +139,8 @@ def _get_play_order(self) -> Iterator[Agent]: if all(len(agent.player.hand) == 0 for agent in self.agents): return # Some player still has a card. Start a new trick - last_agent = self.table.last_move()[1] + # The check is needed for if a player makes an invalid move + last_agent = self.table.last_move()[1] if self.table.last_move() else self.agent_iterator.get() self.table.new_trick() self.passed_agents = { @@ -151,6 +152,7 @@ def _get_play_order(self) -> Iterator[Agent]: self.agent_iterator.next() # We found the player, but the loop will call next, so we have to call previous to neutralize this. self.agent_iterator.previous() + continue yield self.agent_iterator.get() # The unfinished player comes last, add it to the last_played lis diff --git a/main.py b/main.py old mode 100644 new mode 100755 index 076b1f7..95a9aa3 --- a/main.py +++ b/main.py @@ -1,9 +1,15 @@ +#!/usr/bin/env python3 + from game.president import President +from agents.basic_agent import BasicAgent from agents.simple_agent import SimpleAgent +from agents.random_agent import RandomAgent if __name__ == "__main__": game = President([ - SimpleAgent() for _ in range(3) + BasicAgent(), + RandomAgent(), + RandomAgent(), ]) # Start the game