Skip to content

Commit

Permalink
preexisting code added
Browse files Browse the repository at this point in the history
  • Loading branch information
julianandrews committed Oct 25, 2014
1 parent da762c8 commit d306452
Show file tree
Hide file tree
Showing 8 changed files with 1,166 additions and 0 deletions.
26 changes: 26 additions & 0 deletions __main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (C) 2014 Julian Andrews
# This file is part of Flop Ferret.
#
# Flop Ferret is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Flop Ferret is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
import sys

from PySide import QtGui

import main_window

if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
wid = main_window.MainWindow()

sys.exit(app.exec_())

106 changes: 106 additions & 0 deletions board_texture.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Copyright (C) 2014 Julian Andrews
# This file is part of Flop Ferret.
#
# Flop Ferret is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Flop Ferret is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License

import pokereval
import hand_range

hand_types = ["NoPair", "OnePair", "TwoPair", "Trips", "Straight", "Flush",
"FlHouse", "Quads", "StFlush"]
readable_hand_types = ["High Card", "Pair", "Two Pair", "Trips", "Straight",
"Flush", "Full House", "Quads", "Straight Flush"]
draw_types = ["Flush Draw", "OESD", "Gutshot"]
pair_types = ["Over Pair", "Top Pair", "Second Pair", "Low Pair", "Board Pair"]

evaluator = pokereval.PokerEval()

class BoardTexture(dict):

def __init__(self):
for key in hand_types + draw_types + pair_types:
self[key] = 0.0

def calculate(self, hr_str, board_strs):
for key in hand_types + draw_types + pair_types:
self[key] = 0.0
board = map(evaluator.string2card, board_strs)
hr = hand_range.HandRange(hr_str)
hr.exclude_cards(board)
if len(board) < 3:
raise ValueError("Not enough cards in board!")
for hand, prob in hr.iteritems():
if not prob == 0.0:
cards = board + list(hand)
result = evaluator.best('hi', cards)
hand_type = result[1][0]
self[hand_type] += prob
if len(cards) < 7:
if result[0] < 84226576 and self.check_flush_draw(cards):
# worse than flush
self["Flush Draw"] += prob
if result[0] < 67305472: # worse than straight
result = self.check_straight_draw(cards)
if result == 2:
self["OESD"] += prob
elif result == 1:
self["Gutshot"] += prob
if hand_type == "OnePair":
self[self.pair_type(hand, board)] += prob

@staticmethod
def check_flush_draw(cards):
suit_counts = [0, 0, 0, 0]
for c in cards:
suit_counts[c/13] += 1
if max(suit_counts) == 4:
return True
else:
return False

@staticmethod
def check_straight_draw(cards):
rs = set(c%13 for c in cards)
bits = 0
for r in rs:
bits |= (2<<r)
if r == 12:
bits |= 1
for i in range(9):
s = bits>>i
if s&31 == 30 or s&127 == 93: #OESD!
return 2
for i in range(10):
if (bits>>i)&31 in (30, 29, 27, 23, 15): # Gutshot!
return 1
return 0

@staticmethod
def pair_type(hand, board):
rank_counts = [0]*13
board_ranks = sorted(c%13 for c in board)
hand_ranks = [c%13 for c in hand]
for r in board_ranks + hand_ranks:
rank_counts[r] += 1
pair_rank = rank_counts.index(2)
if not pair_rank in hand_ranks:
return "Board Pair"
elif pair_rank > board_ranks[-1]:
return "Over Pair"
elif pair_rank == board_ranks[-1]:
return "Top Pair"
elif pair_rank >= board_ranks[-2]:
return "Second Pair"
else:
return "Low Pair"

80 changes: 80 additions & 0 deletions hand_range.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright (C) 2014 Julian Andrews
# This file is part of Flop Ferret.
#
# Flop Ferret is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Flop Ferret is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License

"""A class to store a weighted range of hands"""

import pokereval
import range_string

evaluator = pokereval.PokerEval()

class HandRange(dict):

def __init__(self, range_str=None):
super(HandRange, self).__init__(self)
self.set_zeros()
if not range_str is None:
self._from_str(range_str)

def _from_str(self, range_str):
hand_str_list = range_string.string_to_hands(range_str)
for hand in self:
self[hand] = 0.0
for hand_strs, weight in hand_str_list:
hand = tuple(map(evaluator.string2card, hand_strs))
self[hand] += weight
self.normalize()

def set_zeros(self):
d = evaluator.deck()
for i in range(51):
for j in range(i+1, 52):
key = (d[j], d[i])
self[key] = 0.0

def set_uniform(self):
N = 1.0/1326
for hand in self:
self[hand] = N

def normalize(self):
"""Normalize the hand range and return the original total."""
total = sum(self.values())
if not total == 0.0:
N = 1.0/total
for hand, weight in self.iteritems():
self[hand] = weight*N
return total

def exclude_cards(self, cards):
for hand in self:
for card in cards:
if card in hand:
self[hand] = 0.0
return self.normalize()

def filter(self, func):
for hand, weight in self.iteritems():
if not weight == 0.0:
if not func(hand):
self[hand] = 0.0
return self.normalize()

def filtered(self, func):
new = HandRange()
new.update(self)
new.filter(func)
return new

0 comments on commit d306452

Please sign in to comment.