Ejemplo n.º 1
0
    def __init__(self, player_one_id):
        """

        :return:
        """
        self.__game_id = str(uuid.uuid4().hex)
        self.__deck = Deck(Game.__TOTAL_CARDS_IN_DECK)
        self.__board = Board(Game.__BOARD_SIZE, self.__deck)
        self.__player_one = Player(player_one_id)
        self.__current_player = self.__player_one
        self.__player_two = None
        self.__is_opponent_automated = True
        self.__is_ready = False
        self.__winner = None

        Game.__LOGGER.debug('Initializing a new game: %s', self.__game_id)
Ejemplo n.º 2
0
class Game(object):
    """
        Class representing a 'synapse' game.
    """

    def __init__(self, player_one_id):
        """

        :return:
        """
        self.__game_id = str(uuid.uuid4().hex)
        self.__deck = Deck(Game.__TOTAL_CARDS_IN_DECK)
        self.__board = Board(Game.__BOARD_SIZE, self.__deck)
        self.__player_one = Player(player_one_id)
        self.__current_player = self.__player_one
        self.__player_two = None
        self.__is_opponent_automated = True
        self.__is_ready = False
        self.__winner = None

        Game.__LOGGER.debug('Initializing a new game: %s', self.__game_id)

    def join(self, player_two_id, is_ai_opponent):
        """
            Joins the game as player two.

            :param player_two_id: The id of player two
            :type player_two_id: str
            :param is_ai_opponent: Whether or not the opponent is an AI
            :type is_ai_opponent: bool

            :precondition: len(player_two_name) > 0
            :precondition: self.__player_two is None
        """
        assert isinstance(player_two_id, str)
        assert len(player_two_id) > 0
        assert isinstance(is_ai_opponent, bool)
        assert self.__player_two is None

        Game.__LOGGER.debug("Game %s - Player Two Join: %s.", self.__game_id, player_two_id)

        self.__player_two = Player(player_two_id)
        self.__is_opponent_automated = is_ai_opponent
        self.__deal()
        self.__is_ready = True

    def __deal(self):
        """
            Deals out the cards to the various players.

            :precondition: self.__player_one is not None and self.__player_two is not None
        """
        assert self.__player_one is not None and self.__player_two is not None

        Game.__LOGGER.debug("Game: %s - Dealing", self.__game_id)

        (player_one_cards, player_two_cards) = self.__deck.deal(2, Game.__NUMBER_OF_CARDS_DEALT)
        for card in player_one_cards:
            self.__player_one.add_card(card)
        for card in player_two_cards:
            self.__player_two.add_card(card)

    def __get_player_by_id(self, player_id):
        """
            Gets a player by id.

            :param player_id: The player id
            :type player_id: str

            :precondition: len(player_id) > 0

            :postcondition: ret is None or isinstance(ret, None)
        """
        assert isinstance(player_id, str)
        assert player_id

        for player in {self.__player_one, self.__player_two}:
            if player.player_id == player_id:
                return Player(player_id)

    def test(self):
        self.__board.find_sequence(4)

    def take_ai_turn(self):
        """
            Takes the turn for the AI player
        """
        assert self.__is_opponent_automated

        # Assumption, AI is always player2...this is bad.
        assert self.__player_two == self.__current_player

        # Determine what move to make and call self.take_turn
        # For now, just choose the first card.

        card_to_play = self.__player_two.cards[0]

        # find the correct sphere to play
        sphere_to_play = self.__board.get_sphere_by_value(card_to_play.value)

        self.take_turn(self.__player_two.player_id, card_to_play.card_id, sphere_to_play.sphere_id)

    def take_turn(self, player_id, card_id, sphere_id):
        """
            Takes the current turn for the given player

            :param player_id: The player taking the turn
            :type player_id: str
            :param card_id: The card being played
            :type card_id: str
            :param sphere_id: The sphere being chosen
            :type sphere_id: str

            :precondition: self.__current_player is player
        """
        assert isinstance(player_id, str)
        assert isinstance(card_id, str)
        assert isinstance(sphere_id, str)
        assert player_id
        assert card_id
        assert sphere_id

        card = self.__deck.get_card_by_id(card_id)
        assert isinstance(card, Card)

        sphere = self.__board.get_sphere_by_id(sphere_id)
        assert isinstance(sphere, Sphere)

        player = self.__get_player_by_id(player_id)
        assert isinstance(player, Player)

        assert card.value == sphere.value
        assert self.__current_player == player
        assert self.__winner is None
        assert self.__is_ready is True
        assert self.__current_player.has_card(card)
        assert self.__board.is_sphere_selectable(card, sphere)

        self.__board.select_sphere(player, sphere)
        self.__current_player.remove_card(card)
        self.__deck.discard(card)
        self.__current_player.add_card(self.__deck.draw())
        self.__check_for_sequence()

        if self.__current_player == self.__player_one:
            self.__current_player = self.__player_two
        else:
            self.__current_player = self.__player_one

    def to_json(self):
        return {
            'game_id': self.__game_id,
            'board': self.__board,
            'player_one': self.__player_one,
            'player_two': self.__player_two,
            'current_player': self.__current_player,
            'winner': self.__winner,
        }

    def __check_for_sequence(self):
        """
            Checks to see if someone has won
        """
        sequence_found = False
        matrix = self.__board.matrix

        for winning_sequence in Game.__WINNING_SEQUENCES:
            sphere_sequence = [matrix[point.x][point.y][point.z].owner == self.__current_player for point in winning_sequence]

            if all(sphere_sequence):
                sequence_found = True
                break
            else:
                assert all(sphere_sequence) is False

        if sequence_found:
            self.__winner = self.__current_player
        else:
            assert self.__winner is None

    @property
    def is_ready(self):
        """
            Returns whether or not the game is ready to start
            :rtype: bool
        """
        return self.__is_ready

    @property
    def game_id(self):
        """
            Returns the id of the game

            :rtype: str
            :postcondition: len(ret) > 0
        """
        return self.__game_id

    @property
    def is_opponent_automated(self):
        """
            Returns true if this game is being played against the CPU

            :rtype: bool
        """
        return self.__is_opponent_automated

    @property
    def players(self):
        """
            Returns a list of players.

            :rtype: list

            :postcondition: all(isinstance(p, Player) for p in ret)
        """
        return [p for p in {self.__player_one, self.__player_two} if p is not None]


    __NUMBER_OF_CARDS_DEALT = 7
    """
        Number of cards dealt to each player
    """

    __TOTAL_CARDS_IN_DECK = 64
    """
        Numbers of cards in the deck
    """

    __BOARD_SIZE = 4
    """
        The size of the board
    """


    __POINT = collections.namedtuple('Point', ['x', 'y', 'z'])
    """
        Named tuple to hold a 3d point coordinate.
    """

    __VERTICAL_WINNING_ENTRIES = set((
        (__POINT(0, 0, 0), __POINT(0, 1, 0), __POINT(0, 2, 0), __POINT(0, 3, 0)),
        (__POINT(1, 0, 0), __POINT(1, 1, 0), __POINT(1, 2, 0), __POINT(1, 3, 0)),
        (__POINT(2, 0, 0), __POINT(2, 1, 0), __POINT(2, 2, 0), __POINT(2, 3, 0)),
        (__POINT(3, 0, 0), __POINT(3, 1, 0), __POINT(3, 2, 0), __POINT(3, 3, 0)),

        (__POINT(0, 0, 1), __POINT(0, 1, 1), __POINT(0, 2, 1), __POINT(0, 3, 1)),
        (__POINT(1, 0, 1), __POINT(1, 1, 1), __POINT(1, 2, 1), __POINT(1, 3, 1)),
        (__POINT(2, 0, 1), __POINT(2, 1, 1), __POINT(2, 2, 1), __POINT(2, 3, 1)),
        (__POINT(3, 0, 1), __POINT(3, 1, 1), __POINT(3, 2, 1), __POINT(3, 3, 1)),

        (__POINT(0, 0, 2), __POINT(0, 1, 2), __POINT(0, 2, 2), __POINT(0, 3, 2)),
        (__POINT(1, 0, 2), __POINT(1, 1, 2), __POINT(1, 2, 2), __POINT(1, 3, 2)),
        (__POINT(2, 0, 2), __POINT(2, 1, 2), __POINT(2, 2, 2), __POINT(2, 3, 2)),
        (__POINT(3, 0, 2), __POINT(3, 1, 2), __POINT(3, 2, 2), __POINT(3, 3, 2)),

        (__POINT(0, 0, 3), __POINT(0, 1, 3), __POINT(0, 2, 3), __POINT(0, 3, 3)),
        (__POINT(1, 0, 3), __POINT(1, 1, 3), __POINT(1, 2, 3), __POINT(1, 3, 3)),
        (__POINT(2, 0, 3), __POINT(2, 1, 3), __POINT(2, 2, 3), __POINT(2, 3, 3)),
        (__POINT(3, 0, 3), __POINT(3, 1, 3), __POINT(3, 2, 3), __POINT(3, 3, 3)),

        #### DIAGONAL ####
        (__POINT(0, 0, 0), __POINT(1, 1, 0), __POINT(2, 2, 0), __POINT(3, 3, 0)),
        (__POINT(0, 3, 0), __POINT(1, 2, 0), __POINT(2, 1, 0), __POINT(3, 0, 0)),

        (__POINT(0, 0, 1), __POINT(1, 1, 1), __POINT(2, 2, 1), __POINT(3, 3, 1)),
        (__POINT(0, 3, 1), __POINT(1, 2, 1), __POINT(2, 1, 1), __POINT(3, 0, 1)),

        (__POINT(0, 0, 2), __POINT(1, 1, 2), __POINT(2, 2, 2), __POINT(3, 3, 2)),
        (__POINT(0, 3, 2), __POINT(1, 2, 2), __POINT(2, 1, 2), __POINT(3, 0, 2)),

        (__POINT(0, 0, 3), __POINT(1, 1, 3), __POINT(2, 2, 3), __POINT(3, 3, 3)),
        (__POINT(0, 3, 3), __POINT(1, 2, 3), __POINT(2, 1, 3), __POINT(3, 0, 3)),
    ))

    __HORIZONTAL_WINNING_ENTRIES = set((
        (__POINT(0, 0, 0), __POINT(1, 0, 0), __POINT(2, 0, 0), __POINT(3, 0, 0)),
        (__POINT(0, 1, 0), __POINT(1, 1, 0), __POINT(2, 1, 0), __POINT(3, 1, 0)),
        (__POINT(0, 2, 0), __POINT(1, 2, 0), __POINT(2, 2, 0), __POINT(3, 2, 0)),
        (__POINT(0, 3, 0), __POINT(1, 3, 0), __POINT(2, 3, 0), __POINT(3, 3, 0)),

        (__POINT(0, 0, 1), __POINT(1, 0, 1), __POINT(2, 0, 1), __POINT(3, 0, 1)),
        (__POINT(0, 1, 1), __POINT(1, 1, 1), __POINT(2, 1, 1), __POINT(3, 1, 1)),
        (__POINT(0, 2, 1), __POINT(1, 2, 1), __POINT(2, 2, 1), __POINT(3, 2, 1)),
        (__POINT(0, 3, 1), __POINT(1, 3, 1), __POINT(2, 3, 1), __POINT(3, 3, 1)),

        (__POINT(0, 0, 2), __POINT(1, 0, 2), __POINT(2, 0, 2), __POINT(3, 0, 2)),
        (__POINT(0, 1, 2), __POINT(1, 1, 2), __POINT(2, 1, 2), __POINT(3, 1, 2)),
        (__POINT(0, 2, 2), __POINT(1, 2, 2), __POINT(2, 2, 2), __POINT(3, 2, 2)),
        (__POINT(0, 3, 2), __POINT(1, 3, 2), __POINT(2, 3, 2), __POINT(3, 3, 2)),

        (__POINT(0, 0, 3), __POINT(1, 0, 3), __POINT(2, 0, 3), __POINT(3, 0, 3)),
        (__POINT(0, 1, 3), __POINT(1, 1, 3), __POINT(2, 1, 3), __POINT(3, 1, 3)),
        (__POINT(0, 2, 3), __POINT(1, 2, 3), __POINT(2, 2, 3), __POINT(3, 2, 3)),
        (__POINT(0, 3, 3), __POINT(1, 3, 3), __POINT(2, 3, 3), __POINT(3, 3, 3)),

        #### DIAGONAL ####
        (__POINT(0, 3, 0), __POINT(1, 3, 1), __POINT(2, 3, 2), __POINT(3, 3, 3)),
        (__POINT(0, 3, 3), __POINT(1, 3, 2), __POINT(2, 3, 1), __POINT(3, 3, 0)),

        (__POINT(0, 2, 0), __POINT(1, 2, 1), __POINT(2, 2, 2), __POINT(3, 2, 3)),
        (__POINT(0, 2, 3), __POINT(1, 2, 2), __POINT(2, 2, 1), __POINT(3, 2, 0)),

        (__POINT(0, 1, 0), __POINT(1, 1, 1), __POINT(2, 1, 2), __POINT(3, 1, 3)),
        (__POINT(0, 1, 3), __POINT(1, 1, 2), __POINT(2, 1, 1), __POINT(3, 1, 0)),

        (__POINT(0, 0, 0), __POINT(1, 0, 1), __POINT(2, 0, 2), __POINT(3, 0, 3)),
        (__POINT(0, 0, 3), __POINT(1, 0, 2), __POINT(2, 0, 1), __POINT(3, 0, 0)),
    ))

    __WINNING_SEQUENCES = __VERTICAL_WINNING_ENTRIES | __HORIZONTAL_WINNING_ENTRIES

    __LOGGER = logging.getLogger(__name__)
    """