示例#1
0
class Server():
    """
    Represents the Tsuro Game server that can be connected to by clients via
    TCP and constructs an Administrator to run a tournament.
    """
    def __init__(self, port: int, names: List[str]):
        self._admin = Administrator(SimpleBracketStrategy())
        self._names = names
        self._players = {}
        try:
            with timeout(seconds=TIMEOUT_SECONDS):
                self.connect_players(port)
        except:
            pass  # after a minute, start the tournament
        r_tournament = self._admin.run_tournament()
        self.print_tournament_results(r_tournament)

    def connect_players(self, port: int):
        """
        Creates TCP connections with player clients at the given port and creates a list of remote players.
        """
        host = "127.0.0.1"
        port = int(port)

        njs = NetworkJSONStream(host, port)
        njs.sock.bind((host, port))
        njs.sock.listen(MAX_PLAYERS)

        while (len(self._players) < MAX_PLAYERS):
            conn, _ = njs.sock.accept()
            player = RemotePlayer(conn)
            r_pid = self._admin.add_player(player)
            if (r_pid.is_ok()):

                self._players[r_pid.value()] = self._names[len(self._players)]

    def print_tournament_results(self, r_tournament: Result) -> None:
        """
        Prints the winners and cheaters in the tournament results in sorted order by player id
        """
        winners = [
            sorted([self._players[winner] for winner in winner_set])
            for winner_set in r_tournament.assert_value()[0]
        ]
        cheaters = [
            self._players[cheater]
            for cheater in r_tournament.assert_value()[1]
        ]

        message = {
            "winners": winners,
            "cheaters": sorted(cheaters)
        } if len(cheaters) > 0 else {
            "winners": winners
        }
        json_stream = StdinStdoutJSONStream()
        json_stream.send_message(message)
示例#2
0
 def __init__(self, port: int, names: List[str]):
     self._admin = Administrator(SimpleBracketStrategy())
     self._names = names
     self._players = {}
     try:
         with timeout(seconds=TIMEOUT_SECONDS):
             self.connect_players(port)
     except:
         pass  # after a minute, start the tournament
     r_tournament = self._admin.run_tournament()
     self.print_tournament_results(r_tournament)
示例#3
0
def test_admin_5_first_s() -> None:
    admin = Administrator(SimpleBracketStrategy())
    pid_to_idx = {}
    for idx, player in enumerate(make_players(5)):
        pid_r = admin.add_player(player)
        assert pid_r.is_ok()
        pid_to_idx[pid_r.value()] = idx
    winners_r = admin.run_tournament()
    assert winners_r.is_ok()
    real_winners = winners_r.value()[0][0]
    assert set([pid_to_idx[pid] for pid in real_winners]) == {0}
示例#4
0
def test_admin_10_second_s() -> None:

    # Assert that it runs in a reasonable amount of time
    with timeout(seconds=10):
        admin = Administrator(SimpleBracketStrategy())
        pid_to_idx = {}
        for idx in range(10):
            pid_r = admin.add_player(Player(SecondS()))
            assert pid_r.is_ok()
            pid_to_idx[pid_r.value()] = idx
        winners_r = admin.run_tournament()
        assert winners_r.is_ok()
        real_winners = winners_r.value()[0][0]
        assert len(real_winners)
        assert set([pid_to_idx[pid] for pid in real_winners]) == {1, 5}
示例#5
0
def run_tournament(players: List[Tuple]):
    admin = Administrator(SimpleBracketStrategy())
    player_ids_to_names = {}
    for player in players:
        r_player = admin.add_player(player[1])
        player_ids_to_names[r_player.assert_value()] = player[0]
    r_tournament = admin.run_tournament()
    winners = [
        sorted([player_ids_to_names[winner] for winner in winner_set])
        for winner_set in r_tournament.assert_value()[0]
    ]
    cheaters = [
        player_ids_to_names[cheater]
        for cheater in r_tournament.assert_value()[1]
    ]
    return winners, cheaters
示例#6
0
def test_admin_5_second_s() -> None:
    admin = Administrator(SimpleBracketStrategy())
    pid_to_idx = {}
    players = []
    for idx in range(5):
        player = Mock(wraps=Player(SecondS()))
        players.append(player)
        pid_r = admin.add_player(player)
        assert pid_r.is_ok()
        pid_to_idx[pid_r.value()] = idx
    winners_r = admin.run_tournament()
    assert winners_r.is_ok()
    real_winners = winners_r.value()[0][0]
    assert set([pid_to_idx[pid] for pid in real_winners]) == {0, 2}
    assert players[0].notify_won_tournament.call_args_list == [call(True)]
    assert players[1].notify_won_tournament.call_args_list == [call(False)]
    assert players[2].notify_won_tournament.call_args_list == [call(True)]
    assert players[3].notify_won_tournament.call_args_list == [call(False)]
    assert players[4].notify_won_tournament.call_args_list == [call(False)]
示例#7
0
def test_admin_by_function() -> None:
    tobs = TournamentObserver()
    admin = Administrator(SimpleBracketStrategy())
    admin.add_observer(tobs)

    pid_to_idx = {}
    for idx in range(20):
        pid_r = admin.add_player(Player(SecondS()))
        assert pid_r.is_ok()
        pid_to_idx[pid_r.value()] = idx
        time.sleep(0.1)
    
    admin.run_tournament()
示例#8
0
def test_admin_crashing_player() -> None:
    admin = Administrator(SimpleBracketStrategy())

    cp_exception_init = CrashingPlayer(True, True)
    assert admin.add_player(cp_exception_init).is_ok()
    cp_error_init = CrashingPlayer(False, True)
    assert admin.add_player(cp_error_init).is_ok()
    cp_exception_inter = CrashingPlayer(True, False)
    assert admin.add_player(cp_exception_inter).is_ok()
    cp_error_inter = CrashingPlayer(False, False)
    assert admin.add_player(cp_error_inter).is_ok()
    p = Player(FirstS())
    r = admin.add_player(p)
    assert r.is_ok()
    real_player_pid = r.value()

    winners_r = admin.run_tournament()
    assert winners_r.is_ok()
    real_winners = winners_r.value()[0][0]
    assert real_winners == {real_player_pid}