Exemplo n.º 1
0
    def next_move(self, player, board):
        if player.tile is None:
            for x, y in revolve(10, True):
                port = None
                for p in Port:
                    coords = get_coordinates_in_direction(x, y, p.direction)
                    if board.get_tile_at(*coords) is OutOfBounds:
                        port = p
                        break

                tile = player.tile_hand[2]
                placement = InitialPlacement(tile.index, tile.rotation.value,
                                             player.color.value, x, y,
                                             port.name)

                if all(
                        r.is_valid(placement, board, player)
                        for r in rules.ALL):
                    return placement

        else:
            x, y = get_coordinates_in_direction(player.tile.x, player.tile.y,
                                                player.port.direction)
            tile = player.tile_hand[0]
            return IntermediatePlacement(tile.index, tile.rotation.value,
                                         player.color.value, x, y)
Exemplo n.º 2
0
    def _get_player_state(self, player: Player):
        """
        Determines the state of the given player in the game.

        :return: the state of the player
        :rtype: PlayerState
        """
        # short-circuit if the player hasn't made their first move, yet
        if player.tile is None:
            return PlayerState.ALIVE

        adjacent = self.board.get_tile_at(*get_coordinates_in_direction(
            player.tile.x, player.tile.y, player.port.direction))

        if adjacent is not None and adjacent is not OutOfBounds:
            # advance the player onto the adjacent tile and recur
            player.tile = adjacent
            player.port = adjacent.get_exit_port(player.port.neighbor)
            return self._get_player_state(player)

        elif adjacent is OutOfBounds:
            death_tile = (player.tile, player.port)

            if death_tile in self.start_positions:
                # a player has collided if they end at another's start position
                return PlayerState.COLLIDED

            return PlayerState.DEAD

        elif adjacent is None:
            return PlayerState.ALIVE
Exemplo n.º 3
0
    def is_valid(self, next_move, board, player):
        if next_move.is_initial:
            for direction in Direction:
                tile = board.get_tile_at(*get_coordinates_in_direction(
                    next_move.x, next_move.y, direction))
                if tile is not OutOfBounds and tile is not None:
                    return False, self.ERROR_MSG

        return True, None
Exemplo n.º 4
0
    def is_valid(self, next_move, board, player):
        if not next_move.is_initial:
            correct_x, correct_y = get_coordinates_in_direction(
                player.tile.x, player.tile.y, player.port.direction)

            if next_move.x != correct_x or next_move.y != correct_y:
                return False, self.ERROR_MSG

        return True, None
Exemplo n.º 5
0
    def _will_survive(self, tile, x, y, entry_port, board):
        exit_port = tile.get_exit_port(entry_port)
        next_x, next_y = get_coordinates_in_direction(x, y,
                                                      exit_port.direction)
        next_tile = board.get_tile_at(next_x, next_y)

        if next_tile is OutOfBounds:
            # the player moves off the board
            return False
        elif next_tile is None:
            # the player reaches an unoccupied space on the board
            return True
        else:
            return self._will_survive(next_tile, next_x, next_y,
                                      exit_port.neighbor, board)
Exemplo n.º 6
0
    def is_valid(self, next_move, board, player):
        # has the player at the exit port
        tile = next_move.build_tile() if player.tile is None else player.tile
        port = tile.get_exit_port(
            next_move.port) if player.port is None else player.port

        if self._will_survive(tile, next_move.x, next_move.y, port.neighbor,
                              board):
            # short circuit if the player's move is valid
            return True, None

        x, y = get_coordinates_in_direction(tile.x, tile.y, port.direction)

        # otherwise, figure out if they have any survivable moves
        if any(
                self._will_survive(t, x, y, port.neighbor, board)
                for t in self._possible_tiles(player)):
            return False, self.ERROR_MSG

        # there are no survivable moves, allow this one
        return True, None