예제 #1
0
def randomize_teams(room_name: str) -> Dict[str, str]:
    """Randomize the teams in a given room.

    If the room specified for randomization exists, the teams are randomized.
    The response message is empty. The new teams are always different.
    If the room does not exist or is not specified, a response message with an
    'error' field is returned.
    Args:
        room_name: the room to randomize.
    """
    if not game_room_exists(room_name):
        return {fields.ERROR: f'Room named {room_name} does not exist.'}

    room = get_room(room_name)
    players = list(room.team_2_players + room.team_1_players)
    num_players = len(players)
    shuffle(players)
    team_2_players = players[:num_players // 2]
    team_1_players = players[num_players // 2:]
    room = evolve(
        room,
        **dict(team_1_players=team_1_players, team_2_players=team_2_players))
    update_room(room_name, room)

    return {}
예제 #2
0
def join_game(join_request: Dict[str, str]) -> Dict[str, Any]:
    """Receive and respond to a join game request from a client.

    If the game room exists and the player name is not already in use, then
    the player is added to the game room. This is done by updating the game
    state in that room. The player is added to the team with fewest players.

    If the game room does not exist an error message is returned.
    If the player name is already taken an error message is returned.
    If a field is missing or blank in the request an error message is returned.

    Args:
        join_request: Dictionary containing a 'player name' and 'room name'
            fields.

    Returns:
        On success, an empty dictionary is returned and the updated game
        state is broadcast to all clients in the room.
        Otherwise returns a dictionary with an 'error' field.
    """

    error = validate_fields(join_request,
                            (fields.ROOM_NAME, fields.PLAYER_NAME),
                            (fields.ROOM_NAME, fields.PLAYER_NAME))
    if error:
        return {fields.ERROR: error}

    room_name = join_request[fields.ROOM_NAME]
    if not game_room_exists(room_name):
        return {fields.ERROR: f'Room {room_name} does not exist.'}

    # Get current teams and check player name not already in use
    room = get_room(room_name)

    player_name = join_request[fields.PLAYER_NAME]
    if any(plyr.name == player_name for plyr in room.all_players()):
        return {fields.ERROR: f'Player \'{player_name}\' already in game.'}

    # Add player to team with fewest members.
    if len(room.team_1_players) > len(room.team_2_players):
        room.team_2_players.append(build_player(player_name))
    else:
        room.team_1_players.append(build_player(player_name))
    update_room(room_name, room)
    return {}
예제 #3
0
def test_next_clue_giver_other_team_missing():
    clear_rooms()
    create_test_game()
    start_game_action.start_game(TEST_GAME)
    room = get_room(TEST_GAME)

    assert room.clue_giver == room.team_1_players[0]
    assert room.last_clue_giver is None
    giver = room.clue_giver

    # remove players from team 2
    update_room(room.name, evolve(room, team_2_players=[]))

    next_clue_giver(room.name)

    # next player now on same team as before
    room = get_room(TEST_GAME)
    assert room.clue_giver == room.team_1_players[1]
    assert room.last_clue_giver == giver
예제 #4
0
def start_game(room_name: str) -> Dict[str, Any]:
    """Change a room from lobby mode to the first mode of the round.

    Args:
        room_name: Name of the room to start game for. Must correspond to
            a room in lobby mode.

    """
    assert game_room_exists(room_name)

    room = get_room(room_name)

    assert room.game_mode == GameModes.LOBBY
    assert room.game_round == 0

    new_room = evolve(room, game_mode=GameModes.TURN_RECAP, game_round=1)
    update_room(room_name, new_room)

    return {}
def next_clue_giver(room_name: str) -> {}:
    """Changes the clue giver in a room to the next one in the order.

    The clue giver is set to the next person on the other team. If the
    other team is empty the next player on the current team is chosen.

    Args:
        room_name: The room for which to iterate the clue giver.
    """
    assert game_room_exists(room_name)

    room = get_room(room_name)

    next_giver = None
    prev_giver = room.last_clue_giver  # the one before current

    teams = (room.team_1_players, room.team_2_players)
    # special processing to handle no previous giver. Pretend like the previous
    # giver for the other team is the last person on that team.
    if prev_giver is None:
        if room.clue_giver in teams[0]:
            other_team = teams[1]
        elif room.clue_giver in teams[1]:
            other_team = teams[0]
        else:
            other_team = []

        if not other_team:  # switch to next player on current player's team
            prev_giver = room.clue_giver
        else:
            prev_giver = other_team[-1]

    # next clue giver is one following last_clue_giver (same team)
    for team in teams:

        if prev_giver in team:
            ind = team.index(prev_giver)
            next_giver = team[(ind + 1) % len(team)]

    update_room(
        room.name,
        evolve(room, last_clue_giver=room.clue_giver, clue_giver=next_giver))
예제 #6
0
def create_test_game() -> None:
    """Add a test game to the data model.

    The game has room name 'test' and is populated with random characters.
    If the game already exists then this function does nothing.
    """

    room_name = fields.TEST_GAME
    if game_room_exists(room_name):
        return

    # initialize room
    initialize_game_room(room_name, 'Mick')

    # populate room with players
    room = get_room(room_name)
    team_1 = [build_player(p) for p in ['Mick', 'Liz', 'M\'Lickz']]
    team_2 = [build_player(p) for p in ['Dvir', 'Celeste', 'Boaz', 'Ronen']]
    room = evolve(room, **dict(team_1_players=team_1, team_2_players=team_2))
    update_room(room_name, room)
예제 #7
0
def next_mode(room_name: str) -> None:
    """Cause a room to change to its next mode in the cycle.
    
    The room must be in mode CLUE_GIVING or TURN_RECAP.
    The mode is iterated between the two modes.
    
    Args:
        room_name: The room to iterate.
    """

    room = get_room(room_name)

    modes = (GameModes.TURN_RECAP, GameModes.CLUE_GIVING)
    current_mode = room.game_mode
    assert current_mode in modes, (f'Next mode not defined for '
                                   f'{current_mode.name}')

    new_mode = modes[1 - modes.index(current_mode)]

    update_room(room_name, evolve(room, game_mode=new_mode))