Add pbotlib.odds.
[poker.git] / pbotlib / hole_bot.py
1 #!/usr/bin/python
2
3 """Go all (or not) depending on whats in the hole.
4 """
5
6 import logging
7 import os
8 import os.path
9 import sys
10
11
12 class RunComplete (Exception):
13     """Raised after receiving the `END` tag to abort execution.
14     """
15     pass
16
17
18 class HoleBot (object):
19     def __init__(self, stdin=None, stdout=None, log_level=logging.WARN):
20         if stdin == None:
21             stdin = sys.stdin
22         self.stdin = stdin
23         if stdout == None:
24             stdout = sys.stdout
25         self.stdout = stdout
26         self.log_file = '%s_%d.log' % (self.__class__.__name__, os.getpid())
27         logging.basicConfig(filename=self.log_file, level=log_level)
28         self.log = logging
29
30     def cleanup_log(self):
31         self.log = None
32         if os.path.getsize(self.log_file) == 0:
33             os.remove(self.log_file)
34
35     def run(self):
36         state = self._initial_state()
37         while True:
38             line = self.stdin.readline().strip()
39             if not line:
40                 continue  # skip blank lines
41             tag,type,data = self._parse(line)
42             try:
43                 self._process(tag, type, data, state)
44             except RunComplete:
45                 break
46         self.cleanup_log()
47
48     def _parse(self, line):
49         self.log.debug('read: %s' % line)
50         fields = line.split(' ')
51         try:
52             tag  = fields[0]
53             type = fields[1]
54             data = fields[2:]
55         except:
56             self.log.debug('tag only: %s' % str(fields))
57             tag  = fields[0]
58             type = data = None
59         self.log.debug('parsed tag %s, type %s, data %s'
60                        % (repr(tag), repr(type), repr(data)))
61         return (tag, type, data)
62
63     def _process(self, tag, type, data, state):
64         if tag == 'END':
65             raise RunComplete
66         elif tag == 'MOVE':
67             bet = self._bet(state)
68             self.log.info('bet %s' % bet)
69             self.stdout.write('%s\n' % bet)
70             self.stdout.flush()
71         elif tag == 'INFO' and type == 'HOLE':
72             self._process_hole(data, state)
73             self.log.info('processed hole %s, state: %s' % (data, state))
74
75     def _initial_state(self):
76         return {'all_in': False}
77
78     def _bet(self, state):
79         if state['all_in']:
80             bet = 'A'
81         else:
82             bet = 'f'
83         state['all_in'] = False
84         return bet
85
86     def _process_hole(self, data, state):
87         raise NotImplementedError