Example #1
0
def test_game_has_ended_when_player_reached_points_to_win(default_game_with_3_players):
    sess: GameStateMachine = default_game_with_3_players

    sess.start_game()
    assert sess.state == GameStates.PLAYERS_SUBMITTING_CARDS

    normal_players = [
        p for p in sess.players if p.current_role == CardsAgainstHumanityRoles.PLAYER
    ]
    active_card_picks = sess.currently_active_card.pick
    for player in normal_players:
        sess.player_submit_card(
            PlayerSubmitCards(
                submitting_user=player.username,
                cards=player.cards_in_hand[0:active_card_picks],
            )
        )

    assert sess.state == GameStates.TZAR_CHOOSING_WINNER
    normal_players[0].points = POINTS_TO_WIN - 1  # Making the next point trigger win.
    the_winner_player: CardsAgainstHumanityPlayer = normal_players[0]
    winning_submission = the_winner_player.submissions[-1]

    with pytest.raises(GameHasEnded):
        sess.select_winner(
            sender_name=sess.tzar.username,
            winner=SelectWinningSubmission(submission=winning_submission),
        )
Example #2
0
def test_logical_error_when_selected_winner_submission_does_not_exist(
    default_game_with_3_players,
):
    sess: GameStateMachine = default_game_with_3_players

    sess.start_game()
    assert sess.state == GameStates.PLAYERS_SUBMITTING_CARDS

    normal_players = [
        p for p in sess.players if p.current_role == CardsAgainstHumanityRoles.PLAYER
    ]
    active_card_picks = sess.currently_active_card.pick
    for player in normal_players:
        sess.player_submit_card(
            PlayerSubmitCards(
                submitting_user=player.username,
                cards=player.cards_in_hand[0:active_card_picks],
            )
        )

    with pytest.raises(InvalidPlayerAction):
        sess.select_winner(
            sender_name=sess.tzar.username,
            winner=SelectWinningSubmission(
                submission=Submission(
                    black_card=sess.currently_active_card,
                    white_cards=sess.white_cards[0 : sess.currently_active_card.pick],
                )
            ),
        )
Example #3
0
def test_game_has_ended_when_ran_out_of_white_cards(default_game_with_3_players):
    sess: GameStateMachine = default_game_with_3_players

    sess.start_game()
    assert sess.state == GameStates.PLAYERS_SUBMITTING_CARDS
    sess.white_cards = [
        sess.white_cards[-1]
    ]  # Manually removing leftover white cards from session

    normal_players = [
        p for p in sess.players if p.current_role == CardsAgainstHumanityRoles.PLAYER
    ]
    active_card_picks = sess.currently_active_card.pick
    for player in normal_players:
        sess.player_submit_card(
            PlayerSubmitCards(
                submitting_user=player.username,
                cards=player.cards_in_hand[0:active_card_picks],
            )
        )

    assert sess.state == GameStates.TZAR_CHOOSING_WINNER
    the_winner_player: CardsAgainstHumanityPlayer = normal_players[0]
    winning_submission = the_winner_player.submissions[-1]

    sess.select_winner(
        sender_name=sess.tzar.username,
        winner=SelectWinningSubmission(submission=winning_submission),
    )

    with pytest.raises(GameHasEnded):
        sess.advance_after_voting()
Example #4
0
def test_invalid_player_action_when_player_tries_to_submit_cards(
    default_game_with_3_players,
):
    sess: GameStateMachine = default_game_with_3_players
    with pytest.raises(InvalidPlayerAction):
        sess.player_submit_card(
            PlayerSubmitCards(
                submitting_user=sess.players[0].username,
                cards=sess.players[0].cards_in_hand[0:1],
            )
        )
Example #5
0
def test_player_select_winner_behaviour(database_connection,
                                        prefill_official_cards_to_database):
    """
        room_name: str,
        round_count: int,
        db: Session,
        preferences: GamePreferences,
    :return:
    """
    prefill_official_cards_to_database()

    sm = GameFactory.new_session(
        room_name="test room",
        db=database_connection,
        preferences=GamePreferences.god_is_dead_mode(),
    )

    assert isinstance(sm, GodIsDeadModeStateMachine)
    players = ["P1", "P2", "P3"]
    for p in players:
        sm.player_join(p)

    assert len(sm.players) == 3
    assert sm.tzar() is None
    sm.start_game()

    with pytest.raises(GameHasEnded):
        for i in range(15):
            to_pick = sm.currently_active_card.pick

            submissions = {}
            for p in players:
                cards_to_submit = sm.player_lookup[p].cards_in_hand[0:to_pick]
                submissions[p] = cards_to_submit
                sm.player_submit_card(
                    PlayerSubmitCards(submitting_user=p,
                                      cards=cards_to_submit))

            for p in players:
                sub = Submission(
                    black_card=sm.currently_active_card,
                    white_cards=submissions[list(submissions.keys())[0]],
                )
                sws = SelectWinningSubmission(submission=sub)
                sm.select_winner(
                    sender_name=p,
                    winner=sws,
                )
            sm.advance_after_voting()

            assert sm.player_lookup[players[0]].points == i + 1
    assert sm.player_lookup[players[0]].points == 10
    assert sm.player_lookup[players[1]].points == 0
    assert sm.player_lookup[players[2]].points == 0
Example #6
0
def test_player_advance_after_winner_raises_exception_when_submitted_invalidly(
        database_connection, prefill_official_cards_to_database):
    """
        room_name: str,
        round_count: int,
        db: Session,
        preferences: GamePreferences,
    :return:
    """
    prefill_official_cards_to_database()

    sm = GameFactory.new_session(
        room_name="test room",
        db=database_connection,
        preferences=GamePreferences.god_is_dead_mode(),
    )

    assert isinstance(sm, GodIsDeadModeStateMachine)
    players = ["P1", "P2", "P3"]
    for p in players:
        sm.player_join(p)

    assert len(sm.players) == 3
    assert sm.tzar() is None
    sm.start_game()

    to_pick = sm.currently_active_card.pick

    submissions = {}
    for p in players:
        cards_to_submit = sm.player_lookup[p].cards_in_hand[0:to_pick]
        submissions[p] = cards_to_submit
        sm.player_submit_card(
            PlayerSubmitCards(submitting_user=p, cards=cards_to_submit))

    for p in players:
        sub = Submission(
            black_card=sm.currently_active_card,
            white_cards=submissions[list(submissions.keys())[0]],
        )
        sws = SelectWinningSubmission(submission=sub)
        sm.select_winner(
            sender_name=p,
            winner=sws,
        )

        # Only the last advance is valid
        if p != players[-1]:
            with pytest.raises(InvalidPlayerAction):
                print(f"{p} votes")
                sm.advance_after_voting()
        else:
            sm.advance_after_voting()
Example #7
0
def test_logical_error_when_non_existing_palyer_submits(default_game_with_3_players):
    sess: GameStateMachine = default_game_with_3_players

    sess.start_game()
    assert sess.state == GameStates.PLAYERS_SUBMITTING_CARDS

    expected_card_count = sess.currently_active_card.pick
    with pytest.raises(LogicalError):
        sess.player_submit_card(
            PlayerSubmitCards(
                submitting_user="******",
                cards=sess.players[0].cards_in_hand[0:expected_card_count],
            )
        )
 def __init__(
     self,
     room_name,
     db: Session,
     preferences: GamePreferences,
 ):
     self.session = GameFactory.new_session(room_name,
                                            db=db,
                                            preferences=preferences)
     self.event_mapping: Dict[Any, Reaction] = {
         PlayerSubmitCards.event_id():
         Reaction(event_callback=self.session.player_submit_card),
         SelectWinningSubmission.event_id():
         Reaction(event_callback=self.session.select_winner, ),
     }
Example #9
0
def test_invalid_player_action_when_player_tries_to_submit_cards_wrong_number(
    default_game_with_3_players,
):
    sess: GameStateMachine = default_game_with_3_players

    sess.start_game()
    assert sess.state == GameStates.PLAYERS_SUBMITTING_CARDS

    expected_card_count = sess.currently_active_card.pick
    with pytest.raises(InvalidPlayerAction):
        sess.player_submit_card(
            PlayerSubmitCards(
                submitting_user=sess.players[0].username,
                cards=sess.players[0].cards_in_hand[0 : expected_card_count + 1],
            )
        )
Example #10
0
def test_invalid_player_action_when_submitting_not_owned_cards(
    default_game_with_3_players,
):
    sess: GameStateMachine = default_game_with_3_players

    sess.start_game()
    assert sess.state == GameStates.PLAYERS_SUBMITTING_CARDS

    normal_players = [
        p for p in sess.players if p.current_role == CardsAgainstHumanityRoles.PLAYER
    ]
    active_card_picks = sess.currently_active_card.pick
    for player in normal_players:
        with pytest.raises(InvalidPlayerAction):
            sess.player_submit_card(
                PlayerSubmitCards(
                    submitting_user=player.username,
                    cards=sess.white_cards[0:active_card_picks],
                )  # <- Cheeky stuff in this line,
                # this should come from the player
            )
Example #11
0
async def submit_cards(
        room_name: str,
        cards: List[WhiteCard],
        game_mapper: GameEventMapper = Depends(get_game_mapper),
        token: str = Depends(JWTBearer()),
        conman: ConnectionManager = Depends(get_websocket_connection_manager),
):
    user = decodeJWT(token)
    if user is None:
        raise HTTPException(404, "User not found with this token.")
    room = game_mapper.get_game(room_name)
    if room is None:
        raise HTTPException(404, "Room does not exist.")

    room.on_new_event(
        PlayerSubmitCards(submitting_user=user.user_id, cards=cards),
        user.user_id,
    )

    await broadcast_event(room_name, conman,
                          f"{user.user_id} has submitted cards!")

    return GameStatePlayerView.from_game_state(room.session, user.user_id)
Example #12
0
def test_game_starts_only_with_enough_players(
    database_connection, prefill_cards_to_database
):
    prefill_cards_to_database()
    db = database_connection
    sess: GameStateMachine = GameFactory.new_session(
        "test", db, GamePreferences.default()
    )
    ### STARTING GAME PHASE ######
    with pytest.raises(InvalidPlayerAction):
        sess.start_game()
    assert sess.state == GameStates.STARTING

    sess.player_join("Joe")
    sess.player_join("David")
    sess.player_join("Peter")

    sess.start_game()
    assert sess.state == GameStates.PLAYERS_SUBMITTING_CARDS

    assert sess.currently_active_card.pick is not None

    ### TZAR ELECTION ###
    tzars = [
        p for p in sess.players if p.current_role == CardsAgainstHumanityRoles.TZAR
    ]
    assert len(tzars) == 1
    first_tzar = tzars[0]

    everyone_else: List[CardsAgainstHumanityPlayer] = [
        p for p in sess.players if p.current_role == CardsAgainstHumanityRoles.PLAYER
    ]

    ### ASSERTING PLAYER CARD ASSIGNMENT ###
    active_card_picks = sess.currently_active_card.pick
    for player in everyone_else:
        assert len(player.cards_in_hand) == CARDS_IN_PLAYER_HAND
        sess.player_submit_card(
            PlayerSubmitCards(
                submitting_user=player.username,
                cards=player.cards_in_hand[0:active_card_picks],
            )
        )
        assert len(player.cards_in_hand) == CARDS_IN_PLAYER_HAND - active_card_picks

    ### TZAR IS CHOSING THE WINNER ###
    assert sess.state == GameStates.TZAR_CHOOSING_WINNER
    the_winner_player: CardsAgainstHumanityPlayer = everyone_else[0]
    winning_submission = the_winner_player.submissions[-1]

    sess.select_winner(
        sender_name=sess.tzar.username,
        winner=SelectWinningSubmission(submission=winning_submission),
    )

    ### CHECK AWARDED POINTS ###
    for p in everyone_else:
        if p != the_winner_player:
            assert p.points == 0
        else:
            assert p.points == 1

    sess.advance_after_voting()
    new_tzars = [
        p for p in sess.players if p.current_role == CardsAgainstHumanityRoles.TZAR
    ]
    assert len(new_tzars) == 1, "must be only 1 tzar!"
    assert (
        new_tzars[0] != first_tzar
    ), "The same player cannot be tzar two times in a row"