def gen_dealt_hands_and_add_to_db(
        n_games,
        table=GameC.CHINESE_POKER_db_consts['dealt_hands_table'],
        write_every=1000):

    conn = DBF.connect_to_db()
    cursor = conn.cursor()
    start = timer()
    to_be_inserted = []
    base_query = f'INSERT INTO {table} (DealtHandsStr) VALUES '
    for i in range(1, n_games + 1):
        dealt_cards = deck_obj.deal_cards()
        dealt_cards_str = _convert_dealt_cards_to_rep_str(dealt_cards)
        to_be_inserted.append(dealt_cards_str)
        if i % write_every == 0:
            query = base_query
            for dealt_cards_str in to_be_inserted:
                query += f'({dealt_cards_str}),'
            #insert_query = """INSERT INTO random_dealt_hands (DealtHandsStr) VALUES (%s)"""
            #cursor.executemany(insert_query, to_be_inserted)
            query = query[:-1]
            cursor.execute(query)
            conn.commit()
            min_elapsed = (timer() - start) / 60
            print(
                f'Inserted {i} of {n_games} DealtHandsStr rows into {table} - {min_elapsed} min elasped.'
            )
            to_be_inserted = []
    return
Beispiel #2
0
def update_CPT_round_row_with_com_split(app_round_ID, com_id, seq_no):
    #split_inds_str = DF._convert_card_inds_to_set_inds_str(split_inds)

    query = f"UPDATE {CPT_rounds_table} SET Com{com_id}SplitSeqNo = {seq_no} WHERE RoundID = {app_round_ID}"
    #print(query)
    _ = DBF.insert_query(query, None, False, False)
    return
Beispiel #3
0
    def yield_dealt_hands_from_db(
        self,
        start_game_no,
        end_game_no,
        db_connector=None,
        db_load_batch_size=1000,
        cards_as_str=False,
    ):
        dealt_hands_table = GameC.CHINESE_POKER_db_consts["dealt_hands_table"]
        base_query = f'SELECT GameID, DealtHandsStr FROM {dealt_hands_table} WHERE GameID BETWEEN %s AND %s'
        deck_obj = self.deck

        if start_game_no is None:
            start_game_no = 1

        temp_start_game_no = start_game_no

        while 1:
            temp_end_game_no = min(end_game_no,
                                   temp_start_game_no + db_load_batch_size - 1)
            query = base_query % (temp_start_game_no, temp_end_game_no)

            db_output, _ = DBF.select_query(query)
            for row in db_output:
                dealt_cards = self._convert_rep_str_to_dealt_cards(
                    row[1], deck_obj)
                if cards_as_str:
                    dealt_cards = [[str(card) for card in hand]
                                   for hand in hands]
                yield row[0], dealt_cards
            if temp_end_game_no >= end_game_no:
                break

            temp_start_game_no += db_load_batch_size
        yield None, None
Beispiel #4
0
def create_CPT_game_row(clientIP, com_difficulties):
    query = f"INSERT INTO {CPT_game_table} (ClientIP, Com1Difficulty, Com2Difficulty, Com3Difficulty, StartTimeUTC) VALUES ('%s', %s, %s, %s, '%s')"
    cur_datetime = datetime.utcnow().strftime(GConst.SQL_DATETIME_FORMAT)
    query = query % (clientIP, com_difficulties[0], com_difficulties[1],
                     com_difficulties[2], cur_datetime)
    print(query)
    _, app_game_ID = DBF.insert_query(query, None, False, True)
    return app_game_ID
Beispiel #5
0
def gen_leaderboard(show_top_n_scores=10, cur_app_game_ID=None):
    query = f"SELECT AppGameID, Name, Com1Difficulty+Com2Difficulty+Com3Difficulty AS TotComDifficulty, NoRounds, TotScore, TotCptScore, CAST(EndTimeUTC AS DATE) AS GameDate FROM {CPT_game_table} WHERE InLeaderboard=1 ORDER BY (TotScore-TotCptScore)/NoRounds DESC, (Com1Difficulty+Com2Difficulty+Com3Difficulty) DESC, NoRounds DESC, EndTimeUTC ASC LIMIT {show_top_n_scores}"
    output, _ = DBF.select_query(query)

    processed_output = []

    for row_i, row in enumerate(output):
        is_user = 0
        if row[0] == cur_app_game_ID:
            is_user = 1
        print(row)
        row_data = [
            row_i + 1,  # Rank
            row[1],  # Name
            row[2],  # TotCompDifficulty
            row[3],  # NoRounds
            row[4],  # TotScore
            row[5],  # TotCPTScore
            row[6].strftime('%Y/%m/%d'),  # GameDate
            is_user,  # IsUser
        ]
        processed_output.append(row_data)

    if cur_app_game_ID:
        if sum([row[-1] for row in processed_output]) == 0:
            query = f"SELECT AppGameID, Name, Com1Difficulty+Com2Difficulty+Com3Difficulty AS TotComDifficulty, NoRounds, TotScore, TotCptScore, CAST(EndTimeUTC AS DATE) AS GameDate FROM {CPT_game_table} WHERE AppGameID={cur_app_game_ID} AND InLeaderboard=1"
            output, _ = DBF.select_query(query)
            if output:
                row_data = [
                    None,  # Rank
                    output[0][1],  # Name
                    output[0][2],  # TotCompDifficulty
                    output[0][3],  # NoRounds
                    output[0][4],  # TotScore
                    output[0][5],  # TotCPTScore
                    output[0][6].strftime('%Y/%m/%d'),  # GameDate
                    1,  # IsUser
                ]
                processed_output.append(row_data)
            #query = f"SELECT AppGameID, Name, Com1Difficulty+Com2Difficulty+Com3Difficulty AS TotComDifficulty, NoRounds, TotScore, TotCptScore, CAST(EndTimeUTC AS DATE) AS GameDate FROM {CPT_game_table} WHERE InLeaderboard=1 WHERE AppGameID={cur_app_game_ID}"

    # Fetch the rank of the cur_app_game_ID
    # If cur_app_game_ID not in the output, then run a separate query

    return processed_output
Beispiel #6
0
def create_CPT_round_row(app_game_ID, app_round_no, hand_game_ID,
                         hand_seat_ID):
    query = f"INSERT INTO {CPT_rounds_table} (AppGameID, RoundNo, HandGameID, HandSeatID, StartTimeUTC) VALUES (%s, %s, %s, %s, '%s')"
    cur_datetime = datetime.utcnow().strftime(GConst.SQL_DATETIME_FORMAT)
    query = query % (app_game_ID, app_round_no, hand_game_ID, hand_seat_ID,
                     cur_datetime)
    #print(query)
    _, app_round_ID = DBF.insert_query(query, None, False, True)
    return app_round_ID
Beispiel #7
0
    def max_game_id_in_splits_table(cls):
        splits_table = GameC.CHINESE_POKER_db_consts['splits_table']
        query = f'SELECT MAX(GameID) FROM {splits_table}'
        db_output, _ = DBF.select_query(query)

        return db_output[0][0]

    ######################################
    ### END Useful query functions END ###
    ######################################
def number_of_feasible_splits_for_game_and_seat(game_id, seat_id):

    splits_table = GameC.CHINESE_POKER_db_consts['splits_table']
    query = f'SELECT Max(SplitSeqNo) FROM {splits_table} WHERE GameID={game_id} AND SeatID={seat_id}'
    db_output, _ = DBF.select_query(query)

    return db_output[0][0]


######################################
### END Useful query functions END ###
######################################
def yield_dealt_hands_from_db(
    start_game_no,
    end_game_no,
    db_connector=None,
    db_load_batch_size=1000,
    cards_as_str=False,
):
    """Generator that yields dealt cards from DB one game at a time for a range of GameIDs.

  Args:
      start_game_no (int): Start game number.
      end_game_no (int): End game number.
      db_connector ([type], optional): [description]. Defaults to None.
      db_load_batch_size (int, optional): [description]. Defaults to 1000.
      cards_as_str (bool, optional): Return cards as string rather then Card objects. Defaults to False.

  Yields:
      [type]: [description]
  """
    dealt_hands_table = GameC.CHINESE_POKER_db_consts["dealt_hands_table"]
    base_query = f'SELECT GameID, DealtHandsStr FROM {dealt_hands_table} WHERE GameID BETWEEN %s AND %s'

    if start_game_no is None:
        start_game_no = 1

    temp_start_game_no = start_game_no

    while 1:
        temp_end_game_no = min(end_game_no,
                               temp_start_game_no + db_load_batch_size - 1)
        query = base_query % (temp_start_game_no, temp_end_game_no)

        db_output, _ = DBF.select_query(query)
        for row in db_output:
            dealt_cards = _convert_rep_str_to_dealt_cards(row[1])
            if cards_as_str:
                dealt_cards = [[str(card) for card in hand]
                               for hand in dealt_cards]
            yield row[0], dealt_cards
        if temp_end_game_no >= end_game_no:
            break

        temp_start_game_no += db_load_batch_size
    yield None, None
def _get_split(game_id, seat_id, split_seq_no):
    splits_table = GameC.CHINESE_POKER_db_consts['splits_table']
    query = f'SELECT SplitStr FROM {splits_table} WHERE GameID={game_id} AND SeatID={seat_id} AND SplitSeqNo={split_seq_no}'
    db_output, _ = DBF.select_query(query)
    return db_output[0][0]
Beispiel #11
0
def update_CPT_round_row_with_player_split_as_com_100(app_round_ID, seq_no):
    query = f"UPDATE {CPT_rounds_table} SET PlayerSplitSeqNoCom100 = {seq_no} WHERE RoundID = {app_round_ID}"
    #print(query)
    _ = DBF.insert_query(query, None, False, False)
    return
def get_splits_data_for_single_game_and_seat_from_db(
    game_id,
    seat_id,
    cards=None,
):
    """[summary]

  Args:
      game_id (int): GameID
      seat_id (int): Between 1 and 4
      cards (List): List of Card objects or card strings. 
  """

    if cards is None:
        hands = next(yield_dealt_hands_from_db(game_id, game_id))[1]
        cards = hands[seat_id - 1]
    elif isinstance(cards[0], str):
        deck = Deck()
        cards = deck.deal_custom_hand(cards)

    splits_table = GameC.CHINESE_POKER_db_consts['splits_table']
    codes_table = GameC.CHINESE_POKER_db_consts['split_codes_table']
    query = f'SELECT SplitSeqNo, SplitStr, + ' \
            f'c1.L1Code AS S1L1Code, c1.L2Code AS S1L2Code, c1.L3Code AS S1L3Code, c1.L4Code AS S1L4Code, c1.L5Code AS S1L5Code, c1.L6Code AS S1L6Code, ' + \
            f'c2.L1Code AS S2L1Code, c2.L2Code AS S2L2Code, c2.L3Code AS S2L3Code, c2.L4Code AS S2L4Code, c2.L5Code AS S2L5Code, c2.L6Code AS S2L6Code, ' + \
            f'c3.L1Code AS S3L1Code, c3.L2Code AS S3L2Code, c3.L3Code AS S3L3Code, c3.L4Code AS S3L4Code, c3.L5Code AS S3L5Code, c3.L6Code AS S3L6Code ' + \
            f'FROM {splits_table} s ' + \
            f'JOIN {codes_table} c1 ON s.SplitID=c1.SplitID ' + \
            f'JOIN {codes_table} c2 ON s.SplitID=c2.SplitID ' + \
            f'JOIN {codes_table} c3 ON s.SplitID=c3.SplitID ' + \
            f'WHERE s.GameID={game_id} AND s.SeatID={seat_id} ' + \
            f'AND c1.SetNo=1 AND c2.SetNo=2 AND c3.SetNo=3'
    db_output, _ = DBF.select_query(query)
    hand_splits = []
    for row in db_output:
        split_seq_no, split_str, s1c1, s1c2, s1c3, s1c4, s1c5, s1c6, s2c1, s2c2, s2c3, s2c4, s2c5, s2c6, s3c1, s3c2, s3c3, s3c4, s3c5, s3c6 = row

        split_cards, split_inds = _convert_split_str_to_split_cards(
            cards, split_str)
        s1code = [s1c1, s1c2, s1c3, s1c4, s1c5, s1c6]
        s2code = [s2c1, s2c2, s2c3, s2c4, s2c5, s2c6]
        s3code = [s3c1, s3c2, s3c3, s3c4, s3c5, s3c6]

        s1code = CardGroupCode([code for code in s1code if code is not None])
        s2code = CardGroupCode([code for code in s2code if code is not None])
        s3code = CardGroupCode([code for code in s3code if code is not None])

        split_info_factory = ChinesePokerStrategy.ranked_split_info_factory

        split_info = split_info_factory(
            split_inds,
            split_cards,
            (s1code, s2code, s3code),
            None,
            None,
            None,
            None,
            None,
            split_seq_no,
        )
        hand_splits.append(split_info)

    hand_splits = sorted(hand_splits, key=lambda x: x.SeqNo)
    return hand_splits
def write_splits_data_to_db(game_id, splits_data):
    """Function for writing splits data generated by 
  yield_splits_from_dealt_hands to db.
  
  Writes to: feasible_hand_splits - GameID, SeatID, SplitSeqNo, SplitStr, DateGen
             split_set_codes - SplitID, SeatID, SetNo, L1Code, L2Code, L3Code, L4Code, L5Code, L6Code

  Args:
      game_id (int): Game ID - Should match what is in
                                random_dealt_hands
      splits_data ([type]): Dict with following structure:
        ('P{PLAYERNO}':player_splits_data) where PLAYERNO between 1 and 4 inclusive
        player_splits_data itself is a dict with the following structure:
          'DealtCards': Dealt cards in original order
          'CardInds': List of indices lists.
                      Each outer list corresponds to a possible split.
                      The indices refer to the indices of the DealtCards list. 
                      The order combined with the split_into attribute of the strategy object infers the split card sets.
          'Codes': List of list of tuples.
                    Each outer list corresponds to a possible split.
                    Each inner list consists of tuples representing the card group codes of the sets.
          'Scores': List of score lists.
                    Each outer list corresponds to a possible split.
                    Each inner list contains the set scores.  
          'WeightedScores': List of weighted scores.
                            One score for each possible split.    
          'SplitIndsStrs': List of strings, each of length 13, the characters correspond to the dealt cards.
                            Each string corresponds to a possible split.
                            The characters refer to the set number where each card is split into.
                            E.g. '1112222233333' means the first 3 cards (of DealtCards) are in the first set, 
                              the next 5 cards are in the second set and the last 5 cards are in the third set. 
  """

    date_gen = datetime.today().strftime('%Y-%m-%d')
    splits_table = GameC.CHINESE_POKER_db_consts['splits_table']

    codes_table = GameC.CHINESE_POKER_db_consts['split_codes_table']

    db_connector = DBF.connect_to_db()
    # First check that there are no existing splits in the DB. If there are, delete them.
    check_query = f"SELECT COUNT(*) FROM {splits_table} WHERE GameID={game_id} AND DateGenerated ='{date_gen}'"
    db_output, db_connector = DBF.select_query(check_query, db_connector)
    if db_output[0][0] > 0:
        delete_query = f"DELETE FROM {splits_table} WHERE GameID={game_id} AND DataGenerated='{date_gen}'"
        db_connector, rows_deleted = DBF.delete_query(delete_query,
                                                      db_connector)
        print(
            f'***Deleted {rows_deleted} rows with identical GameID ({game_id}) and DateGenerated ({date_gen}).***'
        )

    for seat_ID in range(1, 5):

        player_splits_data = splits_data[f'P{seat_ID}']
        #n_splits = len(player_splits_data['SplitIndsStrs']
        for seqI, split_str in enumerate(player_splits_data['SplitIndsStrs']):
            splits_query = f'INSERT INTO {splits_table} (GameID, SeatID, SplitSeqNo, SplitStr, DateGenerated) VALUES (%s, %s, %s, %s, %s)'
            splits_query = splits_query % (game_id, seat_ID, seqI + 1,
                                           split_str, f"'{date_gen}'")

            db_connector, split_id = DBF.insert_query(splits_query,
                                                      db_connector, False,
                                                      True)

            base_codes_query = f'INSERT INTO {codes_table} ' + \
                                '(SplitID, SetNo, L1Code, L2Code, L3Code, L4Code, L5Code, L6Code) VALUES ' + \
                                '(%s, %s, %s, %s, %s, %s, %s, %s)'

            values_list = []
            for setI, set_code in enumerate(player_splits_data['Codes'][seqI]):
                base_val = [None for i in range(8)]
                base_val[0] = split_id
                base_val[1] = setI + 1
                for levelI, level_code in enumerate(set_code):
                    base_val[2 + levelI] = level_code
                values_list.append(tuple(base_val))

            db_connector = DBF.insert_many_query(base_codes_query, values_list,
                                                 db_connector, True)

            db_connector = DBF.try_commit(db_connector)

    return
Beispiel #14
0
    def yield_splits_data_from_db(
        self,
        start_game_id=None,
        end_game_id=None,
    ):

        #db_connector = DBF.connect_to_db()
        splits_table = GameC.CHINESE_POKER_db_consts['splits_table']
        codes_table = GameC.CHINESE_POKER_db_consts['split_codes_table']
        base_query = f'SELECT SplitSeqNo, SplitStr, + ' \
                     f'c1.L1Code AS S1L1Code, c1.L2Code AS S1L2Code, c1.L3Code AS S1L3Code, c1.L4Code AS S1L4Code, c1.L5Code AS S1L5Code, c1.L6Code AS S1L6Code, ' + \
                     f'c2.L1Code AS S2L1Code, c2.L2Code AS S2L2Code, c2.L3Code AS S2L3Code, c2.L4Code AS S2L4Code, c2.L5Code AS S2L5Code, c2.L6Code AS S2L6Code, ' + \
                     f'c3.L1Code AS S3L1Code, c3.L2Code AS S3L2Code, c3.L3Code AS S3L3Code, c3.L4Code AS S3L4Code, c3.L5Code AS S3L5Code, c3.L6Code AS S3L6Code ' + \
                     f'FROM {splits_table} s ' + \
                     f'JOIN {codes_table} c1 ON s.SplitID=c1.SplitID ' + \
                     f'JOIN {codes_table} c2 ON s.SplitID=c2.SplitID ' + \
                     f'JOIN {codes_table} c3 ON s.SplitID=c3.SplitID ' + \
                     f'WHERE s.GameID=%s AND s.SeatID=%s ' + \
                     f'AND c1.SetNo=1 AND c2.SetNo=2 AND c3.SetNo=3'
        for game_id in range(start_game_id, end_game_id + 1):
            hands = next(self.yield_dealt_hands_from_db(game_id, game_id))[1]
            game_splits = []

            for seat_id in range(1, 5):
                query = base_query % (game_id, seat_id)
                cards = hands[seat_id - 1]
                db_output, _ = DBF.select_query(query)

                hand_splits = []
                for row in db_output:
                    split_seq_no, split_str, s1c1, s1c2, s1c3, s1c4, s1c5, s1c6, s2c1, s2c2, s2c3, s2c4, s2c5, s2c6, s3c1, s3c2, s3c3, s3c4, s3c5, s3c6 = row

                    split_cards = self._convert_split_str_to_split_cards(
                        cards, split_str)
                    s1code = [s1c1, s1c2, s1c3, s1c4, s1c5, s1c6]
                    s2code = [s2c1, s2c2, s2c3, s2c4, s2c5, s2c6]
                    s3code = [s3c1, s3c2, s3c3, s3c4, s3c5, s3c6]

                    s1code = CardGroupCode(
                        [code for code in s1code if code is not None])
                    s2code = CardGroupCode(
                        [code for code in s2code if code is not None])
                    s3code = CardGroupCode(
                        [code for code in s3code if code is not None])

                    split_info_factory = ChinesePokerStrategy.ranked_split_info_factory

                    split_info = split_info_factory(
                        None,
                        split_cards,
                        (s1code, s2code, s3code),
                        None,
                        None,
                        None,
                        None,
                        None,
                        split_seq_no,
                    )
                    hand_splits.append(split_info)

                game_splits.append(hand_splits)

            yield game_id, game_splits

            # TODO Convert each row to RankedSplitInfo named tuple
            # (Inds, Cards, Codes, )
        return
Beispiel #15
0
def update_CPT_submit_score(app_game_ID, name, email=None):
    query = f"UPDATE {CPT_game_table} SET Name='{name}', Email='{email}', InLeaderboard=1 WHERE AppGameID={app_game_ID}"
    _ = DBF.insert_query(query, None, False, False)
    return
Beispiel #16
0
def end_of_game_CPT_game_row_update(app_game_ID, n_rounds, tot_score,
                                    tot_CPT_score):
    cur_datetime = datetime.utcnow().strftime(GConst.SQL_DATETIME_FORMAT)
    query = f"UPDATE {CPT_game_table} SET NoRounds={n_rounds}, TotScore={tot_score}, TotCptScore={tot_CPT_score}, EndTimeUTC='{cur_datetime}' WHERE AppGameID={app_game_ID}"
    _ = DBF.insert_query(query, None, False, False)
    return
Beispiel #17
0
def update_CPT_round_row_with_game_scores(app_round_ID, game_scores,
                                          player_score_com_100):
    cur_datetime = datetime.utcnow().strftime(GConst.SQL_DATETIME_FORMAT)
    query = f"UPDATE {CPT_rounds_table} SET PlayerScore = {game_scores[0]}, Com1Score = {game_scores[1]}, Com2Score = {game_scores[2]}, Com3Score = {game_scores[3]}, PlayerScoreCom100 = {player_score_com_100}, EndTimeUTC = '{cur_datetime}' WHERE RoundID = {app_round_ID}"
    _ = DBF.insert_query(query, None, False, False)
    return
Beispiel #18
0
def update_CPT_round_row_with_player_split(app_round_ID, split_inds):
    split_str = DF._convert_card_inds_to_set_inds_str(split_inds)
    query = f"UPDATE {CPT_rounds_table} SET PlayerSplitInds = {split_str} WHERE RoundID = {app_round_ID}"
    #print(query)
    _ = DBF.insert_query(query, None, False, False)
    return