예제 #1
0
파일: db_utils.py 프로젝트: anjaist/tarok
def get_game_type_and_main_player(game_id: int) -> tuple:
    """checks redis round_choices entry and finds which player has chosen the highest game
    and which game is being played.
    Returns a tuple of (game_type, main_player)"""

    # get original player order from redis
    player_order = RedisGetter.round_choices(game_id, 'order')
    player_order = player_order.split(',')

    # get choice of each player
    player1_choice = RedisGetter.round_choices(game_id,
                                               f'{player_order[0]}_chosen')
    player2_choice = RedisGetter.round_choices(game_id,
                                               f'{player_order[1]}_chosen')
    player3_choice = RedisGetter.round_choices(game_id,
                                               f'{player_order[2]}_chosen')

    # if a player's choice is 'pass', it means they are not the main player
    if player1_choice != 'pass':
        return player1_choice, player_order[0]
    elif player2_choice != 'pass':
        return player2_choice, player_order[1]
    elif player3_choice != 'pass':
        return player3_choice, player_order[2]
    else:
        # all three players' choice was 'pass'
        return 'pass', None
예제 #2
0
파일: db_utils.py 프로젝트: anjaist/tarok
def update_player_options(game_id: int):
    """updates players' options based on current state of choices in redis db"""
    is_last_choice = RedisGetter.round_choices(game_id, 'last_choice')

    # get original player order from redis
    player_order = RedisGetter.round_choices(game_id, 'order')
    player_order = player_order.split(',')

    # get current choice of each player
    player1_choice = RedisGetter.round_choices(game_id,
                                               f'{player_order[0]}_chosen')
    player2_choice = RedisGetter.round_choices(game_id,
                                               f'{player_order[1]}_chosen')
    player3_choice = RedisGetter.round_choices(game_id,
                                               f'{player_order[2]}_chosen')

    # get available games
    chosen_games = [player1_choice, player2_choice, player3_choice]
    available_games = get_available_games(chosen_games)

    player1_options = ['pass'] + available_games
    if not player1_choice:
        player1_options = available_games
    player2_options = ['pass'] + available_games
    player3_options = ['pass'] + available_games

    # if all players have made first choice, compare choices and find available ones for each player
    if player1_choice and player2_choice and player3_choice:
        # if players 2 and 3 chose a game worth more than what player 1 chose, player 1 can choose again
        if player1_choice == 'pass' or is_last_choice == 'true':
            player1_options = ['chosen']
        else:
            player1_options = calculate_player1_options(
                player1_choice, player2_choice, player3_choice,
                player1_options)

        # if player 3 chose a game worth more than what player 2 chose, player 2 can choose again
        if player2_choice == 'pass' or is_last_choice == 'true':
            player2_options = ['chosen']
        else:
            player2_options = calculate_player2_options(
                player2_choice, player3_choice, player2_options)

        # if player 3 can still choose a game worth more than what they've already chosen, they can choose again
        if player3_choice == 'pass' or is_last_choice == 'true':
            player3_options = ['chosen']

    if chosen_games.count('pass') == 2:
        is_last_choice = 'true'

    # update redis with current options for each player
    RedisSetter.round_choices(game_id, f'{player_order[0]}_options',
                              ','.join(player1_options))
    RedisSetter.round_choices(game_id, f'{player_order[1]}_options',
                              ','.join(player2_options))
    RedisSetter.round_choices(game_id, f'{player_order[2]}_options',
                              ','.join(player3_options))
    if is_last_choice == 'true':
        RedisSetter.round_choices(game_id, 'last_choice', is_last_choice)
예제 #3
0
파일: db_utils.py 프로젝트: anjaist/tarok
def create_redis_entry_for_round_choices(game_id: int,
                                         players: list,
                                         new_game: bool = False):
    """creates new entry in redis db with empty game choice and assigns players a random order.
     new_game=True should be set only when a new game (not a new round!) begins
     so that the order of the players is set (randomly).
     After that, the same order is kept throughout the game's lifetime (but cycled through)
     """
    if new_game:
        random.shuffle(players)
    else:
        old_order = RedisGetter.round_choices(game_id, 'order')
        order = old_order.split(',')
        order.append(
            order.pop(0)
        )  # move each player up a spot (the previously first player is now in last spot)
        players = order

    for player in players:
        RedisSetter.round_choices(game_id, f'{player}_chosen', '')
        RedisSetter.round_choices(game_id, f'{player}_options',
                                  'three,two,one,pass')

        # player 1 initially shouldn't be able to choose 'pass'
        if player == players[0]:
            RedisSetter.round_choices(game_id, f'{player}_options',
                                      'three,two,one')

    RedisSetter.round_choices(game_id, 'order', ','.join(players))
    RedisSetter.round_choices(game_id, 'new_order', ','.join(players))
    RedisSetter.round_choices(game_id, 'last_choice', 'false')
예제 #4
0
파일: db_utils.py 프로젝트: anjaist/tarok
def is_round_in_progress(game_id: int) -> bool:
    """if all players have 'chosen' in their options in redis it means
    the page was reloaded and the game is in progress."""
    players = get_all_players(game_id)
    for player in players:
        opt = RedisGetter.round_choices(game_id, f'{player}_options')
        if opt == 'chosen':
            return True
    return False
예제 #5
0
파일: db_utils.py 프로젝트: anjaist/tarok
def get_players_that_need_to_choose_game(game_id: int) -> Union[list, None]:
    """queries redis db and returns players that can still make a choice of game for round"""
    if is_round_in_progress(game_id):
        return None

    update_player_options(game_id)

    player_order = RedisGetter.round_choices(game_id, 'new_order')
    player_order = player_order.split(',')
    current_player = player_order[0]

    # remove player from first choosing position if they've already made a choice
    choice_of_current_player = RedisGetter.round_choices(
        game_id, f'{current_player}_chosen')
    if choice_of_current_player:
        player_order.pop(0)

    # add player to end of choosing queue if they still have options available
    options_of_current_player = RedisGetter.round_choices(
        game_id, f'{current_player}_options')
    if not options_of_current_player:
        return None
    if options_of_current_player != 'chosen':
        if player_order:
            if player_order[-1] != current_player:
                player_order.append(current_player)
        else:
            # remove player's _options if player_order is empty
            RedisSetter.round_choices(game_id, f'{current_player}_options', '')
    else:
        # remove player from order if their _choices are chosen
        if current_player in player_order:
            player_order.remove(current_player)

    # save new revised order in redis db
    RedisSetter.round_choices(game_id, 'new_order', ','.join(player_order))

    return player_order
예제 #6
0
파일: db_utils.py 프로젝트: anjaist/tarok
def get_players_choices(game_id: int) -> dict:
    """returns dictionary containing choices made so far by players"""
    all_players = get_all_players(game_id)

    players_choice = {}
    for player_username in all_players:
        p_choice = RedisGetter.round_choices(game_id,
                                             f'{player_username}_chosen')
        if not p_choice:
            p_choice = 'čaka na izbiro'
        else:
            p_choice = TRANSLATION_GAME_TYPE[p_choice]
        players_choice[player_username] = p_choice

    return players_choice
예제 #7
0
파일: db_utils.py 프로젝트: anjaist/tarok
def update_order_of_players(game_id: str, new_first_player: str = None) -> str:
    """this method updates the order of players in the :current_round hash in redis.

    If new_first_player=None, it means that a round is currently in progress (there are cards on the table)
    and so the first player is simply removed from the order.

    If new_first_player='some player' it means that the table has been cleared and the first player is known.
    The other players are determined based on who comes after the known player
    in the original order found in the :round_choices hash.

    Returns the player whose turn it is next and updates the whose_turn entry in redis"""

    original_order = RedisGetter.round_choices(game_id, 'order')
    original_order = original_order.split(',')

    if new_first_player is None:
        order_in_redis = RedisGetter.current_round(game_id, 'order')
        new_order = order_in_redis.split(',')
        new_order.pop(0)
    else:
        if original_order.index(new_first_player) == 0:
            new_order = original_order
        elif original_order.index(new_first_player) == 1:
            new_order = [
                new_first_player, original_order[2], original_order[0]
            ]
        elif original_order.index(new_first_player) == 2:
            new_order = [
                new_first_player, original_order[0], original_order[1]
            ]
        else:
            raise RuntimeError(
                f'Error on trying to retrieve {new_first_player} from {original_order}.'
            )

    RedisSetter.current_round(game_id, 'order', ','.join(new_order))
    RedisSetter.current_round(game_id, 'whose_turn', new_order[0])

    return new_order[0]
예제 #8
0
def update_player_choosing():
    """handler for sending information of which player can choose again and what choices
    are available to them"""
    user = User.query.filter_by(id=session['user_id']).first()
    game_id = user.current_game
    player_order = get_players_that_need_to_choose_game(game_id)
    player_to_choose_game = None
    player_options = None
    if player_order:
        player_to_choose_game = player_order[0]
        player_options = RedisGetter.round_choices(
            game_id, f'{player_to_choose_game}_options')

    co_players_choice = get_players_choices(game_id)

    data_to_send = {
        'player': player_to_choose_game,
        'player_options': player_options,
        'co_players_choice': co_players_choice
    }

    print(f'[SENDING] player to choose: {data_to_send}')
    socketio.emit('player game options', data_to_send)
예제 #9
0
파일: db_utils.py 프로젝트: anjaist/tarok
def create_redis_entry_for_current_round(game_id: int,
                                         dealt_cards: dict,
                                         reset: bool = False):
    """creates new entry in redis db to start a new round. Saves the order of players and the state of the dealt cards.
    The redis key {game_id}:current_round should be reset once the round is complete (reset=True)"""
    # save order of players
    order = RedisGetter.round_choices(game_id, 'order')

    RedisSetter.current_round(game_id, 'order', order)
    RedisSetter.current_round(game_id, 'whose_turn', order.split(',')[0])
    RedisSetter.current_round(game_id, 'called', '')
    RedisSetter.current_round(game_id, 'on_table', '')
    RedisSetter.current_round(game_id, 'main_player_score_pile', '')
    RedisSetter.current_round(game_id, 'against_players_score_pile', '')

    # save dealt cards
    for user, value in dealt_cards.items():
        value_for_redis = ','.join(str(card_name) for card_name in value)
        RedisSetter.current_round(game_id, f'{user}_cards', value_for_redis)
        RedisSetter.current_round(game_id, f'{user}_played', '')

    if reset:
        redis_db.hdel(f'{game_id}:current_round', 'main_player')
        redis_db.hdel(f'{game_id}:current_round', 'type')
예제 #10
0
def play():
    """handler for main page of game"""
    update_user_in_game(session['user_id'], True)
    user = User.query.filter_by(id=session['user_id']).first()
    game_id = user.current_game
    co_players = get_co_players(game_id, session['user_id'])
    all_players = list(co_players.keys()) + [user.username]

    dealt_cards = get_dealt_cards(game_id, all_players)
    choose_order = get_players_that_need_to_choose_game(game_id)
    player_to_choose = None
    player_to_choose_opts = None
    if choose_order:
        player_to_choose = choose_order[0]
        player_to_choose_opts = RedisGetter.round_choices(
            game_id, f'{player_to_choose}_options')

    called = RedisGetter.current_round(game_id, 'called')
    whose_turn = RedisGetter.current_round(game_id, 'whose_turn')
    main_player = RedisGetter.current_round(game_id, 'main_player')
    game_type = RedisGetter.current_round(game_id, 'type')
    cards_on_table = RedisGetter.current_round(game_id, 'on_table')

    connect_handler()
    return render_template('play.html',
                           player=user.username,
                           co_players=co_players,
                           round_state=dealt_cards,
                           player_to_choose=player_to_choose,
                           player_to_choose_opts=player_to_choose_opts,
                           game_id=game_id,
                           called=called,
                           whose_turn=whose_turn,
                           main_player=main_player,
                           game_type=game_type,
                           on_table=cards_on_table)