pypokereval: fixes to allow py2exe to compile. Also, place win32 dependencies
in pyfpdb (pyfpdb files can be deleted when there is a site-package on win) This commit allows fpdb+pypokereval to work on win32 machines without having to manually install pypokereval files
This commit is contained in:
parent
ed7abda1b7
commit
46022509de
|
@ -68,7 +68,6 @@ import matplotlib
|
||||||
import shutil
|
import shutil
|
||||||
#from datetime import date
|
#from datetime import date
|
||||||
|
|
||||||
|
|
||||||
def isSystemDLL(pathname):
|
def isSystemDLL(pathname):
|
||||||
#dwmapi appears to be vista-specific file, not XP
|
#dwmapi appears to be vista-specific file, not XP
|
||||||
if os.path.basename(pathname).lower() in ("dwmapi.dll"):
|
if os.path.basename(pathname).lower() in ("dwmapi.dll"):
|
||||||
|
@ -120,6 +119,7 @@ pydir = rootdir+'pyfpdb/'
|
||||||
gfxdir = rootdir+'gfx/'
|
gfxdir = rootdir+'gfx/'
|
||||||
sys.path.append( pydir ) # allows fpdb modules to be found by options/includes below
|
sys.path.append( pydir ) # allows fpdb modules to be found by options/includes below
|
||||||
|
|
||||||
|
|
||||||
print "\n" + r"Output will be created in "+distdir
|
print "\n" + r"Output will be created in "+distdir
|
||||||
|
|
||||||
print "*** Cleaning working folders ***"
|
print "*** Cleaning working folders ***"
|
||||||
|
@ -142,6 +142,9 @@ setup(
|
||||||
{'script': pydir+'Configuration.py', }
|
{'script': pydir+'Configuration.py', }
|
||||||
],
|
],
|
||||||
|
|
||||||
|
console = [ {'script': pydir+'Stove.py', }
|
||||||
|
],
|
||||||
|
|
||||||
options = {'py2exe': {
|
options = {'py2exe': {
|
||||||
'packages' : ['encodings', 'matplotlib'],
|
'packages' : ['encodings', 'matplotlib'],
|
||||||
'includes' : ['gio', 'cairo', 'pango', 'pangocairo', 'atk', 'gobject'
|
'includes' : ['gio', 'cairo', 'pango', 'pangocairo', 'atk', 'gobject'
|
||||||
|
|
|
@ -1,177 +1,191 @@
|
||||||
pypokereval build for windows stepbystep guide
|
pypokereval build for windows stepbystep guide
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
Created by Gimick on 3rd December 2010
|
Created by Gimick on 3rd December 2010
|
||||||
|
|
||||||
This walkthrough is derived with the assistance of EricBlade and the build notes
|
This walkthrough is derived with the assistance of EricBlade and the build notes
|
||||||
supplied by Loic Dachary <loic@dachary.org> http://dachary.org/
|
supplied by Loic Dachary <loic@dachary.org> http://dachary.org/
|
||||||
|
|
||||||
Content is available under the the GNU Affero General Public License version 3
|
Content is available under the the GNU Affero General Public License version 3
|
||||||
|
|
||||||
|
|
||||||
0. Build environ
|
0. Build environ
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
We are building against the 2008 runtime because Python 2.6
|
We are building against the 2008 runtime because Python 2.6
|
||||||
has the same dependency (msvcr90.dll version 9.0.21022.8)
|
has the same dependency (msvcr90.dll version 9.0.21022.8)
|
||||||
|
|
||||||
Using winXPhome 32 bit
|
Using winXPhome 32 bit
|
||||||
|
|
||||||
1 Visual studio
|
1 Visual studio
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
1.1/ Get the ISO CD from here ... http://www.microsoft.com/express/Downloads/#2008-All
|
1.1/ Get the ISO CD from here ... http://www.microsoft.com/express/Downloads/#2008-All
|
||||||
|
|
||||||
1.2/ Run and install Visual C++ only, don't bother with the additional packages offered
|
1.2/ Run and install Visual C++ only, don't bother with the additional packages offered
|
||||||
|
|
||||||
This package will run 30 days before registration is needed
|
This package will run 30 days before registration is needed
|
||||||
|
|
||||||
2. Python runtime
|
2. Python runtime
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
2.1/ Install python runtime from here ...
|
2.1/ Install python runtime from here ...
|
||||||
|
|
||||||
Python 2.6.5 ... http://www.python.org/ftp/python/2.6.5/python-2.6.5.msi
|
Python 2.6.5 ... http://www.python.org/ftp/python/2.6.5/python-2.6.5.msi
|
||||||
|
|
||||||
3. Source install
|
3. Source install
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
3.1/ grab sources from here
|
3.1/ grab sources from here
|
||||||
|
|
||||||
pypoker-eval v138 ... http://download.gna.org/pokersource/sources/pypoker-eval-138.0.tar.gz
|
pypoker-eval v138 ... http://download.gna.org/pokersource/sources/pypoker-eval-138.0.tar.gz
|
||||||
poker-eval v138 ... http://download.gna.org/pokersource/sources/poker-eval-138.0.tar.gz
|
poker-eval v138 ... http://download.gna.org/pokersource/sources/poker-eval-138.0.tar.gz
|
||||||
|
|
||||||
3.2/ unpack and place the pypoker-eval-138 directory in c:\
|
3.2/ unpack and place the pypoker-eval-138 directory in c:\
|
||||||
3.2.1/ rename to pypoker-eval
|
3.2.1/ rename to pypoker-eval
|
||||||
|
|
||||||
3.3/ unpack and place the poker-eval-138 directory in c:\
|
3.3/ unpack and place the poker-eval-138 directory in c:\
|
||||||
3.3.1/ rename to poker-eval
|
3.3.1/ rename to poker-eval
|
||||||
|
|
||||||
Important: the build will fail with bizarre missing header files if the project is placed
|
Important: the build will fail with bizarre missing header files if the project is placed
|
||||||
in a directory containing a space character - you have been warned!
|
in a directory containing a space character - you have been warned!
|
||||||
|
|
||||||
4. Update source file
|
4. Update source file
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
4.1/ dos> write c:/pypoker-eval/pypokereval.c
|
4.1/ dos> write c:/pypoker-eval/pypokereval.c
|
||||||
|
|
||||||
change this:
|
change this:
|
||||||
|
|
||||||
#define VERSION_NAME(W) W##2_4
|
#define VERSION_NAME(W) W##2_4
|
||||||
#define PYTHON_VERSION "2_4"
|
#define PYTHON_VERSION "2_4"
|
||||||
|
|
||||||
to be this:
|
to be this:
|
||||||
|
|
||||||
#define VERSION_NAME(W) W##2_6
|
#define VERSION_NAME(W) W##2_6
|
||||||
#define PYTHON_VERSION "2_6"
|
#define PYTHON_VERSION "2_6"
|
||||||
|
|
||||||
4.2/ save and exit
|
4.2/ save and exit
|
||||||
|
|
||||||
5. Build pre-preparation
|
4.3/ dos> write c:/pypoker-eval/pokereval.py
|
||||||
------------------------
|
|
||||||
|
Comment-out this line:
|
||||||
(Here we are converting the two project definition files to 2008)
|
|
||||||
|
_pokereval = __import__('_pokereval_' + sys.version[0] + '_' + sys.version[2])
|
||||||
5.1 navigate to directory c:/poker-eval
|
|
||||||
5.1.1 double click poker-eval.vcproj
|
Insert this one in its' place:
|
||||||
5.1.2 Visual studio will launch and make a conversion - accept all defaults
|
|
||||||
5.1.3 exit and save
|
import _pokereval_2_6 as _pokereval
|
||||||
|
|
||||||
5.2 navigate to directory c:/pypoker-eval
|
|
||||||
5.2.1 double click pypoker-eval.vcproj
|
4.4/ save and exit
|
||||||
5.2.2 Visual studio will launch and make a conversion - accept all defaults
|
|
||||||
5.2.3 exit
|
|
||||||
|
5. Build pre-preparation
|
||||||
6. build preparation
|
------------------------
|
||||||
--------------------
|
|
||||||
|
(Here we are converting the two project definition files to 2008)
|
||||||
6.2 navigate to directory c:/pypoker-eval
|
|
||||||
6.2.1 double click pypoker-eval.vcproj - visual studio should launch
|
5.1 navigate to directory c:/poker-eval
|
||||||
|
5.1.1 double click poker-eval.vcproj
|
||||||
6.2.3 Select Build...configuration manager...
|
5.1.2 Visual studio will launch and make a conversion - accept all defaults
|
||||||
Select "active solution configuration" to "Release"
|
5.1.3 exit and save
|
||||||
(The configuration for both projects will change to "Release")
|
|
||||||
|
5.2 navigate to directory c:/pypoker-eval
|
||||||
6.2.3 Close the configuration manager
|
5.2.1 double click pypoker-eval.vcproj
|
||||||
|
5.2.2 Visual studio will launch and make a conversion - accept all defaults
|
||||||
6.2.4 In the solution explorer window, hilight pythonpoker-eval / right mouse / properties...
|
5.2.3 exit
|
||||||
|
|
||||||
6.2.5 In the pythonpoker-eval properties dialog,
|
6. build preparation
|
||||||
|
--------------------
|
||||||
change references to "python24" to "python26" in the following:
|
|
||||||
|
6.2 navigate to directory c:/pypoker-eval
|
||||||
= C/C++/Additional Include Directories/
|
6.2.1 double click pypoker-eval.vcproj - visual studio should launch
|
||||||
= linker/general/Additional library directories
|
|
||||||
= linker/input/Additional Dependencies
|
6.2.3 Select Build...configuration manager...
|
||||||
|
Select "active solution configuration" to "Release"
|
||||||
Change the following
|
(The configuration for both projects will change to "Release")
|
||||||
|
|
||||||
= linker/generate debug info - set to No
|
6.2.3 Close the configuration manager
|
||||||
= linker/debugging/Generate debug info - set to No
|
|
||||||
|
6.2.4 In the solution explorer window, hilight pythonpoker-eval / right mouse / properties...
|
||||||
6.2.6 Apply all changes to the properties dialog and close
|
|
||||||
|
6.2.5 In the pythonpoker-eval properties dialog,
|
||||||
6.3 Exit from visual studio
|
|
||||||
|
change references to "python24" to "python26" in the following:
|
||||||
7. Build poker eval
|
|
||||||
-------------------
|
= C/C++/Additional Include Directories/
|
||||||
|
= linker/general/Additional library directories
|
||||||
7.1 navigate to directory c:/poker-eval
|
= linker/input/Additional Dependencies
|
||||||
7.1.1 double click poker-eval.vcproj
|
|
||||||
7.1.2 Visual studio will launch
|
Change the following
|
||||||
|
|
||||||
7.2 In the solution explorer window, hilight poker-eval / right mouse / build
|
= linker/generate debug info - set to No
|
||||||
|
= linker/debugging/Generate debug info - set to No
|
||||||
7.3 There should be no errors
|
|
||||||
|
6.2.6 Apply all changes to the properties dialog and close
|
||||||
7.4 Exit from visual studio
|
|
||||||
|
6.3 Exit from visual studio
|
||||||
|
|
||||||
8. Build pypoker eval
|
7. Build poker eval
|
||||||
---------------------
|
-------------------
|
||||||
|
|
||||||
8.1 navigate to directory c:/pypoker-eval
|
7.1 navigate to directory c:/poker-eval
|
||||||
8.1.1 double click pypoker-eval.vcproj
|
7.1.1 double click poker-eval.vcproj
|
||||||
8.1.2 Visual studio will launch
|
7.1.2 Visual studio will launch
|
||||||
|
|
||||||
8.2 In the solution explorer window, hilight pythonpoker-eval / right mouse / build
|
7.2 In the solution explorer window, hilight poker-eval / right mouse / build
|
||||||
|
|
||||||
8.3 There should be no errors (but a few warnings)
|
7.3 There should be no errors
|
||||||
|
|
||||||
8.4 Exit from visual studio
|
7.4 Exit from visual studio
|
||||||
|
|
||||||
9. packaging
|
|
||||||
------------
|
8. Build pypoker eval
|
||||||
|
---------------------
|
||||||
9.1 Navigate to c:/pypoker-eval/release
|
|
||||||
9.2 the output file is pypokereval.dll
|
8.1 navigate to directory c:/pypoker-eval
|
||||||
9.3 rename this file to _pokereval_2_6.pyd
|
8.1.1 double click pypoker-eval.vcproj
|
||||||
|
8.1.2 Visual studio will launch
|
||||||
9.4 create a zip file containing :
|
|
||||||
|
8.2 In the solution explorer window, hilight pythonpoker-eval / right mouse / build
|
||||||
_pokereval_2_6.pyd from releases
|
|
||||||
test.py from pypoker-eval-138.0
|
8.3 There should be no errors (but a few warnings)
|
||||||
pokereval.py from pypoker-eval-138.0
|
|
||||||
poker-eval.vcproj from c:\poker-eval
|
8.4 Exit from visual studio
|
||||||
pypoker-eval.vcproj from c:\pypoker-eval
|
|
||||||
pypokereval.c from c:\pypoker-eval
|
9. packaging
|
||||||
|
------------
|
||||||
Remember to include the version (138), python 265 and win32 in the package filename
|
|
||||||
|
9.1 Navigate to c:/pypoker-eval/release
|
||||||
10. Installation and Testing
|
9.2 the output file is pypokereval.dll
|
||||||
----------------------------
|
9.3 rename this file to _pokereval_2_6.pyd
|
||||||
|
|
||||||
Python 2.6.5 must be installed
|
9.4 create a zip file containing :
|
||||||
|
|
||||||
10.1 Extract this package to directory
|
_pokereval_2_6.pyd from releases
|
||||||
10.2 Change directory to the directory in 10.1
|
test.py from pypoker-eval-138.0
|
||||||
10.3 execute dos> c:\Python26\python.exe test.py
|
pokereval.py from pypoker-eval-138.0
|
||||||
10.4 hand-output should scroll down the screen
|
poker-eval.vcproj from c:\poker-eval
|
||||||
10.5 start the python interpreter
|
pypoker-eval.vcproj from c:\pypoker-eval
|
||||||
10.6 >>> import pokereval
|
pypokereval.c from c:\pypoker-eval
|
||||||
10.7 No errors should be seen
|
|
||||||
|
Remember to include the version (138), python 265 and win32 in the package filename
|
||||||
|
|
||||||
|
10. Installation and Testing
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Python 2.6.5 must be installed
|
||||||
|
|
||||||
|
10.1 Extract this package to directory
|
||||||
|
10.2 Change directory to the directory in 10.1
|
||||||
|
10.3 execute dos> c:\Python26\python.exe test.py
|
||||||
|
10.4 hand-output should scroll down the screen
|
||||||
|
10.5 start the python interpreter
|
||||||
|
10.6 >>> import pokereval
|
||||||
|
10.7 No errors should be seen
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
pyfpdb/_pokereval_2_6.pyd
Normal file
BIN
pyfpdb/_pokereval_2_6.pyd
Normal file
Binary file not shown.
338
pyfpdb/pokereval.py
Normal file
338
pyfpdb/pokereval.py
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007, 2008 Loic Dachary <loic@dachary.org>
|
||||||
|
# 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 <loic@dachary.org>
|
||||||
|
#
|
||||||
|
#
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# for fpdb alter the following line from __import__ to import...as... .
|
||||||
|
# fpdb py2exe package build does no recognise __import__ statement,
|
||||||
|
# and fails at runtime with _pokereval_2_6 not found
|
||||||
|
|
||||||
|
#_pokereval = __import__('_pokereval_' + sys.version[0] + '_' + sys.version[2])
|
||||||
|
import _pokereval_2_6 as _pokereval
|
||||||
|
|
||||||
|
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 not kwargs.has_key("fill_pockets"):
|
||||||
|
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 index2index.has_key(index):
|
||||||
|
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)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user