示例#1
0
    def __run_turn(self):
        """
        This method runs a single turn by prompting the current player in the internal state
        to make a move.
        """
        current_player_obj = self.__get_player_by_color(self.__state.current_player)
        try:
            # Get action from player using a deep copy of state
            action = utils.timed_call(Referee.PLAYER_TIMEOUT, current_player_obj, 'get_action',
                                       args=(self.__state.deepcopy(),))

            # If call was not successful or anything but an Action object was returned, the player failed
            if not isinstance(action, Action):
                self.__kick_player(current_player_obj, PlayerKickReason.FAILING)
            else:
                # Use game tree to validate action (will throw InvalidPositionException if
                # action is illegal)
                self.__state = self.__game_tree.try_action(action)

                if Referee.DEBUG:
                    print(f'{current_player_obj.color} just moved from {action.src} to {action.dst}')
                self.__fire_game_state_changed()
        except AssertionError as e:
            # Raise assertion errors are these are used for testing
            raise e
        except InvalidActionException:
            self.__kick_player(current_player_obj, PlayerKickReason.CHEATING)
示例#2
0
    def __broadcast_tournament_end(self) -> None:
        """
        This methods calls tournament_has_ended() on each IPlayer partaking in the tournament
        to let it know that the tournament has ended. Failure on the part of any player to acknowledge
        this in a timely fashion will result in their disconnection.

        :return: None
        """

        # Trim down player list of winning players to those that ack the notification
        present_players = []
        for p in self.__players:
            if utils.timed_call(Manager.PLAYER_TIMEOUT, p, 'tournament_has_ended', tuple([True])):
                present_players.append(p)
            else:
                self.__tournament_losers.append(p)
                self.__tournament_kicked.append(p)
                p.kick(PlayerKickReason.FAILING.name)
        self.__players = present_players
        self.__tournament_winners = present_players

        # Notify loser players that they lost
        for loser in self.__tournament_losers:
            if loser not in self.__tournament_kicked:
                loser.tournament_has_ended(False)
示例#3
0
    def __run_placements(self) -> bool:
        """
        Runs placements rounds until everyone has placed their avatars. Players may
        get removed in the process for either failing or cheating. If all players
        get removed then the function returns False to indicate there is no point
        in pressing forward with the game. Otherwise, it returns True.

        :return: boolean indicating whether any players remain
        """

        # Determine how many avatars there are to place
        avatars_to_place = self.__avatars_per_player * len(self.__players)

        # Prompt players to place until we've exhausted all avatars
        while avatars_to_place > 0:
            # Cycle over players and have them provide a Position object describing where they
            # wish to place their avatars
            for p in self.__players:
                # Check if player has either failed or cheated; if they have, skip 'em over
                if p in self.__failing_players or p in self.__cheating_players:
                    avatars_to_place -= 1
                    continue

                # Get placement for player using a deep copy of state
                placement = utils.timed_call(Referee.PLAYER_TIMEOUT, p, 'get_placement',
                                             args=(self.__state.deepcopy(),))

                # Validate placement received
                if not isinstance(placement, Position):
                    # If it's not a Position, mark out player as failing & remove player from
                    # state
                    self.__kick_player(p, PlayerKickReason.FAILING)
                    # Decrement avatars needed to be placed
                    avatars_to_place -= 1
                    continue

                try:
                    # Try to place on board
                    self.__state.place_avatar(p.color, placement)
                except InvalidPositionException:
                    # Position is out-of-bounds, already occupied or a hole. Mark player
                    # as cheating & remove player from state.
                    self.__kick_player(p, PlayerKickReason.CHEATING)
                    # Decrement avatars needed to be placed
                    avatars_to_place -= 1
                    continue

                if Referee.DEBUG:
                    print(f'got placement of {placement} from player {p.color}')

                self.__fire_game_state_changed()
                # Decrement avatars needed to be placed
                avatars_to_place -= 1

        # Check if any players remain after placement (everyone might have gotten kicked)
        return self.__state.players_no != 0
示例#4
0
    def __notify_player_colors(self):
        """
        Assign each player the color that correspond to their position in the player list and notify
        each player which colors they will be playing against. If player's fail to acknowledge the color
        messages, their are marked as failing players.
        :return: None
        """
        # Assign each player the color that correspond to their position in the player list
        game_colors = []
        for index, p in enumerate(self.__players):
            ack = utils.timed_call(Referee.PLAYER_TIMEOUT, p, 'set_color', args=(Color(index),))
            game_colors.append(Color(index))
            # if the player doesn't ack, they are a failing player
            if ack is None or not ack:
                self.__failing_players.append(p)

        # Notify each player which colors they will be playing against
        for player in self.__players:
            colors = [color for color in game_colors if color != player.color]
            ack = utils.timed_call(Referee.PLAYER_TIMEOUT, player, 'notify_opponent_colors', args=tuple([colors]))
            # if the player doesn't ack, they are a failing player
            if ack is None or not ack:
                self.__failing_players.append(player)
示例#5
0
    def __broadcast_tournament_start(self) -> None:
        """
        This methods calls tournament_has_started() on each IPlayer partaking in the tournament
        to let it know that the tournament has begun. Failure on the part of any player to acknowledge
        this in a timely fashion will result in their disconnection.

        :return: None
        """

        # Trim down player list to players that have acknowledged that the tournament has started
        present_players = []
        for p in self.__players:
            if utils.timed_call(Manager.PLAYER_TIMEOUT, p, 'tournament_has_started', ()):
                present_players.append(p)
            else:
                self.__tournament_kicked.append(p)
                p.kick(PlayerKickReason.FAILING.name)
        self.__players = present_players
示例#6
0
def simimgs(in_csv_path: str, out_csv_path: str):
    """This function, simimgs, is the main entrypoint for the script.

        Read through an input csv file, in_csv_path, that contains a list of image path paris, compute their
        similarity score and record the time it takes to run this computation. For each valid pair of images,
        write out the similarity score and running time in an output file, out_csv_path.

    Args:
        in_csv_path: file path to the input csv file
        out_csv_path: file path to the output csv file
    """

    try:
        with open(in_csv_path, 'rt', encoding='utf-8') as csv_in:
            with open(out_csv_path, 'wt', encoding='utf-8',
                      newline='') as csv_out:
                csv_reader = csv.reader(csv_in, delimiter=',')
                csv_writer = csv.writer(csv_out, delimiter=',')
                next(csv_reader)  # skip input csv header
                csv_writer.writerow(['image1', 'image2', 'similar', 'elapsed'])

                for line_numb, row in enumerate(csv_reader, start=1):
                    im1_path, im2_path = row[0], row[1]
                    invalid_paths = list(
                        filter(lambda path: not os.path.exists(path),
                               [im1_path, im2_path]))
                    if len(invalid_paths) > 0:
                        print("Invalid line {} in input csv".format(line_numb))
                        if im1_path in invalid_paths:
                            print("--- Image 1 has an invalid path: {}".format(
                                im1_path))
                        if im2_path in invalid_paths:
                            print("--- Image 2 has an invalid path: {}".format(
                                im2_path))
                        continue
                    else:
                        similarity_score, run_time = timed_call(
                            get_similarity, [im1_path, im2_path])
                        csv_writer.writerow(
                            [im1_path, im2_path, similarity_score, run_time])
    except Exception as e:
        print('Error: ', e)
示例#7
0
    def __notify_players(self, losers: [IPlayer], winners: [IPlayer], kicked: [IPlayer]) -> [[IPlayer], [IPlayer], [IPlayer]]:
        """
        Notifies the given collection of winning and losing players that they have either
        won the game (a game, not necessarily the tournament) or that they lost the tournament
        (if you lose a game, you lose the tournament). A failure on the part of the winning players
        to accept the notification will result in them being moved to the losers collection.

        :param losers: list of IPlayer representing losing players
        :param winners: list of IPlayer representing winning players
        :param kicked: list of IPlayer representing kicked players
        :return: resulting losers: [IPlayer], winners: [IPlayer], kicked: [IPlayer]
        """
        # Initialize list to hold IPlayer objects that fail to acknowledge that they won
        failing_winners = []
        # Notify this round's winners that they won
        for winner in winners:
            try:
                result = utils.timed_call(Manager.PLAYER_TIMEOUT, winner, 'status_update', (PlayerStatus.WON_GAME, ))

                # Make sure we get back True
                if not isinstance(result, bool) or not result:
                    raise TypeError()

            except Exception:
                # If an exception was thrown the winner becomes a loser.
                failing_winners.append(winner)

        # Remove failing winners from winners and add them to collections of losers
        for failing_winner in failing_winners:
            # A failing winner is not a winner
            winners.remove(failing_winner)
            # A failing winner is a game loser
            losers.append(failing_winner)
            # A failing winner is a kicked players
            kicked.append(failing_winner)
            # A failing winner is a tournament loser
            self.__tournament_losers.append(failing_winner)

        # Notify this rounds kicked players that they've been kicked
        for kick in kicked:
            # append tournament kicked players
            self.__tournament_kicked.append(kick)
            try:
                kick.status_update(PlayerStatus.DISCONTINUED)
            except Exception:
                # Nothing to do.
                pass

        # Notify this round's losers that they've lost, only if they haven't already been kicked
        for loser in losers:
            # append tournament losers
            self.__tournament_losers.append(loser)
            if loser not in kicked:
                try:
                    loser.status_update(PlayerStatus.LOST_GAME)
                except Exception:
                    # Nothing to do.
                    pass

        # Return updated winners & losers
        return winners, losers, kicked