diff --git a/packaging/windows/pypoker-eval-x64/CHANGES.txt b/packaging/windows/pypoker-eval-x64/CHANGES.txt new file mode 100644 index 000000000..d2635c6cb --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/CHANGES.txt @@ -0,0 +1,23 @@ +Changes +======= + +0.1.0 (2014-01-09) +------------------ + +- Package for pip installation (thanks Jim Kelly!) +- Package is called pokereval (thanks Jim Kelly!) +- Additional Card docs added (thanks Jim Kelly!) + +0.0.2 (2012-12-02) +------------------ + +- Fix bug in 2-card hand evaluator +- Add quickstart (thanks arslr!) +- Support Python 2.6 (thanks again arslr!) +- Quick Start docs added (thanks again arslr!) + +0.0.1 (2011-01-27) +------------------ + +- Nothing changed yet; initial public release +- We weren't even versioning at this point, ha \ No newline at end of file diff --git a/packaging/windows/pypoker-eval-x64/LICENSE.txt b/packaging/windows/pypoker-eval-x64/LICENSE.txt new file mode 100644 index 000000000..a0248021b --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/LICENSE.txt @@ -0,0 +1,13 @@ +Copyright (c) 2014 Alvin Liang + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/packaging/windows/pypoker-eval-x64/MANIFEST.in b/packaging/windows/pypoker-eval-x64/MANIFEST.in new file mode 100644 index 000000000..3a6a904e9 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt +include *.rst diff --git a/packaging/windows/pypoker-eval-x64/PKG-INFO b/packaging/windows/pypoker-eval-x64/PKG-INFO new file mode 100644 index 000000000..ddca60ea4 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/PKG-INFO @@ -0,0 +1,87 @@ +Metadata-Version: 1.0 +Name: pokereval +Version: 0.2.0 +Summary: A pure python poker hand evaluator for 5, 6, 7 cards +Home-page: https://github.com/aliang/pokerhand-eval +Author: Alvin Liang +Author-email: ayliang@gmail.com +License: Apache, see LICENSE.txt +Description: Poker Hand Evaluator + ==================== + + In pure python + + 27 January 2011, Alvin Liang + + Introduction + ------------ + + This is a pure python library to calculate the rank of the best poker + hand out of 5, 6, or 7 cards. It does not run the board for you, or + calculate winning percentage, EV, or anything like that. But if you give + it two hands and the same board, you will be able to tell which hand + wins. + + It is nowhere near as fast as pypoker-eval, but it works if you can't + use C for some reason (the early stages of the first MIT pokerbot + competition come to mind). The core algorithm is slower, and you + obviously don't have the speed of C. + + Quick Start + ----------- + + .. code:: python + + from pokereval.card import Card + from pokereval.hand_evaluator import HandEvaluator + + hole = [Card(2, 1), Card(2, 2)] + board = [] + score = HandEvaluator.evaluate_hand(hole, board) + + Rank is 2-14 representing 2-A, while suit is 1-4 representing + spades, hearts, diamonds, clubs. + + The Card constructor accepts two arguments, rank, and suit. + + .. code:: python + + aceOfSpades = Card(14, 1) + twoOfDiamonds = Card(2, 3) + + Algorithm + --------- + + The algorithm for 5 cards is just a port of the algorithm that used to + be at the following URL. (I purposely broke the link because it now hosts + a malware site.) + httx://wwx.suffecool.net/poker/evaluator.html + + I came up with the 6 and 7 card evaluators myself, using a very similar + card representation and applying some of the same ideas with prime + numbers. The idea was to strike a balance between lookup table size and + speed. + + Also, I haven't included the code I used to generate the lookup tables, + but you should be able to do that with a simpler, slower algorithm. + Maybe I'll add that later as well. + + There is also a two-card ranking/percentile algorithm that is unrelated + to the rest and may get cleaned up later. We used it at one point for + some pre-flop evaluation. Credit to Zach Wissner-Gross for developing + this. + + Documentation is sparse at the moment, sorry about that, and obviously I + did not really bother to package it or clean it up. I may or may not + work on this in the future. Basically, I made it, so why not release it? + + Contributors + ------------ + + - Me! Go me! + - Zach Wissner-Gross (2-card algorithm) + - arslr (Fixes for other Python versions) + - Jim Kelly (Help with packaging, additional documentation) + - hwmrocker (Improvements to Card constructor, Python 3 compatibility) + - radekj (Tests, Python 3 compatibility) +Platform: UNKNOWN diff --git a/packaging/windows/pypoker-eval-x64/README.rst b/packaging/windows/pypoker-eval-x64/README.rst new file mode 100644 index 000000000..dfb190033 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/README.rst @@ -0,0 +1,78 @@ +Poker Hand Evaluator +==================== + +In pure python + +27 January 2011, Alvin Liang + +Introduction +------------ + +This is a pure python library to calculate the rank of the best poker +hand out of 5, 6, or 7 cards. It does not run the board for you, or +calculate winning percentage, EV, or anything like that. But if you give +it two hands and the same board, you will be able to tell which hand +wins. + +It is nowhere near as fast as pypoker-eval, but it works if you can't +use C for some reason (the early stages of the first MIT pokerbot +competition come to mind). The core algorithm is slower, and you +obviously don't have the speed of C. + +Quick Start +----------- + +.. code:: python + + from pokereval.card import Card + from pokereval.hand_evaluator import HandEvaluator + + hole = [Card(2, 1), Card(2, 2)] + board = [] + score = HandEvaluator.evaluate_hand(hole, board) + +Rank is 2-14 representing 2-A, while suit is 1-4 representing +spades, hearts, diamonds, clubs. + +The Card constructor accepts two arguments, rank, and suit. + +.. code:: python + + aceOfSpades = Card(14, 1) + twoOfDiamonds = Card(2, 3) + +Algorithm +--------- + +The algorithm for 5 cards is just a port of the algorithm that used to +be at the following URL. (I purposely broke the link because it now hosts +a malware site.) +httx://wwx.suffecool.net/poker/evaluator.html + +I came up with the 6 and 7 card evaluators myself, using a very similar +card representation and applying some of the same ideas with prime +numbers. The idea was to strike a balance between lookup table size and +speed. + +Also, I haven't included the code I used to generate the lookup tables, +but you should be able to do that with a simpler, slower algorithm. +Maybe I'll add that later as well. + +There is also a two-card ranking/percentile algorithm that is unrelated +to the rest and may get cleaned up later. We used it at one point for +some pre-flop evaluation. Credit to Zach Wissner-Gross for developing +this. + +Documentation is sparse at the moment, sorry about that, and obviously I +did not really bother to package it or clean it up. I may or may not +work on this in the future. Basically, I made it, so why not release it? + +Contributors +------------ + +- Me! Go me! +- Zach Wissner-Gross (2-card algorithm) +- arslr (Fixes for other Python versions) +- Jim Kelly (Help with packaging, additional documentation) +- hwmrocker (Improvements to Card constructor, Python 3 compatibility) +- radekj (Tests, Python 3 compatibility) \ No newline at end of file diff --git a/packaging/windows/pypoker-eval-x64/build/lib/pokereval/__init__.py b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packaging/windows/pypoker-eval-x64/build/lib/pokereval/bug-1823.py b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/bug-1823.py new file mode 100644 index 000000000..7a367beef --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/bug-1823.py @@ -0,0 +1,33 @@ +# +# Copyright (C) 2007, 2008 Loic Dachary +# +# This program 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. +# +# This program 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 +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +# +# http://gna.org/support/?1823 +# +import sys +sys.path.insert(0, ".") +sys.path.insert(0, ".libs") + +from pokereval import PokerEval + +pokereval = PokerEval() + +result = pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"]], dead = [], board = ["Ad", "Qs", "2c", "Ac", "Kc"]) +assert result == {'info': (990, 0, 1), 'eval': [{'winlo': 0, 'tielo': 0, 'winhi': 877, 'scoop': 877, 'loselo': 0, 'ev': 903, 'losehi': 78, 'tiehi': 35}, {'winlo': 0, 'tielo': 0, 'winhi': 78, 'scoop': 78, 'loselo': 0, 'ev': 96, 'losehi': 877, 'tiehi': 35}]} + +result = pokereval.poker_eval(game = "omaha8", fill_pockets = 1, pockets = [ ["As", "3s", "2s", "6s"], ["__", "__", "__", "__"]], dead = [], board = ["Ad", "Qs", "2c", "7c", "5c"]) +assert result == {'info': (123410, 1, 1), 'eval': [{'winlo': 109375, 'tielo': 5361, 'winhi': 73190, 'scoop': 69661, 'loselo': 8674, 'ev': 753, 'losehi': 48978, 'tiehi': 1242}, {'winlo': 8674, 'tielo': 5361, 'winhi': 48978, 'scoop': 8674, 'loselo': 68788, 'ev': 246, 'losehi': 73190, 'tiehi': 1242}]} + diff --git a/packaging/windows/pypoker-eval-x64/build/lib/pokereval/compile.py b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/compile.py new file mode 100644 index 000000000..bc5389291 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/compile.py @@ -0,0 +1,2 @@ +import py_compile +py_compile.compile('pokereval.py') \ No newline at end of file diff --git a/packaging/windows/pypoker-eval-x64/build/lib/pokereval/pokereval.py b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/pokereval.py new file mode 100644 index 000000000..12ba9c48f --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/pokereval.py @@ -0,0 +1,332 @@ +# +# Copyright (C) 2007, 2008 Loic Dachary +# Copyright (C) 2004, 2005, 2006 Mekensleep +# +# Mekensleep +# 24 rue vieille du temple +# 75004 Paris +# licensing@mekensleep.com +# +# This program 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. +# +# This program 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 +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Authors: +# Loic Dachary +# +# +import sys +_pokereval = __import__('_pokereval_2_7') + +from types import * + +class PokerEval: + """\ +Evaluate the strengh of a poker hand for a given poker variant. +In all methods, when a list of cards is to be provided (for instance +with the "hand" argument of the "best" method), each member of the +list may be a number or a string designating a card according to +the following table: + + 2h/00 2d/13 2c/26 2s/39 + 3h/01 3d/14 3c/27 3s/40 + 4h/02 4d/15 4c/28 4s/41 + 5h/03 5d/16 5c/29 5s/42 + 6h/04 6d/17 6c/30 6s/43 + 7h/05 7d/18 7c/31 7s/44 + 8h/06 8d/19 8c/32 8s/45 + 9h/07 9d/20 9c/33 9s/46 + Th/08 Td/21 Tc/34 Ts/47 + Jh/09 Jd/22 Jc/35 Js/48 + Qh/10 Qd/23 Qc/36 Qs/49 + Kh/11 Kd/24 Kc/37 Ks/50 + Ah/12 Ad/25 Ac/38 As/51 + +The string __ (two underscore) or the number 255 are placeholders +meaning that the card is unknown. +""" + + def best(self, side, hand, board = []): + """\ +Return the best five card combination that can be made with the cards +listed in "hand" and, optionally, board. The "side" may be "hi" or +"low". The "board" argument must only be provided for variants where +knowing if a given card is taken from the board or not is significant +(such as Omaha but not Holdem). + +A list is returned. The first element is the numerical value +of the hand (better hands have higher values if "side" is "hi" and +lower values if "side" is "low"). The second element is a list whose +first element is the strength of the hand among the following: + +Nothing (only if "side" equals "low") +NoPair +TwoPair +Trips +Straight +Flush +FlHouse +Quads +StFlush + +The last five elements are numbers describing the best hand properly +sorted (for instance the ace is at the end for no pair if "side" is low or +at the beginning if "side" high). + +Examples: + +[134414336, ['StFlush', 29, 28, 27, 26, 38]] is the wheel five to ace, clubs +[475920, ['NoPair', 45, 29, 41, 39, 51]] is As, 8s, 5c, 4s, 2s +[268435455, ['Nothing']] means there is no qualifying low +""" + if len(hand + board) >= 5: + return _pokereval.eval_hand(side, hand, board) + else: + return False + + def best_hand(self, side, hand, board = []): + """\ +Return the best five card combination that can be made with the cards +listed in "hand" and, optionaly, board. The "side" may be "hi" or +"low". The returned value is the second element of the list returned +by the "best" method. +""" + if len(hand + board) >= 5: + return _pokereval.eval_hand(side, hand, board)[1] + else: + return False + + def best_hand_value(self, side, hand, board = []): + """\ +Return the best five card combination that can be made with the cards +listed in "hand" and, optionaly, board. The "side" may be "hi" or +"low". The returned value is the first element of the list returned +by the "best" method. +""" + if len(hand + board) >= 5: + return _pokereval.eval_hand(side, hand, board)[0] + else: + return False + + def evaln(self, cards): + """\ +Call the poker-eval Hand_EVAL_N function with the "cards" argument. +Return the strength of the "cards" as a number. The higher the +better. +""" + return _pokereval.evaln(cards) + + def winners(self, *args, **kwargs): + """\ +Return a list of the indexes of the best hands, relative to the "pockets" +keyword argument. For instance, if the first pocket and third pocket cards +tie, the list would be [0, 2]. Since there may be more than one way to +win a hand, a hash is returned with the list of the winners for each so +called side. For instace {'hi': [0], 'low': [1]} means pocket cards +at index 0 won the high side of the hand and pocket cards at index 1 +won the low side. + +See the"poker_eval" method for a detailed +explanation of the semantics of the arguments. + +If the keyword argument "fill_pockets" is set, pocket cards +can contain a placeholder (i.e. 255 or __) that will be be +used as specified in the "poker_eval" method documentation. + +If the keyword argument "fill_pockets" is not set, pocket cards +that contain at least one placeholder (i.e. 255 or __) are +ignored completly. For instance if winners is called as follows +o.winners(game = 'holdem', pockets = [ [ '__', 'As' ], [ 'Ks', 'Kd'] ]) +it is strictly equivalent as calling +o.winners(game = 'holdem', pockets = [ [ 'Ks', 'Kd'] ]). +""" + index2index = {} + normalized_pockets = [] + normalized_index = 0 + pockets = kwargs["pockets"][:] + for index in xrange(len(pockets)): + if "fill_pockets" not in kwargs: + if 255 in pockets[index] or "__" in pockets[index]: + pockets[index] = [] + + if pockets[index] != []: + normalized_pockets.append(pockets[index]) + index2index[index] = normalized_index + normalized_index += 1 + kwargs["pockets"] = normalized_pockets + + results = _pokereval.poker_eval(*args, **kwargs) + + (count, haslopot, hashipot) = results.pop(0) + winners = { 'low': [], 'hi': [] } + for index in xrange(len(pockets)): + if index in index2index: + result = results[index2index[index]] + if result[1] == 1 or result[3] == 1: + winners["hi"].append(index) + if result[4] == 1 or result[6] == 1: + winners["low"].append(index) + + if not haslopot or len(winners["low"]) == 0: + del winners["low"] + if not hashipot: + del winners["hi"] + return winners + + def poker_eval(self, *args, **kwargs): + """\ +Provided with a description of a poker game, return the outcome (if at showdown) or +the expected value of each hand. The poker game description is provided as a set +of keyword arguments with the following meaning: + +game : the variant (holdem, holdem8, omaha, omaha8, 7stud, 7stud8, razz, + 5draw, 5draw8, 5drawnsq, lowball, lowball27). + Mandatory, no default. + +pockets : list of pocket cards for each player still in game. Each member + of the list is a list of cards. The position of the pocket cards + in the list is meaningfull for the value returned will refer to + this position when stating which player wins, tie or loose. + Example: [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]] + Cards do not have to be real cards like "tc" or "4s". They may also be a + placeholder, denoted by "__" or 255. When using placeholders, the + keyword argument "iterations" may be specified to use Monte Carlo instead of + exhaustive exploration of all the possible combinations. + Example2: [ ["tc", "__"], [255, "ah"], ["8c", "6h"]] + + Mandatory, no default. + +board : list of community cards, for games where this is meaningfull. If + specified when irrelevant, the return value cannot be predicted. + Default: [] + +dead : list of dead cards. These cards won't be accounted for when exloring + the possible hands. + Default: [] + +iterations: the maximum number of iterations when exploring the + possible outcome of a given hand. Roughly speaking, each + iteration means to distribute cards that are missing (for + which there are place holders in the board or pockets + keywords arguments, i.e. 255 or __). If the number of + iterations is not specified and there are place holders, + the return value cannot be predicted. + Default: +infinite (i.e. exhaustive exploration) + +Example: object.poker_eval(game = "holdem", + pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], + dead = [], + board = ["7h", "3s", "2c"]) + +The return value is a map of two entries: +'info' contains three integers: + - the number of samples (which must be equal to the number of iterations given + in argument). + - 1 if the game has a low side, 0 otherwise + - 1 if the game has a high side, 0 otherwise +'eval' is a list of as many maps as there are pocket cards, each +made of the following entries: + 'scoop': the number of time these pocket cards scoop + 'winhi': the number of time these pocket cards win the high side + 'losehi': the number of time these pocket cards lose the high side + 'tiehi': the number of time these pocket cards tie for the high side + 'winlo': the number of time these pocket cards win the low side + 'loselo': the number of time these pocket cards lose the low side + 'tielo': the number of time these pocket cards tie for the low side + 'ev': the EV of these pocket cards as an int in the range [0,1000] with + 1000 being the best. + +It should be clear that if there is only one sample (i.e. because all the +cards are known which is the situation that occurs at showdown) the details +provided by the 'eval' entry is mostly irrelevant and the caller might +prefer to call the winners method instead. +""" + result = _pokereval.poker_eval(*args, **kwargs) + return { + 'info': result[0], + 'eval': [ { 'scoop': x[0], + 'winhi': x[1], + 'losehi': x[2], + 'tiehi': x[3], + 'winlo': x[4], + 'loselo': x[5], + 'tielo': x[6], + 'ev': int(x[7] * 1000) } for x in result[1:] ] + } + + def deck(self): + """\ +Return the list of all cards in the deck. +""" + return [ self.string2card(i + j) for i in "23456789TJQKA" for j in "hdcs" ] + + def nocard(self): + """Return 255, the numerical value of a place holder in a list of cards.""" + return 255 + + def string2card(self, cards): + """\ +Convert card names (strings) to card numbers (integers) according to the +following map: + + 2h/00 2d/13 2c/26 2s/39 + 3h/01 3d/14 3c/27 3s/40 + 4h/02 4d/15 4c/28 4s/41 + 5h/03 5d/16 5c/29 5s/42 + 6h/04 6d/17 6c/30 6s/43 + 7h/05 7d/18 7c/31 7s/44 + 8h/06 8d/19 8c/32 8s/45 + 9h/07 9d/20 9c/33 9s/46 + Th/08 Td/21 Tc/34 Ts/47 + Jh/09 Jd/22 Jc/35 Js/48 + Qh/10 Qd/23 Qc/36 Qs/49 + Kh/11 Kd/24 Kc/37 Ks/50 + Ah/12 Ad/25 Ac/38 As/51 + +The "cards" argument may be either a list in which case a converted list +is returned or a string in which case the corresponding number is +returned. +""" + if type(cards) is ListType or type(cards) is TupleType: + return [ _pokereval.string2card(card) for card in cards ] + else: + return _pokereval.string2card(cards) + + def card2string(self, cards): + """\ +Convert card numbers (integers) to card names (strings) according to the +following map: + + 2h/00 2d/13 2c/26 2s/39 + 3h/01 3d/14 3c/27 3s/40 + 4h/02 4d/15 4c/28 4s/41 + 5h/03 5d/16 5c/29 5s/42 + 6h/04 6d/17 6c/30 6s/43 + 7h/05 7d/18 7c/31 7s/44 + 8h/06 8d/19 8c/32 8s/45 + 9h/07 9d/20 9c/33 9s/46 + Th/08 Td/21 Tc/34 Ts/47 + Jh/09 Jd/22 Jc/35 Js/48 + Qh/10 Qd/23 Qc/36 Qs/49 + Kh/11 Kd/24 Kc/37 Ks/50 + Ah/12 Ad/25 Ac/38 As/51 + +The "cards" argument may be either a list in which case a converted list +is returned or an integer in which case the corresponding string is +returned. +""" + if type(cards) is ListType or type(cards) is TupleType: + return [ _pokereval.card2string(card) for card in cards ] + else: + return _pokereval.card2string(cards) + diff --git a/packaging/windows/pypoker-eval-x64/build/lib/pokereval/sha256hash.py b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/sha256hash.py new file mode 100644 index 000000000..b1bbfc2f4 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/sha256hash.py @@ -0,0 +1,9 @@ +# Python program to find SHA256 hash string of a file +import hashlib; +import base64; +print( + base64.urlsafe_b64encode( + hashlib.sha256(open('_pokereval_2_4.pyd', 'rb').read()).digest()) + .decode('latin1') + .rstrip(b'=') + ) \ No newline at end of file diff --git a/packaging/windows/pypoker-eval-x64/build/lib/pokereval/test.py b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/test.py new file mode 100644 index 000000000..ad8fec4f0 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/build/lib/pokereval/test.py @@ -0,0 +1,178 @@ +# +# Copyright (C) 2007, 2008 Loic Dachary +# Copyright (C) 2004, 2005, 2006 Mekensleep +# +# Mekensleep +# 24 rue vieille du temple +# 75004 Paris +# licensing@mekensleep.com +# +# This program 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. +# +# This program 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 +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Authors: +# Loic Dachary +# +# +import sys +sys.path.insert(0, ".") +sys.path.insert(0, ".libs") + +from pokereval import PokerEval + +iterations_low = 100000 +iterations_high = 200000 + +pokereval = PokerEval() + +if pokereval.best_hand_value("hi", ["Ah", "Ad", "As", "Kh", "Ks" ]) != 101494784: + sys.exit(1) + +if pokereval.string2card("2h") != 0: + sys.exit(1) + +print "" +pockets = [ ["As", "Ad", "Ac", "Tc", "Ts", "2d", "5c" ], + ["Js", "Jc", "7s", "8c", "8d", "3c", "3h" ], + [255, 255 ] ] +print "stud7 (1) result = %s\n" % pokereval.winners(game = "7stud", pockets = pockets, dead = [], board = []) + +pockets = [[22, 18, 21, 3, 41, 1, 30], [39, 255, 255, 15, 13, 17, 255]] +print "stud7 (2) result = %s\n" % pokereval.winners(game = "7stud", pockets = pockets, dead = [], board = []) + +print [ j + i + "/%d" % pokereval.string2card(j + i) for i in "hdcs" for j in "23456789TJQKA" ] +print "deck = %s\n" % pokereval.deck() + +print "result = %s\n" % pokereval.poker_eval(game = "holdem", pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c"]) +print "winners = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c"]) + +print "result = %s\n" % pokereval.poker_eval(game = "holdem", pockets = [ ["tc", "ac"], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) +print "winners = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac"], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) + +print "winners (filthy pockets) = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac", 255], [], [255, 255], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) + +print "winners omaha = %s\n" % pokereval.winners(game = "omaha", pockets = [ ["tc", "ac", "ks", "kc" ], ["th", "ah", "qs", "qc" ], ["8c", "6h", "js", "jc" ]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) +print "winners omaha8 = %s\n" % pokereval.winners(game = "omaha8", pockets = [ ["tc", "ac", "ks", "kc" ], ["th", "ah", "qs", "qc" ], ["8c", "6h", "js", "jc" ]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) + +hand = ["Ac", "As", "Td", "7s", "7h", "3s", "2c"] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ["Ah", "Ts", "Kh", "Qs", "Js" ] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ["2h", "Kh", "Qh", "Jh", "Th" ] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['2s', '3s', 'Jd', 'Ks', 'As', '4d', '5h', '7d', '9c'] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['As', '2s', '4d', '4s', '5c', '5d', '7s'] +best_hand = pokereval.best_hand("low", hand) +print "1/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) ) +print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['As', '2s', '4d', '4s', '5c', '5d', '8s'] +best_hand = pokereval.best_hand("low", hand) +print "2/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) ) +print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['7d', '6c', '5h', '4d', 'As'] +best_hand = pokereval.best_hand("low", hand) +print "3/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) ) +print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'As', '4d', '5h', '7d', '9c' ] +hand = [ '2s', 'Ts', 'Jd', 'Ks' ] +best_hand = pokereval.best_hand("low", hand, board) +print "4/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'As', '4d', '6h', '7d', '3c' ] +hand = [ '2s', '5s', 'Jd', 'Ks' ] +best_hand = pokereval.best_hand("low", hand, board) +print "low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'Jc', '4c', '3c', '5c', '9c' ] +hand = [ '2c', 'Ac', '5h', '9d' ] +best_hand = pokereval.best_hand("hi", hand, board) +print "hi hand from %s / %s = %s" % ( hand, board, pokereval.best("hi", hand, board) ) +print "best hi hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], pokereval.card2string(best_hand[1:])) + +print "" +board = [ 'Jd', '9c', 'Jc', 'Tc', '2h' ] +hand = [ '2c', '4c', 'Th', '6s' ] +best_hand = pokereval.best_hand("low", hand, board) +print "5/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'Ks', 'Jd', '7s', '4d', 'Js' ] +hand = [ '2d', '6c', 'Ac', '5c' ] +best_hand = pokereval.best_hand("low", hand, board) +print "6/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +if len(sys.argv) > 2: + + print "f0 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "Qs", "2c", "Ac", "Kc"]) + + print "" + print "f1 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["7s", "Qs", "2c", "Ac", "Kc"]) + + + print "" + print "f2 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_low, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f3 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["As", "Ac"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f4 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["As", "Ks"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f5 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["2s", "2c"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f6 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["Js", "Jc"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f7 result = %s\n" % pokereval.poker_eval(game = "omaha", fill_pockets = 1, iterations = iterations_high, pockets = [ ["Js", "Jc", "7s", "8c"], ["__", "__", "__", "__"], ["__", "__", "__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + +print "" +hand = ['As', 'Ad'] +print "handval %s = %d " % (hand, pokereval.evaln(hand)) + +print "" +hand = ['Qc', '7d'] +print "handval %s = %d " % (hand, pokereval.evaln(hand)) + +pokereval = None diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval-0.2.0-py2.7.egg b/packaging/windows/pypoker-eval-x64/dist/pokereval-0.2.0-py2.7.egg new file mode 100644 index 000000000..19a5552d2 Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/dist/pokereval-0.2.0-py2.7.egg differ diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/__init__.py b/packaging/windows/pypoker-eval-x64/dist/pokereval/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/__init__.pyc b/packaging/windows/pypoker-eval-x64/dist/pokereval/__init__.pyc new file mode 100644 index 000000000..f4d97dab7 Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/dist/pokereval/__init__.pyc differ diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/_pokereval_2_7.pyd b/packaging/windows/pypoker-eval-x64/dist/pokereval/_pokereval_2_7.pyd new file mode 100644 index 000000000..c287e8471 Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/dist/pokereval/_pokereval_2_7.pyd differ diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/bug-1823.py b/packaging/windows/pypoker-eval-x64/dist/pokereval/bug-1823.py new file mode 100644 index 000000000..7a367beef --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/dist/pokereval/bug-1823.py @@ -0,0 +1,33 @@ +# +# Copyright (C) 2007, 2008 Loic Dachary +# +# This program 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. +# +# This program 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 +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +# +# http://gna.org/support/?1823 +# +import sys +sys.path.insert(0, ".") +sys.path.insert(0, ".libs") + +from pokereval import PokerEval + +pokereval = PokerEval() + +result = pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"]], dead = [], board = ["Ad", "Qs", "2c", "Ac", "Kc"]) +assert result == {'info': (990, 0, 1), 'eval': [{'winlo': 0, 'tielo': 0, 'winhi': 877, 'scoop': 877, 'loselo': 0, 'ev': 903, 'losehi': 78, 'tiehi': 35}, {'winlo': 0, 'tielo': 0, 'winhi': 78, 'scoop': 78, 'loselo': 0, 'ev': 96, 'losehi': 877, 'tiehi': 35}]} + +result = pokereval.poker_eval(game = "omaha8", fill_pockets = 1, pockets = [ ["As", "3s", "2s", "6s"], ["__", "__", "__", "__"]], dead = [], board = ["Ad", "Qs", "2c", "7c", "5c"]) +assert result == {'info': (123410, 1, 1), 'eval': [{'winlo': 109375, 'tielo': 5361, 'winhi': 73190, 'scoop': 69661, 'loselo': 8674, 'ev': 753, 'losehi': 48978, 'tiehi': 1242}, {'winlo': 8674, 'tielo': 5361, 'winhi': 48978, 'scoop': 8674, 'loselo': 68788, 'ev': 246, 'losehi': 73190, 'tiehi': 1242}]} + diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/bug-1823.pyc b/packaging/windows/pypoker-eval-x64/dist/pokereval/bug-1823.pyc new file mode 100644 index 000000000..5ce6131e6 Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/dist/pokereval/bug-1823.pyc differ diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/compile.py b/packaging/windows/pypoker-eval-x64/dist/pokereval/compile.py new file mode 100644 index 000000000..bc5389291 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/dist/pokereval/compile.py @@ -0,0 +1,2 @@ +import py_compile +py_compile.compile('pokereval.py') \ No newline at end of file diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/pokereval.py b/packaging/windows/pypoker-eval-x64/dist/pokereval/pokereval.py new file mode 100644 index 000000000..12ba9c48f --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/dist/pokereval/pokereval.py @@ -0,0 +1,332 @@ +# +# Copyright (C) 2007, 2008 Loic Dachary +# Copyright (C) 2004, 2005, 2006 Mekensleep +# +# Mekensleep +# 24 rue vieille du temple +# 75004 Paris +# licensing@mekensleep.com +# +# This program 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. +# +# This program 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 +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Authors: +# Loic Dachary +# +# +import sys +_pokereval = __import__('_pokereval_2_7') + +from types import * + +class PokerEval: + """\ +Evaluate the strengh of a poker hand for a given poker variant. +In all methods, when a list of cards is to be provided (for instance +with the "hand" argument of the "best" method), each member of the +list may be a number or a string designating a card according to +the following table: + + 2h/00 2d/13 2c/26 2s/39 + 3h/01 3d/14 3c/27 3s/40 + 4h/02 4d/15 4c/28 4s/41 + 5h/03 5d/16 5c/29 5s/42 + 6h/04 6d/17 6c/30 6s/43 + 7h/05 7d/18 7c/31 7s/44 + 8h/06 8d/19 8c/32 8s/45 + 9h/07 9d/20 9c/33 9s/46 + Th/08 Td/21 Tc/34 Ts/47 + Jh/09 Jd/22 Jc/35 Js/48 + Qh/10 Qd/23 Qc/36 Qs/49 + Kh/11 Kd/24 Kc/37 Ks/50 + Ah/12 Ad/25 Ac/38 As/51 + +The string __ (two underscore) or the number 255 are placeholders +meaning that the card is unknown. +""" + + def best(self, side, hand, board = []): + """\ +Return the best five card combination that can be made with the cards +listed in "hand" and, optionally, board. The "side" may be "hi" or +"low". The "board" argument must only be provided for variants where +knowing if a given card is taken from the board or not is significant +(such as Omaha but not Holdem). + +A list is returned. The first element is the numerical value +of the hand (better hands have higher values if "side" is "hi" and +lower values if "side" is "low"). The second element is a list whose +first element is the strength of the hand among the following: + +Nothing (only if "side" equals "low") +NoPair +TwoPair +Trips +Straight +Flush +FlHouse +Quads +StFlush + +The last five elements are numbers describing the best hand properly +sorted (for instance the ace is at the end for no pair if "side" is low or +at the beginning if "side" high). + +Examples: + +[134414336, ['StFlush', 29, 28, 27, 26, 38]] is the wheel five to ace, clubs +[475920, ['NoPair', 45, 29, 41, 39, 51]] is As, 8s, 5c, 4s, 2s +[268435455, ['Nothing']] means there is no qualifying low +""" + if len(hand + board) >= 5: + return _pokereval.eval_hand(side, hand, board) + else: + return False + + def best_hand(self, side, hand, board = []): + """\ +Return the best five card combination that can be made with the cards +listed in "hand" and, optionaly, board. The "side" may be "hi" or +"low". The returned value is the second element of the list returned +by the "best" method. +""" + if len(hand + board) >= 5: + return _pokereval.eval_hand(side, hand, board)[1] + else: + return False + + def best_hand_value(self, side, hand, board = []): + """\ +Return the best five card combination that can be made with the cards +listed in "hand" and, optionaly, board. The "side" may be "hi" or +"low". The returned value is the first element of the list returned +by the "best" method. +""" + if len(hand + board) >= 5: + return _pokereval.eval_hand(side, hand, board)[0] + else: + return False + + def evaln(self, cards): + """\ +Call the poker-eval Hand_EVAL_N function with the "cards" argument. +Return the strength of the "cards" as a number. The higher the +better. +""" + return _pokereval.evaln(cards) + + def winners(self, *args, **kwargs): + """\ +Return a list of the indexes of the best hands, relative to the "pockets" +keyword argument. For instance, if the first pocket and third pocket cards +tie, the list would be [0, 2]. Since there may be more than one way to +win a hand, a hash is returned with the list of the winners for each so +called side. For instace {'hi': [0], 'low': [1]} means pocket cards +at index 0 won the high side of the hand and pocket cards at index 1 +won the low side. + +See the"poker_eval" method for a detailed +explanation of the semantics of the arguments. + +If the keyword argument "fill_pockets" is set, pocket cards +can contain a placeholder (i.e. 255 or __) that will be be +used as specified in the "poker_eval" method documentation. + +If the keyword argument "fill_pockets" is not set, pocket cards +that contain at least one placeholder (i.e. 255 or __) are +ignored completly. For instance if winners is called as follows +o.winners(game = 'holdem', pockets = [ [ '__', 'As' ], [ 'Ks', 'Kd'] ]) +it is strictly equivalent as calling +o.winners(game = 'holdem', pockets = [ [ 'Ks', 'Kd'] ]). +""" + index2index = {} + normalized_pockets = [] + normalized_index = 0 + pockets = kwargs["pockets"][:] + for index in xrange(len(pockets)): + if "fill_pockets" not in kwargs: + if 255 in pockets[index] or "__" in pockets[index]: + pockets[index] = [] + + if pockets[index] != []: + normalized_pockets.append(pockets[index]) + index2index[index] = normalized_index + normalized_index += 1 + kwargs["pockets"] = normalized_pockets + + results = _pokereval.poker_eval(*args, **kwargs) + + (count, haslopot, hashipot) = results.pop(0) + winners = { 'low': [], 'hi': [] } + for index in xrange(len(pockets)): + if index in index2index: + result = results[index2index[index]] + if result[1] == 1 or result[3] == 1: + winners["hi"].append(index) + if result[4] == 1 or result[6] == 1: + winners["low"].append(index) + + if not haslopot or len(winners["low"]) == 0: + del winners["low"] + if not hashipot: + del winners["hi"] + return winners + + def poker_eval(self, *args, **kwargs): + """\ +Provided with a description of a poker game, return the outcome (if at showdown) or +the expected value of each hand. The poker game description is provided as a set +of keyword arguments with the following meaning: + +game : the variant (holdem, holdem8, omaha, omaha8, 7stud, 7stud8, razz, + 5draw, 5draw8, 5drawnsq, lowball, lowball27). + Mandatory, no default. + +pockets : list of pocket cards for each player still in game. Each member + of the list is a list of cards. The position of the pocket cards + in the list is meaningfull for the value returned will refer to + this position when stating which player wins, tie or loose. + Example: [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]] + Cards do not have to be real cards like "tc" or "4s". They may also be a + placeholder, denoted by "__" or 255. When using placeholders, the + keyword argument "iterations" may be specified to use Monte Carlo instead of + exhaustive exploration of all the possible combinations. + Example2: [ ["tc", "__"], [255, "ah"], ["8c", "6h"]] + + Mandatory, no default. + +board : list of community cards, for games where this is meaningfull. If + specified when irrelevant, the return value cannot be predicted. + Default: [] + +dead : list of dead cards. These cards won't be accounted for when exloring + the possible hands. + Default: [] + +iterations: the maximum number of iterations when exploring the + possible outcome of a given hand. Roughly speaking, each + iteration means to distribute cards that are missing (for + which there are place holders in the board or pockets + keywords arguments, i.e. 255 or __). If the number of + iterations is not specified and there are place holders, + the return value cannot be predicted. + Default: +infinite (i.e. exhaustive exploration) + +Example: object.poker_eval(game = "holdem", + pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], + dead = [], + board = ["7h", "3s", "2c"]) + +The return value is a map of two entries: +'info' contains three integers: + - the number of samples (which must be equal to the number of iterations given + in argument). + - 1 if the game has a low side, 0 otherwise + - 1 if the game has a high side, 0 otherwise +'eval' is a list of as many maps as there are pocket cards, each +made of the following entries: + 'scoop': the number of time these pocket cards scoop + 'winhi': the number of time these pocket cards win the high side + 'losehi': the number of time these pocket cards lose the high side + 'tiehi': the number of time these pocket cards tie for the high side + 'winlo': the number of time these pocket cards win the low side + 'loselo': the number of time these pocket cards lose the low side + 'tielo': the number of time these pocket cards tie for the low side + 'ev': the EV of these pocket cards as an int in the range [0,1000] with + 1000 being the best. + +It should be clear that if there is only one sample (i.e. because all the +cards are known which is the situation that occurs at showdown) the details +provided by the 'eval' entry is mostly irrelevant and the caller might +prefer to call the winners method instead. +""" + result = _pokereval.poker_eval(*args, **kwargs) + return { + 'info': result[0], + 'eval': [ { 'scoop': x[0], + 'winhi': x[1], + 'losehi': x[2], + 'tiehi': x[3], + 'winlo': x[4], + 'loselo': x[5], + 'tielo': x[6], + 'ev': int(x[7] * 1000) } for x in result[1:] ] + } + + def deck(self): + """\ +Return the list of all cards in the deck. +""" + return [ self.string2card(i + j) for i in "23456789TJQKA" for j in "hdcs" ] + + def nocard(self): + """Return 255, the numerical value of a place holder in a list of cards.""" + return 255 + + def string2card(self, cards): + """\ +Convert card names (strings) to card numbers (integers) according to the +following map: + + 2h/00 2d/13 2c/26 2s/39 + 3h/01 3d/14 3c/27 3s/40 + 4h/02 4d/15 4c/28 4s/41 + 5h/03 5d/16 5c/29 5s/42 + 6h/04 6d/17 6c/30 6s/43 + 7h/05 7d/18 7c/31 7s/44 + 8h/06 8d/19 8c/32 8s/45 + 9h/07 9d/20 9c/33 9s/46 + Th/08 Td/21 Tc/34 Ts/47 + Jh/09 Jd/22 Jc/35 Js/48 + Qh/10 Qd/23 Qc/36 Qs/49 + Kh/11 Kd/24 Kc/37 Ks/50 + Ah/12 Ad/25 Ac/38 As/51 + +The "cards" argument may be either a list in which case a converted list +is returned or a string in which case the corresponding number is +returned. +""" + if type(cards) is ListType or type(cards) is TupleType: + return [ _pokereval.string2card(card) for card in cards ] + else: + return _pokereval.string2card(cards) + + def card2string(self, cards): + """\ +Convert card numbers (integers) to card names (strings) according to the +following map: + + 2h/00 2d/13 2c/26 2s/39 + 3h/01 3d/14 3c/27 3s/40 + 4h/02 4d/15 4c/28 4s/41 + 5h/03 5d/16 5c/29 5s/42 + 6h/04 6d/17 6c/30 6s/43 + 7h/05 7d/18 7c/31 7s/44 + 8h/06 8d/19 8c/32 8s/45 + 9h/07 9d/20 9c/33 9s/46 + Th/08 Td/21 Tc/34 Ts/47 + Jh/09 Jd/22 Jc/35 Js/48 + Qh/10 Qd/23 Qc/36 Qs/49 + Kh/11 Kd/24 Kc/37 Ks/50 + Ah/12 Ad/25 Ac/38 As/51 + +The "cards" argument may be either a list in which case a converted list +is returned or an integer in which case the corresponding string is +returned. +""" + if type(cards) is ListType or type(cards) is TupleType: + return [ _pokereval.card2string(card) for card in cards ] + else: + return _pokereval.card2string(cards) + diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/pokereval.pyc b/packaging/windows/pypoker-eval-x64/dist/pokereval/pokereval.pyc new file mode 100644 index 000000000..39e793249 Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/dist/pokereval/pokereval.pyc differ diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/sha256hash.py b/packaging/windows/pypoker-eval-x64/dist/pokereval/sha256hash.py new file mode 100644 index 000000000..b1bbfc2f4 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/dist/pokereval/sha256hash.py @@ -0,0 +1,9 @@ +# Python program to find SHA256 hash string of a file +import hashlib; +import base64; +print( + base64.urlsafe_b64encode( + hashlib.sha256(open('_pokereval_2_4.pyd', 'rb').read()).digest()) + .decode('latin1') + .rstrip(b'=') + ) \ No newline at end of file diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/test.py b/packaging/windows/pypoker-eval-x64/dist/pokereval/test.py new file mode 100644 index 000000000..ad8fec4f0 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/dist/pokereval/test.py @@ -0,0 +1,178 @@ +# +# Copyright (C) 2007, 2008 Loic Dachary +# Copyright (C) 2004, 2005, 2006 Mekensleep +# +# Mekensleep +# 24 rue vieille du temple +# 75004 Paris +# licensing@mekensleep.com +# +# This program 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. +# +# This program 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 +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Authors: +# Loic Dachary +# +# +import sys +sys.path.insert(0, ".") +sys.path.insert(0, ".libs") + +from pokereval import PokerEval + +iterations_low = 100000 +iterations_high = 200000 + +pokereval = PokerEval() + +if pokereval.best_hand_value("hi", ["Ah", "Ad", "As", "Kh", "Ks" ]) != 101494784: + sys.exit(1) + +if pokereval.string2card("2h") != 0: + sys.exit(1) + +print "" +pockets = [ ["As", "Ad", "Ac", "Tc", "Ts", "2d", "5c" ], + ["Js", "Jc", "7s", "8c", "8d", "3c", "3h" ], + [255, 255 ] ] +print "stud7 (1) result = %s\n" % pokereval.winners(game = "7stud", pockets = pockets, dead = [], board = []) + +pockets = [[22, 18, 21, 3, 41, 1, 30], [39, 255, 255, 15, 13, 17, 255]] +print "stud7 (2) result = %s\n" % pokereval.winners(game = "7stud", pockets = pockets, dead = [], board = []) + +print [ j + i + "/%d" % pokereval.string2card(j + i) for i in "hdcs" for j in "23456789TJQKA" ] +print "deck = %s\n" % pokereval.deck() + +print "result = %s\n" % pokereval.poker_eval(game = "holdem", pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c"]) +print "winners = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c"]) + +print "result = %s\n" % pokereval.poker_eval(game = "holdem", pockets = [ ["tc", "ac"], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) +print "winners = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac"], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) + +print "winners (filthy pockets) = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac", 255], [], [255, 255], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) + +print "winners omaha = %s\n" % pokereval.winners(game = "omaha", pockets = [ ["tc", "ac", "ks", "kc" ], ["th", "ah", "qs", "qc" ], ["8c", "6h", "js", "jc" ]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) +print "winners omaha8 = %s\n" % pokereval.winners(game = "omaha8", pockets = [ ["tc", "ac", "ks", "kc" ], ["th", "ah", "qs", "qc" ], ["8c", "6h", "js", "jc" ]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) + +hand = ["Ac", "As", "Td", "7s", "7h", "3s", "2c"] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ["Ah", "Ts", "Kh", "Qs", "Js" ] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ["2h", "Kh", "Qh", "Jh", "Th" ] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['2s', '3s', 'Jd', 'Ks', 'As', '4d', '5h', '7d', '9c'] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['As', '2s', '4d', '4s', '5c', '5d', '7s'] +best_hand = pokereval.best_hand("low", hand) +print "1/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) ) +print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['As', '2s', '4d', '4s', '5c', '5d', '8s'] +best_hand = pokereval.best_hand("low", hand) +print "2/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) ) +print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['7d', '6c', '5h', '4d', 'As'] +best_hand = pokereval.best_hand("low", hand) +print "3/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) ) +print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'As', '4d', '5h', '7d', '9c' ] +hand = [ '2s', 'Ts', 'Jd', 'Ks' ] +best_hand = pokereval.best_hand("low", hand, board) +print "4/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'As', '4d', '6h', '7d', '3c' ] +hand = [ '2s', '5s', 'Jd', 'Ks' ] +best_hand = pokereval.best_hand("low", hand, board) +print "low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'Jc', '4c', '3c', '5c', '9c' ] +hand = [ '2c', 'Ac', '5h', '9d' ] +best_hand = pokereval.best_hand("hi", hand, board) +print "hi hand from %s / %s = %s" % ( hand, board, pokereval.best("hi", hand, board) ) +print "best hi hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], pokereval.card2string(best_hand[1:])) + +print "" +board = [ 'Jd', '9c', 'Jc', 'Tc', '2h' ] +hand = [ '2c', '4c', 'Th', '6s' ] +best_hand = pokereval.best_hand("low", hand, board) +print "5/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'Ks', 'Jd', '7s', '4d', 'Js' ] +hand = [ '2d', '6c', 'Ac', '5c' ] +best_hand = pokereval.best_hand("low", hand, board) +print "6/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +if len(sys.argv) > 2: + + print "f0 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "Qs", "2c", "Ac", "Kc"]) + + print "" + print "f1 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["7s", "Qs", "2c", "Ac", "Kc"]) + + + print "" + print "f2 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_low, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f3 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["As", "Ac"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f4 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["As", "Ks"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f5 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["2s", "2c"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f6 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["Js", "Jc"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f7 result = %s\n" % pokereval.poker_eval(game = "omaha", fill_pockets = 1, iterations = iterations_high, pockets = [ ["Js", "Jc", "7s", "8c"], ["__", "__", "__", "__"], ["__", "__", "__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + +print "" +hand = ['As', 'Ad'] +print "handval %s = %d " % (hand, pokereval.evaln(hand)) + +print "" +hand = ['Qc', '7d'] +print "handval %s = %d " % (hand, pokereval.evaln(hand)) + +pokereval = None diff --git a/packaging/windows/pypoker-eval-x64/dist/pokereval/test.pyc b/packaging/windows/pypoker-eval-x64/dist/pokereval/test.pyc new file mode 100644 index 000000000..3f13a475a Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/dist/pokereval/test.pyc differ diff --git a/packaging/windows/pypoker-eval-x64/files.txt b/packaging/windows/pypoker-eval-x64/files.txt new file mode 100644 index 000000000..0cdebbb9a --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/files.txt @@ -0,0 +1,10 @@ +/__init__.py +/_pokereval_2_4.pyd +/bug-1823.py +/pokereval.py +/test.py +/__pycache__/__init__.cpython-27.pyc +/__pycache__/bug-1823.cpython-27.pyc +/__pycache__.cpython-27.pyc +/__pycache__/test.cpython-27.pyc +/pokereval-0.2.0-py2.7.egg-info diff --git a/packaging/windows/pypoker-eval-x64/pokereval.egg-info/PKG-INFO b/packaging/windows/pypoker-eval-x64/pokereval.egg-info/PKG-INFO new file mode 100644 index 000000000..5b687a40e --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/pokereval.egg-info/PKG-INFO @@ -0,0 +1,87 @@ +Metadata-Version: 1.0 +Name: pokereval +Version: 0.2.0 +Summary: A pure python poker hand evaluator for 5, 6, 7 cards +Home-page: https://github.com/aliang/pokerhand-eval +Author: Alvin Liang +Author-email: ayliang@gmail.com +License: Apache, see LICENSE.txt +Description: Poker Hand Evaluator + ==================== + + In pure python + + 27 January 2011, Alvin Liang + + Introduction + ------------ + + This is a pure python library to calculate the rank of the best poker + hand out of 5, 6, or 7 cards. It does not run the board for you, or + calculate winning percentage, EV, or anything like that. But if you give + it two hands and the same board, you will be able to tell which hand + wins. + + It is nowhere near as fast as pypoker-eval, but it works if you can't + use C for some reason (the early stages of the first MIT pokerbot + competition come to mind). The core algorithm is slower, and you + obviously don't have the speed of C. + + Quick Start + ----------- + + .. code:: python + + from pokereval.card import Card + from pokereval.hand_evaluator import HandEvaluator + + hole = [Card(2, 1), Card(2, 2)] + board = [] + score = HandEvaluator.evaluate_hand(hole, board) + + Rank is 2-14 representing 2-A, while suit is 1-4 representing + spades, hearts, diamonds, clubs. + + The Card constructor accepts two arguments, rank, and suit. + + .. code:: python + + aceOfSpades = Card(14, 1) + twoOfDiamonds = Card(2, 3) + + Algorithm + --------- + + The algorithm for 5 cards is just a port of the algorithm that used to + be at the following URL. (I purposely broke the link because it now hosts + a malware site.) + httx://wwx.suffecool.net/poker/evaluator.html + + I came up with the 6 and 7 card evaluators myself, using a very similar + card representation and applying some of the same ideas with prime + numbers. The idea was to strike a balance between lookup table size and + speed. + + Also, I haven't included the code I used to generate the lookup tables, + but you should be able to do that with a simpler, slower algorithm. + Maybe I'll add that later as well. + + There is also a two-card ranking/percentile algorithm that is unrelated + to the rest and may get cleaned up later. We used it at one point for + some pre-flop evaluation. Credit to Zach Wissner-Gross for developing + this. + + Documentation is sparse at the moment, sorry about that, and obviously I + did not really bother to package it or clean it up. I may or may not + work on this in the future. Basically, I made it, so why not release it? + + Contributors + ------------ + + - Me! Go me! + - Zach Wissner-Gross (2-card algorithm) + - arslr (Fixes for other Python versions) + - Jim Kelly (Help with packaging, additional documentation) + - hwmrocker (Improvements to Card constructor, Python 3 compatibility) + - radekj (Tests, Python 3 compatibility) +Platform: UNKNOWN diff --git a/packaging/windows/pypoker-eval-x64/pokereval.egg-info/SOURCES.txt b/packaging/windows/pypoker-eval-x64/pokereval.egg-info/SOURCES.txt new file mode 100644 index 000000000..57e2df59b --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/pokereval.egg-info/SOURCES.txt @@ -0,0 +1,17 @@ +CHANGES.txt +LICENSE.txt +MANIFEST.in +README.rst +files.txt +setup.cfg +setup.py +pokereval/__init__.py +pokereval/bug-1823.py +pokereval/compile.py +pokereval/pokereval.py +pokereval/sha256hash.py +pokereval/test.py +pokereval.egg-info/PKG-INFO +pokereval.egg-info/SOURCES.txt +pokereval.egg-info/dependency_links.txt +pokereval.egg-info/top_level.txt \ No newline at end of file diff --git a/packaging/windows/pypoker-eval-x64/pokereval.egg-info/dependency_links.txt b/packaging/windows/pypoker-eval-x64/pokereval.egg-info/dependency_links.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/pokereval.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/packaging/windows/pypoker-eval-x64/pokereval.egg-info/top_level.txt b/packaging/windows/pypoker-eval-x64/pokereval.egg-info/top_level.txt new file mode 100644 index 000000000..f9e1dc4ff --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/pokereval.egg-info/top_level.txt @@ -0,0 +1 @@ +pokereval diff --git a/packaging/windows/pypoker-eval-x64/pokereval/__init__.py b/packaging/windows/pypoker-eval-x64/pokereval/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packaging/windows/pypoker-eval-x64/pokereval/__init__.pyc b/packaging/windows/pypoker-eval-x64/pokereval/__init__.pyc new file mode 100644 index 000000000..f4d97dab7 Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/pokereval/__init__.pyc differ diff --git a/packaging/windows/pypoker-eval-x64/pokereval/_pokereval_2_7.pyd b/packaging/windows/pypoker-eval-x64/pokereval/_pokereval_2_7.pyd new file mode 100644 index 000000000..c287e8471 Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/pokereval/_pokereval_2_7.pyd differ diff --git a/packaging/windows/pypoker-eval-x64/pokereval/bug-1823.py b/packaging/windows/pypoker-eval-x64/pokereval/bug-1823.py new file mode 100644 index 000000000..7a367beef --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/pokereval/bug-1823.py @@ -0,0 +1,33 @@ +# +# Copyright (C) 2007, 2008 Loic Dachary +# +# This program 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. +# +# This program 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 +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +# +# http://gna.org/support/?1823 +# +import sys +sys.path.insert(0, ".") +sys.path.insert(0, ".libs") + +from pokereval import PokerEval + +pokereval = PokerEval() + +result = pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"]], dead = [], board = ["Ad", "Qs", "2c", "Ac", "Kc"]) +assert result == {'info': (990, 0, 1), 'eval': [{'winlo': 0, 'tielo': 0, 'winhi': 877, 'scoop': 877, 'loselo': 0, 'ev': 903, 'losehi': 78, 'tiehi': 35}, {'winlo': 0, 'tielo': 0, 'winhi': 78, 'scoop': 78, 'loselo': 0, 'ev': 96, 'losehi': 877, 'tiehi': 35}]} + +result = pokereval.poker_eval(game = "omaha8", fill_pockets = 1, pockets = [ ["As", "3s", "2s", "6s"], ["__", "__", "__", "__"]], dead = [], board = ["Ad", "Qs", "2c", "7c", "5c"]) +assert result == {'info': (123410, 1, 1), 'eval': [{'winlo': 109375, 'tielo': 5361, 'winhi': 73190, 'scoop': 69661, 'loselo': 8674, 'ev': 753, 'losehi': 48978, 'tiehi': 1242}, {'winlo': 8674, 'tielo': 5361, 'winhi': 48978, 'scoop': 8674, 'loselo': 68788, 'ev': 246, 'losehi': 73190, 'tiehi': 1242}]} + diff --git a/packaging/windows/pypoker-eval-x64/pokereval/bug-1823.pyc b/packaging/windows/pypoker-eval-x64/pokereval/bug-1823.pyc new file mode 100644 index 000000000..5ce6131e6 Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/pokereval/bug-1823.pyc differ diff --git a/packaging/windows/pypoker-eval-x64/pokereval/compile.py b/packaging/windows/pypoker-eval-x64/pokereval/compile.py new file mode 100644 index 000000000..bc5389291 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/pokereval/compile.py @@ -0,0 +1,2 @@ +import py_compile +py_compile.compile('pokereval.py') \ No newline at end of file diff --git a/packaging/windows/pypoker-eval-x64/pokereval/pokereval.py b/packaging/windows/pypoker-eval-x64/pokereval/pokereval.py new file mode 100644 index 000000000..12ba9c48f --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/pokereval/pokereval.py @@ -0,0 +1,332 @@ +# +# Copyright (C) 2007, 2008 Loic Dachary +# Copyright (C) 2004, 2005, 2006 Mekensleep +# +# Mekensleep +# 24 rue vieille du temple +# 75004 Paris +# licensing@mekensleep.com +# +# This program 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. +# +# This program 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 +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Authors: +# Loic Dachary +# +# +import sys +_pokereval = __import__('_pokereval_2_7') + +from types import * + +class PokerEval: + """\ +Evaluate the strengh of a poker hand for a given poker variant. +In all methods, when a list of cards is to be provided (for instance +with the "hand" argument of the "best" method), each member of the +list may be a number or a string designating a card according to +the following table: + + 2h/00 2d/13 2c/26 2s/39 + 3h/01 3d/14 3c/27 3s/40 + 4h/02 4d/15 4c/28 4s/41 + 5h/03 5d/16 5c/29 5s/42 + 6h/04 6d/17 6c/30 6s/43 + 7h/05 7d/18 7c/31 7s/44 + 8h/06 8d/19 8c/32 8s/45 + 9h/07 9d/20 9c/33 9s/46 + Th/08 Td/21 Tc/34 Ts/47 + Jh/09 Jd/22 Jc/35 Js/48 + Qh/10 Qd/23 Qc/36 Qs/49 + Kh/11 Kd/24 Kc/37 Ks/50 + Ah/12 Ad/25 Ac/38 As/51 + +The string __ (two underscore) or the number 255 are placeholders +meaning that the card is unknown. +""" + + def best(self, side, hand, board = []): + """\ +Return the best five card combination that can be made with the cards +listed in "hand" and, optionally, board. The "side" may be "hi" or +"low". The "board" argument must only be provided for variants where +knowing if a given card is taken from the board or not is significant +(such as Omaha but not Holdem). + +A list is returned. The first element is the numerical value +of the hand (better hands have higher values if "side" is "hi" and +lower values if "side" is "low"). The second element is a list whose +first element is the strength of the hand among the following: + +Nothing (only if "side" equals "low") +NoPair +TwoPair +Trips +Straight +Flush +FlHouse +Quads +StFlush + +The last five elements are numbers describing the best hand properly +sorted (for instance the ace is at the end for no pair if "side" is low or +at the beginning if "side" high). + +Examples: + +[134414336, ['StFlush', 29, 28, 27, 26, 38]] is the wheel five to ace, clubs +[475920, ['NoPair', 45, 29, 41, 39, 51]] is As, 8s, 5c, 4s, 2s +[268435455, ['Nothing']] means there is no qualifying low +""" + if len(hand + board) >= 5: + return _pokereval.eval_hand(side, hand, board) + else: + return False + + def best_hand(self, side, hand, board = []): + """\ +Return the best five card combination that can be made with the cards +listed in "hand" and, optionaly, board. The "side" may be "hi" or +"low". The returned value is the second element of the list returned +by the "best" method. +""" + if len(hand + board) >= 5: + return _pokereval.eval_hand(side, hand, board)[1] + else: + return False + + def best_hand_value(self, side, hand, board = []): + """\ +Return the best five card combination that can be made with the cards +listed in "hand" and, optionaly, board. The "side" may be "hi" or +"low". The returned value is the first element of the list returned +by the "best" method. +""" + if len(hand + board) >= 5: + return _pokereval.eval_hand(side, hand, board)[0] + else: + return False + + def evaln(self, cards): + """\ +Call the poker-eval Hand_EVAL_N function with the "cards" argument. +Return the strength of the "cards" as a number. The higher the +better. +""" + return _pokereval.evaln(cards) + + def winners(self, *args, **kwargs): + """\ +Return a list of the indexes of the best hands, relative to the "pockets" +keyword argument. For instance, if the first pocket and third pocket cards +tie, the list would be [0, 2]. Since there may be more than one way to +win a hand, a hash is returned with the list of the winners for each so +called side. For instace {'hi': [0], 'low': [1]} means pocket cards +at index 0 won the high side of the hand and pocket cards at index 1 +won the low side. + +See the"poker_eval" method for a detailed +explanation of the semantics of the arguments. + +If the keyword argument "fill_pockets" is set, pocket cards +can contain a placeholder (i.e. 255 or __) that will be be +used as specified in the "poker_eval" method documentation. + +If the keyword argument "fill_pockets" is not set, pocket cards +that contain at least one placeholder (i.e. 255 or __) are +ignored completly. For instance if winners is called as follows +o.winners(game = 'holdem', pockets = [ [ '__', 'As' ], [ 'Ks', 'Kd'] ]) +it is strictly equivalent as calling +o.winners(game = 'holdem', pockets = [ [ 'Ks', 'Kd'] ]). +""" + index2index = {} + normalized_pockets = [] + normalized_index = 0 + pockets = kwargs["pockets"][:] + for index in xrange(len(pockets)): + if "fill_pockets" not in kwargs: + if 255 in pockets[index] or "__" in pockets[index]: + pockets[index] = [] + + if pockets[index] != []: + normalized_pockets.append(pockets[index]) + index2index[index] = normalized_index + normalized_index += 1 + kwargs["pockets"] = normalized_pockets + + results = _pokereval.poker_eval(*args, **kwargs) + + (count, haslopot, hashipot) = results.pop(0) + winners = { 'low': [], 'hi': [] } + for index in xrange(len(pockets)): + if index in index2index: + result = results[index2index[index]] + if result[1] == 1 or result[3] == 1: + winners["hi"].append(index) + if result[4] == 1 or result[6] == 1: + winners["low"].append(index) + + if not haslopot or len(winners["low"]) == 0: + del winners["low"] + if not hashipot: + del winners["hi"] + return winners + + def poker_eval(self, *args, **kwargs): + """\ +Provided with a description of a poker game, return the outcome (if at showdown) or +the expected value of each hand. The poker game description is provided as a set +of keyword arguments with the following meaning: + +game : the variant (holdem, holdem8, omaha, omaha8, 7stud, 7stud8, razz, + 5draw, 5draw8, 5drawnsq, lowball, lowball27). + Mandatory, no default. + +pockets : list of pocket cards for each player still in game. Each member + of the list is a list of cards. The position of the pocket cards + in the list is meaningfull for the value returned will refer to + this position when stating which player wins, tie or loose. + Example: [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]] + Cards do not have to be real cards like "tc" or "4s". They may also be a + placeholder, denoted by "__" or 255. When using placeholders, the + keyword argument "iterations" may be specified to use Monte Carlo instead of + exhaustive exploration of all the possible combinations. + Example2: [ ["tc", "__"], [255, "ah"], ["8c", "6h"]] + + Mandatory, no default. + +board : list of community cards, for games where this is meaningfull. If + specified when irrelevant, the return value cannot be predicted. + Default: [] + +dead : list of dead cards. These cards won't be accounted for when exloring + the possible hands. + Default: [] + +iterations: the maximum number of iterations when exploring the + possible outcome of a given hand. Roughly speaking, each + iteration means to distribute cards that are missing (for + which there are place holders in the board or pockets + keywords arguments, i.e. 255 or __). If the number of + iterations is not specified and there are place holders, + the return value cannot be predicted. + Default: +infinite (i.e. exhaustive exploration) + +Example: object.poker_eval(game = "holdem", + pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], + dead = [], + board = ["7h", "3s", "2c"]) + +The return value is a map of two entries: +'info' contains three integers: + - the number of samples (which must be equal to the number of iterations given + in argument). + - 1 if the game has a low side, 0 otherwise + - 1 if the game has a high side, 0 otherwise +'eval' is a list of as many maps as there are pocket cards, each +made of the following entries: + 'scoop': the number of time these pocket cards scoop + 'winhi': the number of time these pocket cards win the high side + 'losehi': the number of time these pocket cards lose the high side + 'tiehi': the number of time these pocket cards tie for the high side + 'winlo': the number of time these pocket cards win the low side + 'loselo': the number of time these pocket cards lose the low side + 'tielo': the number of time these pocket cards tie for the low side + 'ev': the EV of these pocket cards as an int in the range [0,1000] with + 1000 being the best. + +It should be clear that if there is only one sample (i.e. because all the +cards are known which is the situation that occurs at showdown) the details +provided by the 'eval' entry is mostly irrelevant and the caller might +prefer to call the winners method instead. +""" + result = _pokereval.poker_eval(*args, **kwargs) + return { + 'info': result[0], + 'eval': [ { 'scoop': x[0], + 'winhi': x[1], + 'losehi': x[2], + 'tiehi': x[3], + 'winlo': x[4], + 'loselo': x[5], + 'tielo': x[6], + 'ev': int(x[7] * 1000) } for x in result[1:] ] + } + + def deck(self): + """\ +Return the list of all cards in the deck. +""" + return [ self.string2card(i + j) for i in "23456789TJQKA" for j in "hdcs" ] + + def nocard(self): + """Return 255, the numerical value of a place holder in a list of cards.""" + return 255 + + def string2card(self, cards): + """\ +Convert card names (strings) to card numbers (integers) according to the +following map: + + 2h/00 2d/13 2c/26 2s/39 + 3h/01 3d/14 3c/27 3s/40 + 4h/02 4d/15 4c/28 4s/41 + 5h/03 5d/16 5c/29 5s/42 + 6h/04 6d/17 6c/30 6s/43 + 7h/05 7d/18 7c/31 7s/44 + 8h/06 8d/19 8c/32 8s/45 + 9h/07 9d/20 9c/33 9s/46 + Th/08 Td/21 Tc/34 Ts/47 + Jh/09 Jd/22 Jc/35 Js/48 + Qh/10 Qd/23 Qc/36 Qs/49 + Kh/11 Kd/24 Kc/37 Ks/50 + Ah/12 Ad/25 Ac/38 As/51 + +The "cards" argument may be either a list in which case a converted list +is returned or a string in which case the corresponding number is +returned. +""" + if type(cards) is ListType or type(cards) is TupleType: + return [ _pokereval.string2card(card) for card in cards ] + else: + return _pokereval.string2card(cards) + + def card2string(self, cards): + """\ +Convert card numbers (integers) to card names (strings) according to the +following map: + + 2h/00 2d/13 2c/26 2s/39 + 3h/01 3d/14 3c/27 3s/40 + 4h/02 4d/15 4c/28 4s/41 + 5h/03 5d/16 5c/29 5s/42 + 6h/04 6d/17 6c/30 6s/43 + 7h/05 7d/18 7c/31 7s/44 + 8h/06 8d/19 8c/32 8s/45 + 9h/07 9d/20 9c/33 9s/46 + Th/08 Td/21 Tc/34 Ts/47 + Jh/09 Jd/22 Jc/35 Js/48 + Qh/10 Qd/23 Qc/36 Qs/49 + Kh/11 Kd/24 Kc/37 Ks/50 + Ah/12 Ad/25 Ac/38 As/51 + +The "cards" argument may be either a list in which case a converted list +is returned or an integer in which case the corresponding string is +returned. +""" + if type(cards) is ListType or type(cards) is TupleType: + return [ _pokereval.card2string(card) for card in cards ] + else: + return _pokereval.card2string(cards) + diff --git a/packaging/windows/pypoker-eval-x64/pokereval/pokereval.pyc b/packaging/windows/pypoker-eval-x64/pokereval/pokereval.pyc new file mode 100644 index 000000000..39e793249 Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/pokereval/pokereval.pyc differ diff --git a/packaging/windows/pypoker-eval-x64/pokereval/sha256hash.py b/packaging/windows/pypoker-eval-x64/pokereval/sha256hash.py new file mode 100644 index 000000000..b1bbfc2f4 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/pokereval/sha256hash.py @@ -0,0 +1,9 @@ +# Python program to find SHA256 hash string of a file +import hashlib; +import base64; +print( + base64.urlsafe_b64encode( + hashlib.sha256(open('_pokereval_2_4.pyd', 'rb').read()).digest()) + .decode('latin1') + .rstrip(b'=') + ) \ No newline at end of file diff --git a/packaging/windows/pypoker-eval-x64/pokereval/test.py b/packaging/windows/pypoker-eval-x64/pokereval/test.py new file mode 100644 index 000000000..ad8fec4f0 --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/pokereval/test.py @@ -0,0 +1,178 @@ +# +# Copyright (C) 2007, 2008 Loic Dachary +# Copyright (C) 2004, 2005, 2006 Mekensleep +# +# Mekensleep +# 24 rue vieille du temple +# 75004 Paris +# licensing@mekensleep.com +# +# This program 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. +# +# This program 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 +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Authors: +# Loic Dachary +# +# +import sys +sys.path.insert(0, ".") +sys.path.insert(0, ".libs") + +from pokereval import PokerEval + +iterations_low = 100000 +iterations_high = 200000 + +pokereval = PokerEval() + +if pokereval.best_hand_value("hi", ["Ah", "Ad", "As", "Kh", "Ks" ]) != 101494784: + sys.exit(1) + +if pokereval.string2card("2h") != 0: + sys.exit(1) + +print "" +pockets = [ ["As", "Ad", "Ac", "Tc", "Ts", "2d", "5c" ], + ["Js", "Jc", "7s", "8c", "8d", "3c", "3h" ], + [255, 255 ] ] +print "stud7 (1) result = %s\n" % pokereval.winners(game = "7stud", pockets = pockets, dead = [], board = []) + +pockets = [[22, 18, 21, 3, 41, 1, 30], [39, 255, 255, 15, 13, 17, 255]] +print "stud7 (2) result = %s\n" % pokereval.winners(game = "7stud", pockets = pockets, dead = [], board = []) + +print [ j + i + "/%d" % pokereval.string2card(j + i) for i in "hdcs" for j in "23456789TJQKA" ] +print "deck = %s\n" % pokereval.deck() + +print "result = %s\n" % pokereval.poker_eval(game = "holdem", pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c"]) +print "winners = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac"], ["3h", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c"]) + +print "result = %s\n" % pokereval.poker_eval(game = "holdem", pockets = [ ["tc", "ac"], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) +print "winners = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac"], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) + +print "winners (filthy pockets) = %s\n" % pokereval.winners(game = "holdem", pockets = [ ["tc", "ac", 255], [], [255, 255], ["th", "ah"], ["8c", "6h"]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) + +print "winners omaha = %s\n" % pokereval.winners(game = "omaha", pockets = [ ["tc", "ac", "ks", "kc" ], ["th", "ah", "qs", "qc" ], ["8c", "6h", "js", "jc" ]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) +print "winners omaha8 = %s\n" % pokereval.winners(game = "omaha8", pockets = [ ["tc", "ac", "ks", "kc" ], ["th", "ah", "qs", "qc" ], ["8c", "6h", "js", "jc" ]], dead = [], board = ["7h", "3s", "2c", "7s", "7d"]) + +hand = ["Ac", "As", "Td", "7s", "7h", "3s", "2c"] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ["Ah", "Ts", "Kh", "Qs", "Js" ] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ["2h", "Kh", "Qh", "Jh", "Th" ] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['2s', '3s', 'Jd', 'Ks', 'As', '4d', '5h', '7d', '9c'] +best_hand = pokereval.best_hand("hi", hand) +print "best hand from %s = %s" % ( hand, pokereval.best_hand("hi", hand) ) +print "best hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['As', '2s', '4d', '4s', '5c', '5d', '7s'] +best_hand = pokereval.best_hand("low", hand) +print "1/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) ) +print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['As', '2s', '4d', '4s', '5c', '5d', '8s'] +best_hand = pokereval.best_hand("low", hand) +print "2/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) ) +print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +hand = ['7d', '6c', '5h', '4d', 'As'] +best_hand = pokereval.best_hand("low", hand) +print "3/ low hand from %s = %s" % ( hand, pokereval.best("low", hand) ) +print "best low hand from %s = (%s) %s " % (hand, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'As', '4d', '5h', '7d', '9c' ] +hand = [ '2s', 'Ts', 'Jd', 'Ks' ] +best_hand = pokereval.best_hand("low", hand, board) +print "4/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'As', '4d', '6h', '7d', '3c' ] +hand = [ '2s', '5s', 'Jd', 'Ks' ] +best_hand = pokereval.best_hand("low", hand, board) +print "low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'Jc', '4c', '3c', '5c', '9c' ] +hand = [ '2c', 'Ac', '5h', '9d' ] +best_hand = pokereval.best_hand("hi", hand, board) +print "hi hand from %s / %s = %s" % ( hand, board, pokereval.best("hi", hand, board) ) +print "best hi hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], pokereval.card2string(best_hand[1:])) + +print "" +board = [ 'Jd', '9c', 'Jc', 'Tc', '2h' ] +hand = [ '2c', '4c', 'Th', '6s' ] +best_hand = pokereval.best_hand("low", hand, board) +print "5/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +print "" +board = [ 'Ks', 'Jd', '7s', '4d', 'Js' ] +hand = [ '2d', '6c', 'Ac', '5c' ] +best_hand = pokereval.best_hand("low", hand, board) +print "6/ low hand from %s / %s = %s" % ( hand, board, pokereval.best("low", hand, board) ) +print "best low hand from %s / %s = (%s) %s " % (hand, board, best_hand[0], [ pokereval.card2string(i) for i in best_hand[1:] ]) + +if len(sys.argv) > 2: + + print "f0 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "Qs", "2c", "Ac", "Kc"]) + + print "" + print "f1 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["7s", "Qs", "2c", "Ac", "Kc"]) + + + print "" + print "f2 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_low, pockets = [ ["As", "3s"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f3 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["As", "Ac"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f4 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["As", "Ks"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f5 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["2s", "2c"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f6 result = %s\n" % pokereval.poker_eval(game = "holdem", fill_pockets = 1, iterations = iterations_high, pockets = [ ["Js", "Jc"], ["__", "__"], ["__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + + print "" + print "f7 result = %s\n" % pokereval.poker_eval(game = "omaha", fill_pockets = 1, iterations = iterations_high, pockets = [ ["Js", "Jc", "7s", "8c"], ["__", "__", "__", "__"], ["__", "__", "__", "__"]], dead = [], board = ["__", "__", "__", "__", "__"]) + +print "" +hand = ['As', 'Ad'] +print "handval %s = %d " % (hand, pokereval.evaln(hand)) + +print "" +hand = ['Qc', '7d'] +print "handval %s = %d " % (hand, pokereval.evaln(hand)) + +pokereval = None diff --git a/packaging/windows/pypoker-eval-x64/pokereval/test.pyc b/packaging/windows/pypoker-eval-x64/pokereval/test.pyc new file mode 100644 index 000000000..3f13a475a Binary files /dev/null and b/packaging/windows/pypoker-eval-x64/pokereval/test.pyc differ diff --git a/packaging/windows/pypoker-eval-x64/setup.cfg b/packaging/windows/pypoker-eval-x64/setup.cfg new file mode 100644 index 000000000..8bfd5a12f --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/setup.cfg @@ -0,0 +1,4 @@ +[egg_info] +tag_build = +tag_date = 0 + diff --git a/packaging/windows/pypoker-eval-x64/setup.py b/packaging/windows/pypoker-eval-x64/setup.py new file mode 100644 index 000000000..6cbe92a6d --- /dev/null +++ b/packaging/windows/pypoker-eval-x64/setup.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +from setuptools import setup + +setup( + name='pokereval', + version='0.2.0', + author='Alvin Liang', + author_email='ayliang@gmail.com', + packages=['pokereval'], + url='https://github.com/aliang/pokerhand-eval', + license='Apache, see LICENSE.txt', + description='A pure python poker hand evaluator for 5, 6, 7 cards', + long_description=open('README.rst').read(), +)