In this I did an analysis on poker. I made my own dataset by randomly selecting 7 cards from the dataset. It does not gives the actual results. It is more of a simulation of actual data.
I have used jupyter-notebook for this you can use any IDE according to your liking.
Start by importing the modules.
import pandas as pd
import numpy as np
import random
import time
Then I created a function calculate_hand which takes hand as a list and returns a boolean list with the corresponding values [royal_flush, straight_flush, four_of_a_kind, full_house, flush, straight, three_of_a_kind, two_pairs, pair, highcard]. If the hand has three cards of same value three_of_a_kind will be True, also pair will be True because if a hand has three of a kind, it also has a pair. Highcard always return the high card.
ALL_CARDS_NUM = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
ALL_CARDS_NUM_TO_TEXT = {1:'A', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10:'T', 11:'J', 12:'Q', 13:'K', 14:'A'}
FACE_CARDS = {'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
def to_number(card):
if card[0].isnumeric():
return int(card[0])
else:
return FACE_CARDS[card[0]]
def is_straight(num):
all_straights = []
seqcount = np.zeros(7, dtype=np.int)
for i in range(1,len(num)):
if ALL_CARDS_NUM[num[i-1]] - ALL_CARDS_NUM[num[i]] == -1:
seqcount[i] = seqcount[i-1] + 1
elif ALL_CARDS_NUM[num[i-1]] == ALL_CARDS_NUM[num[i]]:
seqcount[i] = seqcount[i-1]
for x in np.argwhere(seqcount >= 4):
return (True, seqcount)
try:
if num[-1] == 'A' and seqcount[num.index('5')] >=3:
return (True, seqcount)
except:
pass
return (False, seqcount)
def count_cards(num):
ptf = {}
temp_count = np.zeros(13)
for x in num:
temp_count[ALL_CARDS_NUM[x]%13 - 1] += 1
for x in np.argwhere(temp_count > 1):
ptf[ALL_CARDS_NUM_TO_TEXT[x[0] + 1]] = int(temp_count[x[0]])
return ptf
def count_suites(suite):
suites_array = {'S': [],
'C': [],
'H': [],
'D': []}
for i in range(len(suite)):
suites_array[suite[i]].append(i)
for key, value in suites_array.items():
if len(value) >= 5:
return value
return []
def calculate_hand(temp_hand, show = False):
hand = temp_hand.copy()
hand.sort(key=to_number)
num = []
suite = []
hand_value = {}
for x in hand:
num.append(x[0])
suite.append(x[1])
#straight
straight, seq = is_straight(num)
pairs = count_cards(num)
flushes = count_suites(suite)
#straignt flush
straight_flush = False
straight_flush_sequence = []
if straight and flushes:
for i in range(len(flushes)-4):
flush_seq = [num[z] for z in flushes[i:i+5]]
temp, _ = is_straight(flush_seq)
if temp:
straight_flush = True
straight_flush_sequence = flush_seq
#royal flush
royal_flush = False
if straight_flush:
if straight_flush_sequence[-1] == 'A':
royal_flush = True
#pairs
pair_value = np.asarray([value for _,value in pairs.items()], dtype=np.int)
#four of a kind
four_of_a_kind = False
if np.argwhere(pair_value >= 4).size != 0:
four_of_a_kind = True
#three of a kind
three_of_a_kind = False
if np.argwhere(pair_value >= 3).size != 0:
three_of_a_kind = True
#full house
full_house = False
if three_of_a_kind and np.argwhere(pair_value >= 2).size >= 2:
full_house = True
#flush
flush = False
if flushes:
flush = True
#two pairs
two_pairs = False
if np.argwhere(pair_value >= 2).size >= 2:
two_pairs = True
#pairs
pair = bool(pairs)
#high card
highcard = num[-1]
if show:
print(num, suite)
print("royal flush:\t\t",royal_flush)
print("straight flush:\t\t", straight_flush)
print("four of a kind:\t\t", four_of_a_kind)
print("full house:\t\t", full_house)
print("flush:\t\t\t", flush)
print("straight:\t\t", straight)
print("three of a kind:\t", three_of_a_kind)
print("Two pairs:\t\t", two_pairs)
print("Pair:\t\t\t", pair)
print("High card: \t\t",highcard)
return [royal_flush, straight_flush, four_of_a_kind, full_house, flush, straight, three_of_a_kind, two_pairs, pair, highcard]
The other functions here are the helping functions.
Now you can create your dataset:
card_num = ['A','2','3','4','5','6','7','8','9','T','J','Q','K']
suite = ['S','C','H','D']
main = []
def randCard():
choosen_num = random.choice(card_num)
choosen_suite = random.choice(suite)
return str(choosen_num) + choosen_suite
start = time.time()
for i in range(1000000):
temp = []
for j in range(7):
choosen_card = randCard()
while (choosen_card in temp):
choosen_card = randCard()
temp.append(choosen_card)
hand_val = calculate_hand(temp)
try:
top_val = hand_val.index(True)
except:
top_val = 9
temp += hand_val
temp.append(top_val)
if i%100000 == 0:
print("Time Elapsed",i,"=", time.time() - start)
main.append(temp)
print("\n\nTotal Time Elapsed =", time.time() - start)
The dataset is stored in the main variable now convert into a pandas dataframe.
x = pd.DataFrame(data=main, columns=["YC1", "YC2", "F1", "F2", "F3", "R", "T", "royal_flush", "straight_flush", "four_of_a_kind", "full_house", "flush", "straight", "three_of_a_kind", "two_pairs", "pair", "highcard", "top_val" ])
x.head()
Now you can either save your data set in csv format or create new dataset every time you decide to use this.
I have used jupyter-notebook for this you can use any IDE according to your liking.
Start by importing the modules.
import pandas as pd
import numpy as np
import random
import time
Then I created a function calculate_hand which takes hand as a list and returns a boolean list with the corresponding values [royal_flush, straight_flush, four_of_a_kind, full_house, flush, straight, three_of_a_kind, two_pairs, pair, highcard]. If the hand has three cards of same value three_of_a_kind will be True, also pair will be True because if a hand has three of a kind, it also has a pair. Highcard always return the high card.
ALL_CARDS_NUM = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
ALL_CARDS_NUM_TO_TEXT = {1:'A', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10:'T', 11:'J', 12:'Q', 13:'K', 14:'A'}
FACE_CARDS = {'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
def to_number(card):
if card[0].isnumeric():
return int(card[0])
else:
return FACE_CARDS[card[0]]
def is_straight(num):
all_straights = []
seqcount = np.zeros(7, dtype=np.int)
for i in range(1,len(num)):
if ALL_CARDS_NUM[num[i-1]] - ALL_CARDS_NUM[num[i]] == -1:
seqcount[i] = seqcount[i-1] + 1
elif ALL_CARDS_NUM[num[i-1]] == ALL_CARDS_NUM[num[i]]:
seqcount[i] = seqcount[i-1]
for x in np.argwhere(seqcount >= 4):
return (True, seqcount)
try:
if num[-1] == 'A' and seqcount[num.index('5')] >=3:
return (True, seqcount)
except:
pass
return (False, seqcount)
def count_cards(num):
ptf = {}
temp_count = np.zeros(13)
for x in num:
temp_count[ALL_CARDS_NUM[x]%13 - 1] += 1
for x in np.argwhere(temp_count > 1):
ptf[ALL_CARDS_NUM_TO_TEXT[x[0] + 1]] = int(temp_count[x[0]])
return ptf
def count_suites(suite):
suites_array = {'S': [],
'C': [],
'H': [],
'D': []}
for i in range(len(suite)):
suites_array[suite[i]].append(i)
for key, value in suites_array.items():
if len(value) >= 5:
return value
return []
def calculate_hand(temp_hand, show = False):
hand = temp_hand.copy()
hand.sort(key=to_number)
num = []
suite = []
hand_value = {}
for x in hand:
num.append(x[0])
suite.append(x[1])
#straight
straight, seq = is_straight(num)
pairs = count_cards(num)
flushes = count_suites(suite)
#straignt flush
straight_flush = False
straight_flush_sequence = []
if straight and flushes:
for i in range(len(flushes)-4):
flush_seq = [num[z] for z in flushes[i:i+5]]
temp, _ = is_straight(flush_seq)
if temp:
straight_flush = True
straight_flush_sequence = flush_seq
#royal flush
royal_flush = False
if straight_flush:
if straight_flush_sequence[-1] == 'A':
royal_flush = True
#pairs
pair_value = np.asarray([value for _,value in pairs.items()], dtype=np.int)
#four of a kind
four_of_a_kind = False
if np.argwhere(pair_value >= 4).size != 0:
four_of_a_kind = True
#three of a kind
three_of_a_kind = False
if np.argwhere(pair_value >= 3).size != 0:
three_of_a_kind = True
#full house
full_house = False
if three_of_a_kind and np.argwhere(pair_value >= 2).size >= 2:
full_house = True
#flush
flush = False
if flushes:
flush = True
#two pairs
two_pairs = False
if np.argwhere(pair_value >= 2).size >= 2:
two_pairs = True
#pairs
pair = bool(pairs)
#high card
highcard = num[-1]
if show:
print(num, suite)
print("royal flush:\t\t",royal_flush)
print("straight flush:\t\t", straight_flush)
print("four of a kind:\t\t", four_of_a_kind)
print("full house:\t\t", full_house)
print("flush:\t\t\t", flush)
print("straight:\t\t", straight)
print("three of a kind:\t", three_of_a_kind)
print("Two pairs:\t\t", two_pairs)
print("Pair:\t\t\t", pair)
print("High card: \t\t",highcard)
return [royal_flush, straight_flush, four_of_a_kind, full_house, flush, straight, three_of_a_kind, two_pairs, pair, highcard]
The other functions here are the helping functions.
Now you can create your dataset:
card_num = ['A','2','3','4','5','6','7','8','9','T','J','Q','K']
suite = ['S','C','H','D']
main = []
def randCard():
choosen_num = random.choice(card_num)
choosen_suite = random.choice(suite)
return str(choosen_num) + choosen_suite
start = time.time()
for i in range(1000000):
temp = []
for j in range(7):
choosen_card = randCard()
while (choosen_card in temp):
choosen_card = randCard()
temp.append(choosen_card)
hand_val = calculate_hand(temp)
try:
top_val = hand_val.index(True)
except:
top_val = 9
temp += hand_val
temp.append(top_val)
if i%100000 == 0:
print("Time Elapsed",i,"=", time.time() - start)
main.append(temp)
print("\n\nTotal Time Elapsed =", time.time() - start)
The dataset is stored in the main variable now convert into a pandas dataframe.
x = pd.DataFrame(data=main, columns=["YC1", "YC2", "F1", "F2", "F3", "R", "T", "royal_flush", "straight_flush", "four_of_a_kind", "full_house", "flush", "straight", "three_of_a_kind", "two_pairs", "pair", "highcard", "top_val" ])
x.head()
Now you can either save your data set in csv format or create new dataset every time you decide to use this.
x.to_csv(file_name,index=False)
To read the csv file you can use read_csv function
x = pd.read_csv(file_name)
Now we can start analysing the data.
top_hand_value_dict = {
0: "royal_flush",
1: "straight_flush",
2: "four_of_a_kind",
3: "full_house",
4: "flush",
5: "straight",
6: "three_of_a_kind",
7: "two_pairs",
8: "pair",
9: "highcard"
}
def calculate_hand_value(data, x1, x2):
print("\nIndividuaized values\n")
hands = data.loc[((data["YC1"] == x1) & (data["YC2"] == x2)) | ((data["YC1"] == x2) & (data["YC2"] == x1))]
len_hand = len(hands)
print("Length of the sample: ", len_hand, "\n")
for i in range(9):
perc_val = 100 * hands[top_hand_value_dict[i]].sum()/len_hand
print(top_hand_value_dict[i] + ":\t", round( perc_val , 3))
z = hands.loc[:, hands.columns[7:len(hands.columns)-1]].sum(axis = 1)
print("\nNothing:\t\t" , 100 * len(z.loc[z == 0])/len(z) )
def calculate_top_values(data, x1, x2):
print("\nTop Values:\n")
hands = data.loc[((data["YC1"] == x1) & (data["YC2"] == x2)) | ((data["YC1"] == x2) & (data["YC2"] == x1))]
len_hand = len(hands)
print("Total number of rows:", len_hand)
l = hands['top_val'].value_counts()
for key, value in dict(l).items():
print(top_hand_value_dict[key] + ":\t", round( (value/len_hand)*100, 3))
calculate_hand_value check the possibility of the value of the hand. x1 and x2 are the cards.
calculate_top_values check the top value of the hand. x1 and x2 are the cards.
calculate_hand_value(x, "8S", "8D")
calculate_top_values(x, "QH", "JS")
Use above functions to check outputs.
def hand_losing(data, YC1, YC2, delt_card):
print("\nChances of loosing this hand: ")
hand = [YC1, YC2] + delt_card
len_delt_card = len(delt_card)
delt_card_hands = data.loc[ data.iloc[:,0:7].isin(delt_card).sum(axis="columns") >= len_delt_card]
if delt_card_hands.empty:
print("Sorry no values present!!! Increase the rows database")
else:
len_hand = len(delt_card_hands)
hand_val = calculate_hand(hand)
try:
top_val = hand_val.index(True)
except:
top_val = 9
len_lost = len(delt_card_hands.loc[data['top_val'] < top_val])
print("Chances of losing by cards value: ", len_lost)
hand_high_card = ALL_CARDS_NUM[hand_val[9]]
len_lost_high_val = len(
delt_card_hands.loc[
(data['top_val'] == top_val) &
(data['highcard'].apply(lambda i: ALL_CARDS_NUM[i]) > hand_high_card)
]
)
print("Chances of losing by highcard: ", len_lost_high_val)
unpredicted = len(
delt_card_hands.loc[
(data['top_val'] == top_val) &
(data['highcard'] == hand_val[9])
]
)
print("Unpredicted data: ", unpredicted)
print("Chances of losing (w unpredicted): ",
len_lost + len_lost_high_val, "/",len_hand)
print("Percentage of losing (w unpredicted): ",
round(100 * (len_lost + len_lost_high_val)/len_hand,3))
print("Chances of losing (w/o unpredicted): ",
len_lost + len_lost_high_val, "/",(len_hand - unpredicted))
print("Percentage of losing (w/o unpredicted): ",
round(100 * (len_lost + len_lost_high_val)/(len_hand - unpredicted),3))
hand_losing gives the number of times your hand can loose given the dataset.
hand_losing(x, "8S", "8D", ["8C", "TS", "TH", "9S", "8H"])
You can change the number of cards in the list for turn,flop and river.
Hope you liked this.
Comments
Post a Comment