-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
da762c8
commit d306452
Showing
8 changed files
with
1,166 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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_()) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
Oops, something went wrong.