예제 #1
0
 def test_cards_to_hand(self):
     hand = PSHandHistory.cards_to_hand('As Qd')
     self.assertEqual(hand, 'AQo')
     hand = PSHandHistory.cards_to_hand('2s 2d')
     self.assertEqual(hand, '22')
     hand = PSHandHistory.cards_to_hand('Js Qd')
     self.assertEqual(hand, 'QJo')
     hand = PSHandHistory.cards_to_hand('5s Qs')
     self.assertEqual(hand, 'Q5s')
     hand = PSHandHistory.cards_to_hand('Qs 5c')
     self.assertEqual(hand, 'Q5o')
예제 #2
0
def test_co_reg_filter():
    th = Path('cases/bb-not-reg.txt').read_text(encoding='utf-8')
    parsed = PSHandHistory(th)
    f = filters.CORegFilter()
    result = f(parsed, notes=notes, config=config)
    expected = False
    assert result == expected
예제 #3
0
def test_bu_fish_filter():
    th = Path('cases/bb-not-reg.txt').read_text(encoding='utf-8')
    parsed = PSHandHistory(th)
    f = filters.BUFishFilter()
    result = f(parsed, notes=notes, config=config)
    expected = True
    assert result == expected
예제 #4
0
def test_co_fish_filter():
    th = Path('cases/bb-not-reg.txt').read_text(encoding='utf-8')
    parsed = PSHandHistory(th)
    f = filters.COFishFilter()
    result = f(parsed, **{'notes': notes, 'config': config})
    expected = True
    assert result == expected
예제 #5
0
def get_calc_results(hand_text: str) -> CalcResults:
    parsed_hand = PSHandHistory(hand_text)
    hero = parsed_hand.hero
    prize = get_prize_structure(parsed_hand)
    icm = Icm(prize)
    try:
        ev_calc = EV(parsed_hand, icm)
        ev_calc.calc(hero)
        ai_equity = round(ev_calc.get_probs(hero), 4) * 100
        icm_ev_diff_cur = round(ev_calc.icm_ev_diff(), 2)
        icm_ev_diff = round(ev_calc.icm_ev_diff_pct(), 4) * 100
        chip_ev_diff = round(ev_calc.chip_diff_ev_adj(), 0)
        chip_won = ev_calc.chip_net_won().get(hero, 0)
        chip_won_adj = chip_ev_diff + chip_won
        won_amount = round(parsed_hand.prize_won.get(hero, 0), 2)
    except Exception as e:
        logger.exception(f"Exception", exc_info=sys.exc_info())
    rc = CalcResults(
        dt=parsed_hand.datetime,
        bi=parsed_hand.bi,
        hero_cards=parsed_hand.hero_cards,
        hero=parsed_hand.hero,
        h_id=parsed_hand.hid,
        prize=get_prize_structure(parsed_hand),
        ai_equity=ai_equity,
        icm_ev_diff_cur=icm_ev_diff_cur,
        icm_ev_diff=icm_ev_diff,
        chip_ev_diff=chip_ev_diff,
        chip_won=chip_won,
        chip_won_adj=chip_won_adj,
        won_amount=won_amount,
        t_id=parsed_hand.tid,
    )
    return rc
예제 #6
0
def test_wrong_condition_bi():
    hf = HandFilter()
    th = Path('cases/bb-not-reg.txt').read_text(encoding='utf-8')
    parsed = PSHandHistory(th)
    cond = Condition('xxbi', operator.gt, 14)
    hf.add_condition(cond, notes=notes, config=config)
    result = hf.check_conditions(parsed)
    expected = False
    assert result == expected
예제 #7
0
def test_condition_dt():
    hf = HandFilter()
    th = Path('cases/bb-not-reg.txt').read_text(encoding='utf-8')
    parsed = PSHandHistory(th)
    dt1 = datetime.datetime(2020, 4, 26, 13, 43)
    dt2 = datetime.datetime(2020, 4, 26, 13, 49)
    cond1 = Condition('datetime', operator.gt, dt1)
    cond2 = Condition('datetime', operator.lt, dt2)
    hf.add_condition(cond1)
    hf.add_condition(cond2)
    result = hf.check_conditions(parsed)
    expected = True
    assert result == expected
예제 #8
0
def test_hand_filter_match_3conditions():
    hf = HandFilter()
    th = Path('cases/bb-not-reg.txt').read_text(encoding='utf-8')
    parsed = PSHandHistory(th)
    f1 = filters.SBRegFilter()
    f2 = filters.BBFishFilter()
    f3 = filters.BUFishFilter()
    hf.add_condition(f1, notes=notes, config=config)
    hf.add_condition(f2, notes=notes, config=config)
    hf.add_condition(f3, notes=notes, config=config)
    result = hf.check_conditions(parsed)
    expected = True
    assert result == expected
예제 #9
0
def test_multi_condition_bi():
    hf = HandFilter()
    th = Path('cases/bb-not-reg.txt').read_text(encoding='utf-8')
    parsed = PSHandHistory(th)
    cond1 = Condition('bi', operator.gt, 14)
    cond2 = Condition('hero', operator.eq, "DiggErr555")
    cond3 = Condition('bi', operator.lt, 26)
    hf.add_condition(cond1, notes=notes, config=config)
    hf.add_condition(cond2, notes=notes, config=config)
    hf.add_condition(cond3, notes=notes, config=config)
    result = hf.check_conditions(parsed)
    expected = True
    assert result == expected
예제 #10
0
 def test__process_regexp(self):
     # TODO more tests on _process_regexp
     ACTIONS_AMOUNTS_REGEX = "(?P<player>.*?): (?:calls|raises.*to|bets|checks) (?P<amount>\d+)?"
     ACTIONS_AMOUNTS_DICT = {'player': 'amount'}
     parsed_hand = get_parsed_hand_from_file(
         "hh/sat16/round1/hu-ai-postflop.txt")
     hand_txt = parsed_hand.preflop_str
     print(hand_txt)
     res = PSHandHistory._process_regexp("",
                                         ACTIONS_AMOUNTS_REGEX,
                                         hand_txt,
                                         type_func=lambda x: int(x),
                                         reslist=True,
                                         **ACTIONS_AMOUNTS_DICT)
     self.assertDictEqual(res, {'NL_Classic': [50], 'Smdpair77': [0]})
예제 #11
0
    def sort(self, options):
        # this script filters hh of sats with 4 playrs tables, suits for 4max and for 3max

        # checking input and output directories
        try:
            input_path = get_path_dir_or_error(options.input_dir)
        except RuntimeError:
            self.statusBar().showMessage(
                'Place hand history files in "input" directory')
            return
        output_dir_path = get_path_dir_or_create(options.output_dir)

        storage = HandStorage(input_path)
        result = []
        total = len(list(storage.read_hand()))
        counter = 0
        skipped = 0

        hands_write_query = []
        self.progressBar.reset()
        self.progressBar.setRange(0, total)
        self.statusBar().showMessage('Sorting hands...')
        for txt in storage.read_hand():
            try:
                hh = PSHandHistory(txt)
            except Exception as e:
                self.statusBar().showMessage("%s " % e)
                continue

            counter += 1
            self.progressBar.setValue(counter)
            # TODO add filters
            # if not pass_filters(hh, options):
            #     continue
            try:
                pos_str = get_positions_str(hh)
            except RuntimeError:
                continue

            entry = HandWriteEntry(output_dir_path.joinpath(pos_str),
                                   hh.hid + '.txt', txt)
            hands_write_query.append(entry)

        self.progressBar.setValue(total)
        self.save_hands(hands_write_query)
        self.statusBar().showMessage(
            f'Total hands processed: {counter}, skipped: {skipped}')
예제 #12
0
def get_dt_from_hh(hh: str):
    """returns (dd, mm, yy) from hand history file"""
    s = hh.split('\n\n')
    # determine date and time by first hand in tournament
    hh = None
    dt = datetime.now()
    for text in s:
        try:
            # if None or empty string take next element
            if not bool(text and text.strip()):
                continue
            # print(f'text: {text}')
            hh = PSHandHistory(text)
            dt = hh.datetime
            break
        except Exception as e:
            logger.exception('hand id: %s, tournament id: %s', hh.hid, hh.tid)

    return dt
예제 #13
0
 def process_hands(self,
                   hands,
                   file,
                   notes,
                   options,
                   hand_filter,
                   path,
                   hands_write_query,
                   by_position=False):
     new_path = Path(path)
     for txt in hands:
         if bool(txt and txt.strip()):
             pos_str = '0'
             try:
                 parsed = PSHandHistory(txt)
                 dd, mm, yy = get_ddmmyy_from_dt(parsed.datetime)
             except Exception as e:
                 logger.exception('Exception %s while parsing file: %s', e,
                                  file)
                 logger.debug("hid: " + str(parsed.hid))
                 logger.debug("hh: " + parsed.hand_history)
                 continue
             if hand_filter.check_conditions(parsed,
                                             notes=notes,
                                             config=options):
                 if by_position:
                     try:
                         pos_str = get_positions_str(parsed)
                         new_path = path.joinpath(pos_str)
                     except (RuntimeError, KeyError) as e:
                         logger.exception(
                             'Exception %s in get_position_str in file: %s',
                             e, file)
                         continue
                 self.append_write_entry(new_path, yy, mm, dd, parsed, txt,
                                         hands_write_query)
예제 #14
0
def get_parsed_hand_from_file(fn):
    with open(fn) as f:
        hh_text = f.read()
        parsed_hand = PSHandHistory(hh_text)
        return parsed_hand
예제 #15
0
 def setUp(self):
     self.case0 = PSHandHistory(th)
     # self.case1 = PSHandHistory(th1)
     self.case2 = PSHandHistory(th2)
     # self.case3 = PSHandHistory(th3)
     self.case4 = PSHandHistory(th4)
     self.case5 = PSHandHistory(th5)
     self.case6 = PSHandHistory(th6)
     self.case7 = PSHandHistory(th7)
     self.case8 = PSHandHistory(th8)
     self.case9 = PSHandHistory(th9)  #2 bounty won case
     self.case10 = PSHandHistory(th10)  #3 bounty won case
     self.auto_ai_case = PSHandHistory(auto_ai_th)
     self.case11 = PSHandHistory(debug_hrcparser)
예제 #16
0
def main():
    logging.basicConfig(
        format='[%(asctime)s] %(levelname).1s %(message)s',
        datefmt='%Y.%m.%d %H:%M:%S',
        level=logging.INFO
    )

    args = parse_arguments()
    load_config(config, args.config)
    logging.info('Start...')
    notes = load_ps_notes(config['NOTES_FILE'])
    logging.info('Player notes loaded...')
    hero = config['HERO']
    storage = hand_storage.HandStoragePgsql(dbname='nolim 2.3.0 04-12-2017',
                                            user='******',
                                            host='127.0.0.1',
                                            port='5318',
                                            pwd='')

    # storage = hand_storage.HandStorage('hands/debug')
    results_icm = {}
    results_bounty = {}
    tournaments = {}
    finishes = {}
    logging.info('Selecting hands...')
    for hand in storage.read_hand(start_date=config['START_DATE'], end_date=config['END_DATE']):
    # for hand in storage.read_hand():
        try:
            hh = PSHandHistory(hand)

        except Exception as e:
            logging.info(hh)
            logging.info(e)
            continue
        if hh.hero != hero:
            continue
        if hh.bi not in (10.0, 25.0, 5.0, 100.0, 50.0):
            continue
        if tournaments.get(hh.tid) is None:
            # if len(hh.players) == 6:
            tournaments[hh.tid] = [[hh.bi, hh.datetime, fish_per_table(hh.players, notes), hh.bounty]]
            results_icm[hh.tid] = -hh.bi + hh.prize_won.get(hero, 0)
            results_bounty[hh.tid] = hh.bounty_won.get(hero, 0)
        else:
            tournaments[hh.tid].append([hh.bi, hh.datetime, fish_per_table(hh.players, notes), hh.bounty])
            results_icm[hh.tid] += hh.prize_won.get(hero, 0)
            results_bounty[hh.tid] += hh.bounty_won.get(hero, 0)

        if hh.finishes.get(hero):
            finishes[hh.tid] = hh.finishes.get(hero)

        # logging.info(f'{results_bounty[hh.tid]} {hh.hid} {hh.datetime}')

    logging.info('Calculating statistics')
    results = []
    for tour, value in tournaments.items():
        if finishes.get(tour) is None:
            ts_text = storage.read_summary(tour)
            if ts_text:
                ts = PSTournamentSummary(ts_text)
                finishes[tour] = ts.finishes
                results_icm[tour] += ts.prize_won.get(hero, 0)
                if ts.finishes == 1:
                    logging.info(results_bounty[tour])
                    results_bounty[tour] += value[0][3] * 2

        results.append([tour,
                        value[0][0],
                        min([_[1] for _ in value]),
                        max([_[2] for _ in value]),
                        results_icm[tour],
                        results_bounty[tour],
                        results_icm[tour] + results_bounty[tour],
                        finishes.get(tour, 0),
                        len(value)
                       ])

    if results:
        logging.info('Saving results...')
        df = pd.DataFrame(results)
        columns = ['tid', 'bi', 'date', 'fish', 'prize_won', 'bounty_won', 'total_won', 'finishes', 'hands']
        df.to_csv(f'results {config["START_DATE"]} {config["END_DATE"]}.csv', header=columns)
        logging.info('Success')
    else:
        logging.info('No tournament results found!')
예제 #17
0
def sort_by_tournament_position(options):
    # this script filters hh of sats with 4 playrs tables, suits for 4max and for 3max
    try:
        storage = HandStorage(options.input_dir)
    except IOError:
        logging.exception('Invalid input dir')
        try:
            storage = HandStorage(CWD.joinpath(DEFAULT_INPIT_DIR))
        except IOError:
            logging.exception('Default input dir doesnt exists')
            return

    output_dir_path = get_path_dir_or_create(options.output_dir)

    result = []
    pos_codes = set()
    total = len(list(storage.read_hand()))
    counter = 0
    logging.info('Sorting hands...')
    printProgressBar(counter, total)
    for txt in storage.read_hand():
        try:
            hh = PSHandHistory(txt)
        except Exception as e:
            logging.exception("%s " % e)
            continue

        counter += 1
        printProgressBar(counter, total)
        if not pass_filters(hh, options):
            continue

        positions = hh.positions()
        player_pos = {
            pos: hh.tournamentPosition(player)
            for player, pos in positions.items()
        }
        # for now only for 4 and 3 max
        if hh.players_number() == 4:
            pos_str = str(player_pos['CO']) + str(player_pos['BU']) + str(
                player_pos['SB']) + str(player_pos['BB'])
        elif hh.players_number() == 3:
            pos_str = str(player_pos['BU']) + str(player_pos['SB']) + str(
                player_pos['BB'])
        else:
            continue
        # for ex. "1234" if CO has 1 stack BU 2 stack SB -3 BB -4
        pos_codes.add(pos_str)
        result_row = {'pos_code': pos_str, 'txt': txt, 'fn': hh.hid}
        result.append(result_row)
    # create all possible output directories from pos_codes
    for pos_code in pos_codes:
        pos_code_dir_path = output_dir_path.joinpath(pos_code)
        if not pos_code_dir_path.exists():
            pos_code_dir_path.mkdir()

    counter = 0
    total = len(result)
    logging.info('Saving results...')
    printProgressBar(counter, total)
    for row in result:
        res_dir_path = output_dir_path.joinpath(row['pos_code'])
        res_file_path = res_dir_path.joinpath(row['fn']).with_suffix('.txt')
        res_file_path.write_text(row['txt'], encoding='utf-8')
        counter += 1
        printProgressBar(counter, total)