The adventures of poker,
  packets, pipes and
        Python
        Roger Barnes
I like playing online poker
But I could be better at it
I needed a poker buddy

                             All in!




              That's a
            terrible hand!
Live Hold'em Poker Pro
Packet capture options
from your (rooted) Android device - wifi or 3G
● apps - eg Shark for Root
● tcpdump - via shell
Packet capture options
from your router or another device on the
network (if promiscuous mode) - wifi only
● tcpdump/libpcap
● wireshark/tshark
● pcapy
● ngrep
Hackable routers
There are many devices and firmwares to
choose from (see dd-wrt and tomato-usb)

I have Netgear WNR3500L with Tomato-USB
● ssh built in
● Additional packages installed using Optware
  ○ http://tomatousb.org/doc:optware
  ○ Includes python, tshark, ngrep, wget, some build
    tools, ...
Initial capture using tshark

tshark -i eth1 -w capture.pcap -f
"host 192.168.1.106 and
(port 9400 or port 9500)"
Analyse using wireshark - bingo!
IPython Notebook
  http://ipython.org/ipython-doc/dev/interactive/htmlnotebook.html
Parsing game state
More IPython notebook work to figure out
sequence of events, card values, player actions
etc
Mapping card values
def cardmapper(val):
   vals = '23456789TJQKA'
   suits = 'cdhs'
   result = divmod(val, 13)
   return vals[result[1]] + suits[result[0]]
print cardmapper(44) # 7s
print cardmapper(21) # Td
print cardmapper(17) # 6d
print cardmapper(51) # As
print cardmapper(7) # 9c
print cardmapper(0) # 2c
Getting live capture data
● tshark?              Too hard
● pcapy?               Maybe
● ngrep?               Probably
Getting live capture data into Python
● Install pcapy on router?   Too hard
● zmq on router?             Too hard
● SSH and pipe?              Maybe
Running hand analysis
● Run directly on router?   Too hard
Solution - ssh, ngrep and pipes




ssh $router "ngrep ..." | python -u poker-buddy.py
Pipes
Piping data into Python is easy
You can read stdin...
import sys
while True:
    l = sys.stdin.readline():



Alternatively use the Unix-like fileinput
module...
import fileinput
for line in fileinput.input():



... fileinput reads from a list of files, or else stdin
Pipes
Watch out for buffering!

python -u
Now for some poker smarts
Loads of resources on the web
● Poker games generally
  ○ starting hand rankings
  ○ odds calculations etc
Now for some poker smarts
Easy lookup tables in python...
# Unprocessed space separated string dump
stats_rankings = 
"""AA     2.3200     550,632
KK     1.6700     551,878
... lots more lines
32s     -0.1600     369,182"""
# Now convert to structured data
stats_rankings = dict([
   (line.split()[0], (rank + 1, float(line.split()[1])))
   for rank, line
   in enumerate(stats_rankings.split("n"))
])
Now for some poker smarts
Python specific
● pypoker-eval
  ○ Wrapper for poker-eval toolkit
  ○ Run hand simulations
● machine learning systems
  ○ endless possibilities
● Lots of other resources at:
  http://pokerai.org/pf3/viewforum.php?f=32
Code
def read_raw_from_stdin():
    line = ''
    while 1:
        l = sys.stdin.readline()
        line += l.strip()
        if '''we have a complete line''':
             parse_update(line)
             line = ''

if __name__ == "__main__":
    read_raw_from_stdin()
Code
def parse_update(update_str):
    player_cards = get_cards(update_str)
    if player_cards:
        my_cards = [v for v in player_cards if v[0] != '__']
        if my_cards:
            rank_starting_hand(my_cards[0])
    else:
        player_cards = old_player_cards # global state excluded
        community_cards = get_cards(update_str, player=False)
        if community_cards:
            print("Community cards %s" % community_cards)
            rank_hand(player_cards, community_cards)
Code
e = PokerEval()
def rank_hand(pocket_cards, community_cards, iterations=100000):
  unknown_cards = ['__'] * (5 - len(community_cards))
  result = e.poker_eval(game = "holdem",
    pockets = pocket_cards,
    iterations = iterations,
    board = community_cards + unknown_cards)

    for i, data in enumerate(result['eval']):
        print(pocket_cards[i], "%2d%%" % (float(data['ev']) /
10), data['winhi'], data['losehi'], data['tiehi'])
Game in progress - poker-buddy.py
Player cards [['__', '__'], ['__', '__'], ['Ac', 'Kc'],
['__', '__'], ['__', '__']]
Group 1
(5, 0.77)
Game in progress - poker-buddy.py
Community cards ['Th', '5s', '9h']
['__', '__'] 21% 20486 77811 1703
['__', '__'] 21% 20267 78013 1720
['Ac', 'Kc'] 15% 14880 84332 788
['__', '__'] 21% 20386 77819 1795
['__', '__'] 21% 20207 78074 1719
Game in progress - poker-buddy.py
Community cards ['Th', '5s', '9h', 'Jc', '6s']
['__', '__'] 24% 24185 74694 1121
['__', '__'] 24% 24332 74502 1166
['Ac', 'Kc'] 1% 1019 98870 111
['__', '__'] 24% 24005 74893 1102
['__', '__'] 24% 24148 74698 1154
Summary
● Python can be used for packet capture
   ○ pycapy
● Python for data processing
   ○ Pipes, unbuffered input (-u option), stdin, fileinput
     module
● Python on embedded devices
   ○ Optware on routers & other embedded devices
● IPython Notebook great for analysis...
     ...and documenting what you found
● There's a library for almost everything
   ○ eg pypoker-eval
Thanks! Questions?




Code (warts and all):
https://github.com/mindsocket/poker-buddy

Poker, packets, pipes and Python

  • 1.
    The adventures ofpoker, packets, pipes and Python Roger Barnes
  • 2.
    I like playingonline poker
  • 3.
    But I couldbe better at it
  • 4.
    I needed apoker buddy All in! That's a terrible hand!
  • 5.
  • 6.
    Packet capture options fromyour (rooted) Android device - wifi or 3G ● apps - eg Shark for Root ● tcpdump - via shell
  • 7.
    Packet capture options fromyour router or another device on the network (if promiscuous mode) - wifi only ● tcpdump/libpcap ● wireshark/tshark ● pcapy ● ngrep
  • 8.
    Hackable routers There aremany devices and firmwares to choose from (see dd-wrt and tomato-usb) I have Netgear WNR3500L with Tomato-USB ● ssh built in ● Additional packages installed using Optware ○ http://tomatousb.org/doc:optware ○ Includes python, tshark, ngrep, wget, some build tools, ...
  • 9.
    Initial capture usingtshark tshark -i eth1 -w capture.pcap -f "host 192.168.1.106 and (port 9400 or port 9500)"
  • 10.
  • 11.
    IPython Notebook http://ipython.org/ipython-doc/dev/interactive/htmlnotebook.html
  • 12.
    Parsing game state MoreIPython notebook work to figure out sequence of events, card values, player actions etc
  • 13.
    Mapping card values defcardmapper(val): vals = '23456789TJQKA' suits = 'cdhs' result = divmod(val, 13) return vals[result[1]] + suits[result[0]] print cardmapper(44) # 7s print cardmapper(21) # Td print cardmapper(17) # 6d print cardmapper(51) # As print cardmapper(7) # 9c print cardmapper(0) # 2c
  • 14.
    Getting live capturedata ● tshark? Too hard ● pcapy? Maybe ● ngrep? Probably
  • 15.
    Getting live capturedata into Python ● Install pcapy on router? Too hard ● zmq on router? Too hard ● SSH and pipe? Maybe
  • 16.
    Running hand analysis ●Run directly on router? Too hard
  • 17.
    Solution - ssh,ngrep and pipes ssh $router "ngrep ..." | python -u poker-buddy.py
  • 18.
    Pipes Piping data intoPython is easy You can read stdin... import sys while True: l = sys.stdin.readline(): Alternatively use the Unix-like fileinput module... import fileinput for line in fileinput.input(): ... fileinput reads from a list of files, or else stdin
  • 19.
    Pipes Watch out forbuffering! python -u
  • 20.
    Now for somepoker smarts Loads of resources on the web ● Poker games generally ○ starting hand rankings ○ odds calculations etc
  • 21.
    Now for somepoker smarts Easy lookup tables in python... # Unprocessed space separated string dump stats_rankings = """AA 2.3200 550,632 KK 1.6700 551,878 ... lots more lines 32s -0.1600 369,182""" # Now convert to structured data stats_rankings = dict([ (line.split()[0], (rank + 1, float(line.split()[1]))) for rank, line in enumerate(stats_rankings.split("n")) ])
  • 22.
    Now for somepoker smarts Python specific ● pypoker-eval ○ Wrapper for poker-eval toolkit ○ Run hand simulations ● machine learning systems ○ endless possibilities ● Lots of other resources at: http://pokerai.org/pf3/viewforum.php?f=32
  • 23.
    Code def read_raw_from_stdin(): line = '' while 1: l = sys.stdin.readline() line += l.strip() if '''we have a complete line''': parse_update(line) line = '' if __name__ == "__main__": read_raw_from_stdin()
  • 24.
    Code def parse_update(update_str): player_cards = get_cards(update_str) if player_cards: my_cards = [v for v in player_cards if v[0] != '__'] if my_cards: rank_starting_hand(my_cards[0]) else: player_cards = old_player_cards # global state excluded community_cards = get_cards(update_str, player=False) if community_cards: print("Community cards %s" % community_cards) rank_hand(player_cards, community_cards)
  • 25.
    Code e = PokerEval() defrank_hand(pocket_cards, community_cards, iterations=100000): unknown_cards = ['__'] * (5 - len(community_cards)) result = e.poker_eval(game = "holdem", pockets = pocket_cards, iterations = iterations, board = community_cards + unknown_cards) for i, data in enumerate(result['eval']): print(pocket_cards[i], "%2d%%" % (float(data['ev']) / 10), data['winhi'], data['losehi'], data['tiehi'])
  • 26.
    Game in progress- poker-buddy.py Player cards [['__', '__'], ['__', '__'], ['Ac', 'Kc'], ['__', '__'], ['__', '__']] Group 1 (5, 0.77)
  • 27.
    Game in progress- poker-buddy.py Community cards ['Th', '5s', '9h'] ['__', '__'] 21% 20486 77811 1703 ['__', '__'] 21% 20267 78013 1720 ['Ac', 'Kc'] 15% 14880 84332 788 ['__', '__'] 21% 20386 77819 1795 ['__', '__'] 21% 20207 78074 1719
  • 28.
    Game in progress- poker-buddy.py Community cards ['Th', '5s', '9h', 'Jc', '6s'] ['__', '__'] 24% 24185 74694 1121 ['__', '__'] 24% 24332 74502 1166 ['Ac', 'Kc'] 1% 1019 98870 111 ['__', '__'] 24% 24005 74893 1102 ['__', '__'] 24% 24148 74698 1154
  • 29.
    Summary ● Python canbe used for packet capture ○ pycapy ● Python for data processing ○ Pipes, unbuffered input (-u option), stdin, fileinput module ● Python on embedded devices ○ Optware on routers & other embedded devices ● IPython Notebook great for analysis... ...and documenting what you found ● There's a library for almost everything ○ eg pypoker-eval
  • 30.
    Thanks! Questions? Code (wartsand all): https://github.com/mindsocket/poker-buddy