Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
*.pyc
.idea
.venv
build/
dist/
*.egg-info/
Empty file added holdem_calc/__init__.py
Empty file.
64 changes: 26 additions & 38 deletions holdem_argparser.py → holdem_calc/holdem_argparser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import argparse
import re
import holdem_functions
from holdem_calc import holdem_functions


# Wrapper class which holds the arguments for library calls
Expand All @@ -13,6 +13,7 @@ def __init__(self, board, exact, num, input_file, hole_cards):
self.input = input_file
self.exact = exact


# Parses arguments passed to holdem_calc as a library call
def parse_lib_args(args):
error_check_arguments(args)
Expand All @@ -22,25 +23,26 @@ def parse_lib_args(args):
hole_cards, board = parse_cards(args.cards, args.board)
return hole_cards, args.n, args.exact, board, args.input


# Parses command line arguments to holdem_calc
def parse_args():
# Define possible command line arguments
parser = argparse.ArgumentParser(
description="Find the odds that a Texas Hold'em hand will win. Note "
"that cards must be given in the following format: As, Jc, Td, 3h.")
"that cards must be given in the following format: As, Jc, Td, 3h.")
parser.add_argument("cards", nargs="*", type=str, metavar="hole card",
help="Hole cards you want to find the odds for.")
parser.add_argument("-b", "--board", nargs="*", type=str, metavar="card",
help="Add board cards")
parser.add_argument("-e", "--exact", action="store_true",
help="Find exact odds by enumerating every possible "
"board")
"board")
parser.add_argument("-n", type=int, default=100000,
help="Run N Monte Carlo simulations")
parser.add_argument("-i", "--input", type=str,
help="Read hole cards and boards from an input file. "
"Commandline arguments for hole cards and board will "
"be ignored")
"Commandline arguments for hole cards and board will "
"be ignored")
# Parse command line arguments and check for errors
args = parser.parse_args()
error_check_arguments(args)
Expand All @@ -50,16 +52,17 @@ def parse_args():
hole_cards, board = parse_cards(args.cards, args.board)
return hole_cards, args.n, args.exact, board, args.input


# Parses a line taken from the input file and returns the hole cards and board
def parse_file_args(line):
if line is None or len(line) == 0:
print line
print "Invalid format"
print(line)
print("Invalid format")
exit()
values = line.split("|")
if len(values) > 2 or len(values) < 1:
print line
print "Invalid format"
print(line)
print("Invalid format")
exit()
hole_cards = values[0].split()
all_cards = list(hole_cards)
Expand All @@ -70,39 +73,20 @@ def parse_file_args(line):
error_check_cards(all_cards)
return parse_cards(hole_cards, board)


# Parses hole cards and board
def parse_cards(cards, board):
hole_cards = create_hole_cards(cards)
if board:
board = parse_board(board)
return hole_cards, board

# Error check the command line arguments
def error_check_arguments(args):
# Check that the number of Monte Carlo simulations is a positive number
if args.n <= 0:
print "Number of Monte Carlo simulations must be positive."
exit()
# Check that we can open the specified input file
if args.input:
file_name = args.input
try:
input_file = open(file_name, 'r')
input_file.close()
except IOError:
print "Error opening file " + file_name
exit()
# Check to make sure all cards are of a valid format
all_cards = list(args.cards)
if args.board:
all_cards.extend(args.board)
error_check_cards(all_cards)

# Error check the command line arguments
def error_check_arguments(args):
# Check that the number of Monte Carlo simulations is a positive number
if args.n <= 0:
print "Number of Monte Carlo simulations must be positive."
print("Number of Monte Carlo simulations must be positive.")
exit()
# Check that we can open the specified input file
if args.input:
Expand All @@ -111,32 +95,34 @@ def error_check_arguments(args):
input_file = open(file_name, 'r')
input_file.close()
except IOError:
print "Error opening file " + file_name
print("Error opening file " + file_name)
exit()
# Check to make sure all cards are of a valid format
all_cards = list(args.cards)
if args.board:
all_cards.extend(args.board)
error_check_cards(all_cards)


# Checking that the hole cards + board are formatted properly and unique
def error_check_cards(all_cards):
card_re = re.compile('[AKQJT98765432][scdh]')
for card in all_cards:
if card != "?" and not card_re.match(card):
print "Invalid card given."
print("Invalid card given.")
exit()
else:
if all_cards.count(card) != 1 and card != "?":
print "The cards given must be unique."
print("The cards given must be unique.")
exit()


# Returns tuple of two-tuple hole_cards: e.g. ((As, Ks), (Ad, Kd), (Jh, Th))
def create_hole_cards(raw_hole_cards):
# Checking that there are an even number of hole cards
if (raw_hole_cards is None or len(raw_hole_cards) < 2 or
len(raw_hole_cards) % 2):
print "You must provide a non-zero even number of hole cards"
print("You must provide a non-zero even number of hole cards")
exit()
# Create two-tuples out of hole cards
hole_cards, current_hole_cards = [], []
Expand All @@ -150,24 +136,26 @@ def create_hole_cards(raw_hole_cards):
if None in current_hole_cards:
if (current_hole_cards[0] is not None or
current_hole_cards[1] is not None):
print "Unknown hole cards must come in pairs"
print("Unknown hole cards must come in pairs")
exit()
hole_cards.append((current_hole_cards[0], current_hole_cards[1]))
current_hole_cards = []
if hole_cards.count((None, None)) > 1:
print "Can only have one set of unknown hole cards"
print("Can only have one set of unknown hole cards")
return tuple(hole_cards)


# Returns list of board cards: e.g. [As Ks Ad Kd]
def parse_board(board):
if len(board) > 5 or len(board) < 3:
print "Board must have a length of 3, 4, or 5."
print("Board must have a length of 3, 4, or 5.")
exit()
if "?" in board:
print "Board cannot have unknown cards"
print("Board cannot have unknown cards")
exit()
return create_cards(board)


# Instantiates new cards from the arguments and returns them in a tuple
def create_cards(card_strings):
return [holdem_functions.Card(arg) for arg in card_strings]
13 changes: 8 additions & 5 deletions holdem_calc.py → holdem_calc/holdem_calc.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import time
import holdem_functions
import holdem_argparser
from holdem_calc import holdem_functions, holdem_argparser


def main():
hole_cards, num, exact, board, file_name = holdem_argparser.parse_args()
run(hole_cards, num, exact, board, file_name, True)


def calculate(board, exact, num, input_file, hole_cards, verbose):
args = holdem_argparser.LibArgs(board, exact, num, input_file, hole_cards)
hole_cards, n, e, board, filename = holdem_argparser.parse_lib_args(args)
return run(hole_cards, n, e, board, filename, verbose)


def run(hole_cards, num, exact, board, file_name, verbose):
if file_name:
input_file = open(file_name, 'r')
Expand All @@ -21,12 +22,13 @@ def run(hole_cards, num, exact, board, file_name, verbose):
hole_cards, board = holdem_argparser.parse_file_args(line)
deck = holdem_functions.generate_deck(hole_cards, board)
run_simulation(hole_cards, num, exact, board, deck, verbose)
print "-----------------------------------"
print("-----------------------------------")
input_file.close()
else:
deck = holdem_functions.generate_deck(hole_cards, board)
return run_simulation(hole_cards, num, exact, board, deck, verbose)


def run_simulation(hole_cards, num, exact, given_board, deck, verbose):
num_players = len(hole_cards)
# Create results data structures which track results of comparisons
Expand All @@ -36,7 +38,7 @@ def run_simulation(hole_cards, num, exact, given_board, deck, verbose):
# 3) result_list: list of the best possible poker hand for each pair of
# hole cards for a given board
result_histograms, winner_list = [], [0] * (num_players + 1)
for _ in xrange(num_players):
for _ in range(num_players):
result_histograms.append([0] * len(holdem_functions.hand_rankings))
# Choose whether we're running a Monte Carlo or exhaustive simulation
board_length = 0 if given_board is None else len(given_board)
Expand Down Expand Up @@ -67,7 +69,8 @@ def run_simulation(hole_cards, num, exact, given_board, deck, verbose):
result_histograms)
return holdem_functions.find_winning_percentage(winner_list)


if __name__ == '__main__':
start = time.time()
main()
print "\nTime elapsed(seconds): ", time.time() - start
print("\nTime elapsed(seconds): ", time.time() - start)
Loading