In [1]:
%pylab inline
from matplotlib import font_manager as fm
import matplotlib as mpl
import pandas as pd
import requests
from pokereval import PokerEval
pokereval=PokerEval()
from bs4 import  BeautifulSoup
from IPython.html.widgets import interact, fixed
from IPython.html import widgets
from IPython.display import HTML, YouTubeVideo, Image
plt.rc('xtick', labelsize=30)
plt.rc('ytick', labelsize=30)
plt.rc('lines', linewidth=5)
plt.rc('figure', figsize=[14.0, 10.0])
plt.rc('font', family=["Microsoft JhengHei"])
plt.rcParams['text.usetex']=False
def pretty_card(c):
    return c[0]+'$\\'+{'h': 'heart', 'd':'diamond', 's':'spade', 'c':'club'}[c[1].lower()]+'suit$'
def pretty_cards(cards):
    return " ".join(map(pretty_card, cards))
def str2cards(s):
    if type(s) is str:
        return [s[i:i+2] for i in range(0, len(s),2)]
    else:
        return list(s)
def poker_eval(pockets, board, **kw):
    pockets = [str2cards(x) for x in pockets]
    board = str2cards(board)
    img_style = "float: left; width: 12%; margin-right: 1%; margin-bottom: 0em;margin-top: 0em"
    result = pokereval.poker_eval(game='holdem', fill_pockets=1, pockets=pockets, board=board, **kw)
    sizes = [x['ev'] for x in result['eval']]
    labels = [pretty_cards(x) for x in pockets]
    prop = fm.FontProperties()
    prop.set_size(30)
    explode = (0.1,)+(0,)*(len(pockets)-1)
    pie = plt.pie(sizes, labels=labels, shadow=True, autopct="%2.2f%%", startangle=90, explode=explode)
    plt.axis("equal")
    plt.setp(pie[2], fontproperties=prop)
    display(HTML("<div>"+"".join('<img src="cards/%s.png" style="%s" />'%(b, img_style) for b in board if b!="__")+"</div>"))
    return sizes

def preflop(*pockets, **kw):
    return poker_eval(pockets=list(pockets), board=["__"]*5, **kw)

def show_html(html, noclass=False):
    if noclass and 'class' in html.attrs:
        html=BeautifulSoup(str(html)).body.contents[0]
        del html.attrs['class']
    display(HTML(str(html)))

def get_html(url):
    r = requests.get(url)
    soup = BeautifulSoup(r.content)
    for s in soup.findAll('span', attrs={'class':'sortkey'}):
        s.extract()
    return soup

def show_bio(name):
    url = 'http://en.wikipedia.org/wiki/'
    table = get_html(url+name).find('table', attrs={'class':'vcard'})
    table.attrs['style']='width: 80%'
    for img in table.findAll('img'):
        img.parent.attrs['class']='zoom_img'
    show_html(table)
Populating the interactive namespace from numpy and matplotlib
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-5cb8fc199956> in <module>()
      4 import pandas as pd
      5 import requests
----> 6 from pokereval import PokerEval
      7 pokereval=PokerEval()
      8 from bs4 import  BeautifulSoup

ImportError: No module named 'pokereval'

數學漫談 Week3

博奕科學與技術

魏澤人

Poker

In [2]:
html = get_html('http://en.wikipedia.org/wiki/World_Series_of_Poker')
show_html(html.find('h1'))

World Series of Poker

In [3]:
YouTubeVideo('P8SqtRTt4gM')
Out[3]:
In [4]:
YouTubeVideo('PklwYY3jWiw')
Out[4]:
In [5]:
YouTubeVideo('gD-FQBpT2o0')
Out[5]:
In [6]:
show_html(html.findAll('table')[2])
Year Winner Winning
hand
First place prize Entrants Runner-up Losing
hand
1970 Johnny Moss N/A N/A 7 N/A N/A
1971 Johnny Moss N/A 30,000 6 Walter "Puggy" Pearson N/A
1972 Thomas "Amarillo Slim" Preston, Jr. K J 80,000 8 Walter "Puggy" Pearson 6  6 
1973 Walter "Puggy" Pearson A 7 130,000 13 Johnny Moss K J
1974 Johnny Moss 3 3 160,000 16 Crandell Addington A 2
1975 Brian "Sailor" Roberts J J 210,000 21 Bob Hooks J 9
1976 Doyle Brunson 10 2 220,000 22 Jesse Alto A J
1977 Doyle Brunson 10 2 340,000 34 Gary Berland 8 5
1978 Bobby Baldwin Q Q 210,000 42 Crandell Addington 9 9
1979 Hal Fowler 7 6 270,000 54 Bobby Hoff A A
1980 Stu Ungar 5 4 385,000 73 Doyle Brunson A 7
1981 Stu Ungar A Q 375,000 75 Perry Green 10 9
1982 Jack Straus A 10 520,000 104 Dewey Tomko A 4
1983 Tom McEvoy Q Q 540,000 108 Rod Peate K J
1984 Jack Keller 10 10 660,000 132 Byron Wolford 6 4
1985 Bill Smith 3 3 700,000 140 T. J. Cloutier A 3
1986 Berry Johnston A 10 570,000 141 Mike Harthcock A 8
1987 Johnny Chan A 9 625,000 152 Frank Henderson 4♦ 4♣
1988 Johnny Chan J 9 700,000 167 Erik Seidel Q 7
1989 Phil Hellmuth, Jr. 9 9 755,000 178 Johnny Chan A 7
1990 Mansour Matloubi 6 6 895,000 194 Hans Lund 4 4
1991 Brad Daugherty K J 1,000,000 215 Don Holt 7 3
1992 Hamid Dastmalchi 8 4 1,000,000 201 Tom Jacobs J 7
1993 Jim Bechtel J 6 1,000,000 220 Glenn Cozen 7 4
1994 Russ Hamilton K 8 1,000,000 268 Hugh Vincent 8 5
1995 Dan Harrington 9 8 1,000,000 273 Howard Goldfarb A 7
1996 Huck Seed 9 8 1,000,000 295 Bruce Van Horn K 8
1997 Stu Ungar A 4 1,000,000 312 John Strzemp A 8
1998 Scotty Nguyen J 9 1,000,000 350 Kevin McBride Q 10
1999 Noel Furlong 5 5 1,000,000 393 Alan Goehring 6 6
2000 Chris Ferguson A 9 1,500,000 512 T. J. Cloutier A Q
2001 Juan Carlos Mortensen K Q 1,500,000 613 Dewey Tomko A A
2002 Robert Varkonyi Q 10 2,000,000 631 Julian Gardner J 8
2003 Chris Moneymaker 5 4 2,500,000 839 Sam Farha J 10
2004 Greg Raymer 8 8 5,000,000 2,576 David Williams A 4
2005 Joe Hachem 7 3 7,500,000 5,619 Steve Dannenmann A 3
2006 Jamie Gold Q 9 12,000,000 8,773 Paul Wasicka 10 10
2007 Jerry Yang 8 8 8,250,000 6,358 Tuan Lam A Q
2008 Peter Eastgate A 5 9,152,416 6,844 Ivan Demidov 4 2
2009 Joe Cada 9 9 8,547,042 6,494 Darvin Moon Q J
2010 Jonathan Duhamel A J 8,944,310 7,319 John Racener K 8
2011 Pius Heinz A K 8,715,638 6,865 Martin Staszko 10 7
2012 Greg Merson K 5 8,531,853 6,598 Jesse Sylvia Q J
2013 Ryan Riess A K 8,361,570 6,352 Jay Farber Q 5
2014 Martin Jacobson 10 10 10,000,000 6,683 Felix Stephensen A 9
In [7]:
winners = pd.read_html(str(html.findAll('table')), header=0)[2]
plt.title(r'$\alpha$')
bar(winners['Year'], winners['First place prize']);
In [3]:
trs = html.findAll('table')[2].findAll('tr')[1:]
yw = (row.findAll('td')[:2] for row in trs)
dic = {int(y.text): w.find('a').attrs['href'][6:] for y,w in yw} 
interact(lambda year:show_bio(dic[year]), year=(1970, 2015))   
Doyle Brunson
Doyle Brunson.jpg
Nickname(s) Texas Dolly, Big Papa, The Godfather of Poker
Residence Las Vegas, Nevada
Born (1933-08-10) August 10, 1933 (age 81)
Longworth, Fisher County, Texas
World Series of Poker
Bracelet(s) 10
Money finish(es) 36
Highest ITM
Main Event finish
Winner, 1976, 1977
World Poker Tour
Title(s) 1
Final table(s) 3
Money finish(es) 8
European Poker Tour
Title(s) None
Final table(s) None
Money finish(es) 1
Information accurate as of 24 January 2014.
In [36]:
preflop('QcQs', '5sTc');
In [37]:
preflop('AhQh', 'TdJd', 'KdKs', '7c6c');
In [40]:
poker_eval(['AhKh', 'TdJd'], '6d5c2d____');
In [60]:
1500+pr[1]*1500
Out[60]:
2011.3636363636363

Bluff

In [4]:
YouTubeVideo('6feMAMC5ysw')
Out[4]:
In [57]:
pr=poker_eval(['AhKd', '6s5s'], '4h7sQhAs__');

Semi Bluff

桌面上 500

AK 加注 500

你 all in 2000 還是跟 500

Fold 的話: $2000$

All in 的話:

$\Pr(Fold)\cdot3000+\Pr(Call)\cdot\Pr(Hit)\cdot4500$

Call 的話:

$1500+\Pr(Hit)\cdot(1500+\Pr(BetCall)\cdot1500)$

In [61]:
x=linspace(0,1)
plot(x, x*3000+(1-x)*pr[1]*4500)
plot(x, 1500+pr[1]*(1500+0*x))
plot(x, 1500+pr[1]*(1500+1500+0*x));
In [62]:
N = 100
m=np.zeros((N+1,N+1))
for i in range(N+1):
    for j in (0,N-i):
        m[i][j]=50*i/N+30*(N-i)/N
for i in range(N+1):
    m[0][i]=20
    
for l in range(2000):
    m2 = m.copy()
    for i in range(1,N):
        for j in range(1,N-i):
            m2[i][j] = (m[i][j+1]+m[i][j-1]+m[i+1][j]+m[i-1][j]+m[i+1][j-1]+m[i-1][j+1])/6
    if l%100==0:
        __diff = (m2-m).max()
        if __diff==0:
            m=m2
            break
        print(l, __diff)
        print(min(m[i][j] for i in range(0,N+1) for j in range(0,N+1-i)))
    m=m2
0 33.1333333333
0.0
100 0.191652674808
0.00373924292691
200 0.0934212572944
0.365545515702
300 0.0609462414416
1.72924037993
400 0.0449286026246
3.8565166558
500 0.0357139759994
6.29140078676
600 0.030198177851
8.76786618848
700 0.0266516100608
11.1027452371
800 0.0238362071518
13.2249392642
900 0.021272126444
15.0969338955
1000 0.0188897825257
16.6972278868
1100 0.0167181199745
18.0221087785
1200 0.0147473513132
19.0594865184
1300 0.0129800089034
19.7776038819
1400 0.0114118195223
20.0
1500 0.0100235475072
20.0
1600 0.00880020054217
20.0
1700 0.00772209770097
20.0
1800 0.00677372473657
20.0
1900 0.00594047428689
20.0
In [63]:
Z=np.zeros((500,500))
for x in range(500):
    for y in range(500):
        β = y/500*2/sqrt(3)
        α = x/500-β/2
        if 0<=α+β<=1 and 0<=α<=1 and 0<=β<=1:
            Z[499-y,x]=  m[int(N*β)][int(N*α)]
im = plt.imshow(Z, cmap=cm.Dark2)

plt.colorbar(im);
In [68]:
print(m[50][25], m[50][50])
plot(m[50][0:51])
35.5049888419 40.0
Out[68]:
[<matplotlib.lines.Line2D at 0x10d63ce80>]
In [69]:
%pylab qt
from mpl_toolkits.mplot3d.axes3d import Axes3D
fig = plt.figure(figsize(14,6))
X,Y = meshgrid(arange(500),arange(500))
ax = fig.add_subplot(1,1,1,projection='3d')
p=ax.plot_surface(X,Y,Z, rstride=3, cstride=3, cmap=cm.coolwarm, linewidth=0)
Populating the interactive namespace from numpy and matplotlib

Blackjack

In [70]:
bjhtml = get_html('http://en.wikipedia.org/wiki/Blackjack')
show_html(bjhtml.findAll('table')[0])
Blackjack
BlackJack6.jpg
A blackjack
Alternative name(s) Twenty-One
Players 2+, usually 2–6
Skill(s) required Probability
Cards 52
Deck French
Play Clockwise
Random chance High
In [71]:
show_html(bjhtml.findAll('ul')[27])
In [72]:
show_html(bjhtml.findAll('table')[1])
Number of Decks House Advantage
Single deck 0.17%
Double deck 0.46%
Four decks 0.60%
Six decks 0.64%
Eight decks 0.65%
In [73]:
show_html(bjhtml.findAll('table')[2])
Player hand Dealer's face-up card
2 3 4 5 6 7 8 9 10 A
Hard totals (excluding pairs)
17–20 S S S S S S S S S S
16 S S S S S H H SU SU SU
15 S S S S S H H H SU H
13–14 S S S S S H H H H H
12 H H S S S H H H H H
11 Dh Dh Dh Dh Dh Dh Dh Dh Dh H
10 Dh Dh Dh Dh Dh Dh Dh Dh H H
9 H Dh Dh Dh Dh H H H H H
5–8 H H H H H H H H H H
Soft totals
2 3 4 5 6 7 8 9 10 A
A,8–A,9 S S S S S S S S S S
A,7 S Ds Ds Ds Ds S S H H H
A,6 H Dh Dh Dh Dh H H H H H
A,4–A,5 H H Dh Dh Dh H H H H H
A,2–A,3 H H H Dh Dh H H H H H
Pairs
2 3 4 5 6 7 8 9 10 A
A,A SP SP SP SP SP SP SP SP SP SP
10,10 S S S S S S S S S S
9,9 SP SP SP SP SP S SP SP S S
8,8 SP SP SP SP SP SP SP SP SP SP
7,7 SP SP SP SP SP SP H H H H
6,6 SP SP SP SP SP H H H H H
5,5 Dh Dh Dh Dh Dh Dh Dh Dh H H
4,4 H H H SP SP H H H H H
2,2–3,3 SP SP SP SP SP SP H H H H

Misc

機率

  • Girolamo Cardano 16th century
  • Pierre de Fermat and Blaise Pascal (1654).
  • Christiaan Huygens (1657) earliest known scientific treatment.
  • Jakob Bernoulli's Ars Conjectandi (posthumous, 1713) and Abraham de Moivre's Doctrine of Chances (1718)
  • Pierre-Simon Laplace (1774)

心理

  • Gambler’s Fallacy
  • Availability Error
  • Clustering Illusion (see pattern)
  • Ramsey Theory: "complete disorder is impossible"
  • Gambler’s Conceit: David Ewing
  • Illusion of Control

輪盤破解

  • Joseph Hobson Jagger , 1837 統計破解
  • Eudaemons 1978
  • J. Doyne Farmer and Norman Packard
  • "The Eudaemonic Pie“
  • The trio 2004
  • a Hungarian woman and two Serbian men
  • Laser, Cell Phone
  • 英國, 無罪

  • Martingale 1, 2, 4, 8, 16, ….
  • 贏要衝 輸要縮
  • 99.99% win $1.
  • Gambler’s ruin: A有 99 元,B有 1元,那麼 99% A贏,1% B贏。
  • Optional Sampling Theorem (Doob 1953).
  • 在賭客或者賭場資金有限的前提下
  • 賭場有利的遊戲,賭客不可能靠「纜」擊敗賭場。
  • Kelly Criterion 1956