Пример #1
0
def evaluate_game(room_id):
    n_alive_civilians = Player.num_alive_players(room_id,
                                                 role=Role.CIVILIAN.name)

    if n_alive_civilians == 1:
        summary = generate_summary(room_id)
        clear_game(room_id)
        return [
            GameState(Status.NON_CIVILIAN_WIN, room_id=room_id),
            GameState(Status.SUMMARY, data=summary),
        ]

    n_alive_players = Player.num_alive_players(room_id)

    if n_alive_civilians == n_alive_players:
        summary = generate_summary(room_id)
        clear_game(room_id)
        return [
            GameState(Status.CIVILIAN_WIN, room_id=room_id),
            GameState(Status.SUMMARY, data=summary),
        ]

    alive_player_ids = Player.alive_player_ids(room_id)
    playing_order = decide_playing_order(alive_player_ids)
    return [GameState(Status.PLAYING_ORDER, playing_order, room_id=room_id)]
Пример #2
0
    def test_get():
        user_id = 1
        room_id = 1
        Player.insert(Player(user_id, room_id, Role.CIVILIAN.name))
        player = Player.get(user_id)

        assert isinstance(player, Player)
        assert player.user_id == user_id
        assert player.room_id == room_id
        assert player.role == Role.CIVILIAN.name
        assert player.alive
        assert not player.guessing
    def test_eliminate_invalid_scenario(room_id, user_id, expected_status):
        PlayingRole.insert(PlayingRole(2, Role.MR_WHITE.name))
        Player.insert(Player(5, 2, Role.MR_WHITE.name))
        kill_player(2)

        game_states = eliminate_player(room_id, user_id)
        assert len(game_states) == 1

        game_state = game_states[0]
        assert game_state.status is expected_status

        PlayingRole.delete(2)
        Player.delete(2)
Пример #4
0
def complete_poll(room_id):
    tally, total_votes = count_vote(room_id)
    data = {"tally": tally}
    if total_votes == 0:
        terminate_poll(room_id)
        return [GameState(Status.NO_VOTES_SUBMITTED, data)]

    alive_player_ids = Player.alive_player_ids(room_id)
    data["players"] = alive_player_ids
    if total_votes < len(alive_player_ids) // 2 + 1:
        terminate_poll(room_id)
        return [GameState(Status.NOT_ENOUGH_VOTES, data)]

    max_votes = max(tally.values())
    voted_players = [
        voted_player
        for voted_player, votes in tally.items()
        if votes == max_votes
    ]
    if len(voted_players) > 1:
        terminate_poll(room_id)
        return [GameState(Status.MULTIPLE_PLAYERS_VOTED, data)]

    data["player"] = voted_players[0]
    terminate_poll(room_id)
    return [GameState(Status.POLL_DECIDED, data)]
Пример #5
0
def generate_summary(room_id):
    players = Player.get_all(room_id)
    civilians = []
    undercovers = []
    mr_whites = []

    for player in players:
        if player.role == Role.CIVILIAN.name:
            civilians.append({
                "user_id": player.user_id,
                "alive": player.alive
            })
        elif player.role == Role.UNDERCOVER.name:
            undercovers.append({
                "user_id": player.user_id,
                "alive": player.alive
            })
        elif player.role == Role.MR_WHITE.name:
            mr_whites.append({
                "user_id": player.user_id,
                "alive": player.alive
            })

    return {
        "civilian_word": PlayingRole.get_word(room_id, Role.CIVILIAN).word,
        "undercover_word": PlayingRole.get_word(room_id, Role.UNDERCOVER).word,
        "civilians": civilians,
        "undercovers": undercovers,
        "mr_whites": mr_whites,
    }
Пример #6
0
    def test_evaluate_game(killed_user_ids, expected_status, session):
        room_id = 1
        for user_id in killed_user_ids:
            kill_player(user_id)

        game_states = evaluate_game(room_id)

        assert game_states[0].status is expected_status
        if game_states[0].status is not Status.PLAYING_ORDER:
            assert game_states[0].data is None
        else:
            new_playing_order = game_states[0].data["playing_order"]
            assert isinstance(new_playing_order, list)
            assert len(new_playing_order) == Player.num_alive_players(room_id)
            print(f"the new playing order is: {new_playing_order}")

        remaining_role = (session.query(PlayingRole).filter_by(
            room_id=room_id).first())
        remaining_player = (session.query(Player).filter_by(
            room_id=room_id).first())
        if game_states[0].status is not Status.PLAYING_ORDER:
            assert remaining_role is None
            assert remaining_player is None
        else:
            assert remaining_role is not None
            assert remaining_player is not None
Пример #7
0
def guess_word(user_id, word):
    player = Player.get(user_id)
    if player is None or not player.guessing:
        return [GameState(Status.NOT_IN_GUESSING_TURN)]

    civilian_word = PlayingRole.get_word(player.room_id, Role.CIVILIAN).word

    word = re.sub("[^a-z0-9]", "", word.lower())
    civilian_word = re.sub("[^a-z0-9]", "", civilian_word.lower())

    if Levenshtein.distance(word, civilian_word) <= 1:
        clear_game(player.room_id)
        return [GameState(Status.MR_WHITE_WIN, room_id=player.room_id)]

    Player.update(user_id, guessing=False)
    return evaluate_game(player.room_id)
Пример #8
0
def decide_vote_states(room_id):
    tally, total_votes = count_vote(room_id)
    num_alive_players = Player.num_alive_players(room_id)
    poll = Poll.get(room_id)
    data = {"msg_id": poll.msg_id, "tally": tally}
    if total_votes == num_alive_players:
        return [GameState(Status.TOTAL_VOTES_REACHED, data)]
    return [GameState(Status.VOTE_SUCCESS, data)]
Пример #9
0
 def wrapper(room_id, user_id, *args, **kwargs):
     player = Player.get(user_id)
     data = {"player": user_id}
     if player is None or player.room_id != room_id:
         return [GameState(Status.PLAYER_NOT_FOUND, data)]
     if not player.alive:
         return [GameState(Status.PLAYER_ALREADY_KILLED, data)]
     return func(room_id, user_id, *args, **kwargs)
Пример #10
0
    def test_alive_player_ids():
        room_id = 1
        user_ids = [1, 2, 3, 4]
        status = [True, True, False, True]
        roles = [
            Role.CIVILIAN.name,
            Role.CIVILIAN.name,
            Role.MR_WHITE.name,
            Role.UNDERCOVER.name,
        ]
        for user_id, alive, role in zip(user_ids, status, roles):
            player = Player(user_id=user_id,
                            alive=alive,
                            role=role,
                            room_id=room_id)
            Player.insert(player)

        alive_players_ids = Player.alive_player_ids(room_id)
        alive_civilians_ids = Player.alive_player_ids(room_id,
                                                      role=Role.CIVILIAN.name)
        alive_undercover_ids = Player.alive_player_ids(
            room_id, role=Role.UNDERCOVER.name)
        alive_mr_white_ids = Player.alive_player_ids(room_id,
                                                     role=Role.MR_WHITE.name)

        assert alive_players_ids == [1, 2, 4]
        assert alive_civilians_ids == [1, 2]
        assert alive_undercover_ids == [4]
        assert alive_mr_white_ids == []
Пример #11
0
    def test_num_alive_players():
        room_id = 1
        user_ids = [1, 2, 3, 4]
        status = [True, True, False, True]
        roles = [
            Role.CIVILIAN.name,
            Role.CIVILIAN.name,
            Role.MR_WHITE.name,
            Role.UNDERCOVER.name,
        ]
        for user_id, alive, role in zip(user_ids, status, roles):
            player = Player(user_id=user_id,
                            alive=alive,
                            role=role,
                            room_id=room_id)
            Player.insert(player)

        n_alive_players = Player.num_alive_players(room_id)
        n_alive_civilians = Player.num_alive_players(room_id,
                                                     role=Role.CIVILIAN.name)
        n_alive_undercover = Player.num_alive_players(
            room_id, role=Role.UNDERCOVER.name)
        n_alive_mr_white = Player.num_alive_players(room_id,
                                                    role=Role.MR_WHITE.name)

        assert n_alive_players == 3
        assert n_alive_civilians == 2
        assert n_alive_undercover == 1
        assert n_alive_mr_white == 0
Пример #12
0
    def test_insert_player(session):
        playing_role = PlayingRole(1, Role.CIVILIAN.name, "civilian_word")
        civilian = Player(
            user_id=1,
            room_id=playing_role.room_id,
            role=playing_role.role,
        )
        Player.insert(civilian)
        players = session.query(Player).filter_by(user_id=1).all()

        assert len(players) == 1
        player = players[0]
        assert player.user_id == 1
        assert player.alive
        assert not player.guessing
        assert player.role == playing_role.role
        assert player.room_id == playing_role.room_id
        assert player.playing_role.word == playing_role.word
Пример #13
0
    def test_delete(session):
        user_ids = [1, 2, 3]
        room_ids = [1, 1, 2]
        for user_id, room_id in zip(user_ids, room_ids):
            player = Player(user_id=user_id,
                            room_id=room_id,
                            role=Role.CIVILIAN.name)
            Player.insert(player)

        to_be_deleted_room_id = 1
        intact_room_id = 2
        Player.delete(to_be_deleted_room_id)

        should_be_none = (session.query(Player).filter_by(
            room_id=to_be_deleted_room_id).first())
        should_not_none = (session.query(Player).filter_by(
            room_id=intact_room_id).first())
        assert should_be_none is None
        assert should_not_none is not None
Пример #14
0
def assign_role(
    room_id, user_ids, civilian_word, undercover_word, role_proportion
):
    num_civilians, num_undercovers, num_mr_whites = role_proportion
    random.shuffle(user_ids)
    user_words = {}
    mr_whites = set()
    for user_id in user_ids:
        if len(user_words) < num_civilians:
            user_words[user_id] = {"word": civilian_word}
            Player.insert(Player(user_id, room_id, Role.CIVILIAN.name))
        elif len(user_words) < num_civilians + num_undercovers:
            user_words[user_id] = {"word": undercover_word}
            Player.insert(Player(user_id, room_id, Role.UNDERCOVER.name))
        else:
            user_words[user_id] = {"word": MR_WHITE_WORD}
            Player.insert(Player(user_id, room_id, Role.MR_WHITE.name))
            mr_whites.add(user_id)
    return user_words, mr_whites
def eliminate_player(room_id, user_id):
    kill_player(user_id)
    killed_player = Player.get(user_id)
    data = {"player": killed_player.user_id, "role": killed_player.role}

    game_states = []
    if killed_player.role == Role.CIVILIAN.name:
        game_states.append(GameState(Status.CIVILIAN_ELIMINATED, data))
        game_states += evaluate_game(room_id)
    elif killed_player.role == Role.UNDERCOVER.name:
        game_states.append(GameState(Status.UNDERCOVER_ELIMINATED, data))
        game_states += evaluate_game(room_id)
    elif killed_player.role == Role.MR_WHITE.name:
        game_states.append(GameState(Status.MR_WHITE_ELIMINATED, data))
        game_states.append(GameState(Status.ASK_GUESSED_WORD))

    return game_states
Пример #16
0
 def test_insert_duplicate_player():
     civilian = Player(
         user_id=1,
         room_id=1,
         role=Role.CIVILIAN.name,
     )
     Player.insert(civilian)
     with pytest.raises(Exception):
         undercover = Player(
             user_id=1,
             room_id=2,
             role=Role.UNDERCOVER.name,
         )
         Player.insert(undercover)
Пример #17
0
    def test_update():
        user_id = 1
        player = Player(user_id=user_id, room_id=1, role=Role.CIVILIAN.name)
        Player.insert(player)

        updated_room_id = 2
        updated_role = Role.MR_WHITE.name
        updated_alive = False
        updated_guessing = True
        updated_attrs = {
            "room_id": updated_room_id,
            "role": updated_role,
            "alive": updated_alive,
            "guessing": updated_guessing,
        }
        Player.update(user_id, **updated_attrs)

        updated_player = Player.get(user_id)
        assert updated_player.room_id == updated_room_id
        assert updated_player.role == updated_role
        assert not updated_player.alive
        assert updated_player.guessing
def kill_player(user_id):
    player = Player.get(user_id)
    updated_attrs = {"alive": False}
    if player.role == Role.MR_WHITE.name:
        updated_attrs["guessing"] = True
    Player.update(user_id, **updated_attrs)
Пример #19
0
 def test_get_non_existing_player():
     # no players added previously in `populate_db()`
     user_id = 1
     assert Player.get(user_id) is None
 def test_kill_player(user_id, expected_guessing):
     kill_player(user_id)
     killed_player = Player.get(user_id)
     assert not killed_player.alive
     assert killed_player.guessing is expected_guessing
 def populate_db():
     PlayingRole.insert(PlayingRole(1, Role.CIVILIAN.name, "civilian_word"))
     PlayingRole.insert(
         PlayingRole(1, Role.UNDERCOVER.name, "undercover_word"))
     PlayingRole.insert(PlayingRole(1, Role.MR_WHITE.name))
     Player.insert(Player(1, 1, Role.CIVILIAN.name))
     Player.insert(Player(2, 1, Role.CIVILIAN.name))
     Player.insert(Player(3, 1, Role.UNDERCOVER.name))
     Player.insert(Player(4, 1, Role.MR_WHITE.name))
     yield
     PlayingRole.delete(1)
     Player.delete(1)
Пример #22
0
def clear_game(room_id):
    Player.delete(room_id)
    PlayingRole.delete(room_id)
    Vote.delete_all(room_id)
    Poll.delete(room_id)
Пример #23
0
 def wrapper(room_id, user_ids, *args, **kwargs):
     playing_users = Player.filter_exists(user_ids)
     if len(playing_users) > 0:
         data = {"playing_users": playing_users}
         return [GameState(Status.PLAYING_USER_FOUND, data)]
     return func(room_id, user_ids, *args, **kwargs)
Пример #24
0
 def test_update_non_existing_player():
     # no players added previously in `populate_db()`
     user_id = 1
     with pytest.raises(Exception):
         Player.update(user_id, alive=False)
Пример #25
0
def start_poll(room_id, user_id, msg_id):  # user_id used inside decorator
    alive_player_ids = Player.alive_player_ids(room_id)
    new_poll = Poll(room_id, msg_id)
    Poll.add(new_poll)
    data = {"players": alive_player_ids}
    return [GameState(Status.POLL_STARTED, data)]