Cleanup bot code.
[poker.git] / bots / hole_bot.py
diff --git a/bots/hole_bot.py b/bots/hole_bot.py
new file mode 100755 (executable)
index 0000000..5274c69
--- /dev/null
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+
+"""Go all (or not) depending on whats in the hole.
+"""
+
+import logging
+import os
+import sys
+
+
+class RunComplete (Exception):
+    """Raised after receiving the `END` tag to abort execution.
+    """
+    pass
+
+
+class HoleBot (object):
+    def __init__(self, stdin=None, stdout=None, log_level=logging.WARN):
+        if stdin == None:
+            stdin = sys.stdin
+        self.stdin = stdin
+        if stdout == None:
+            stdout = sys.stdout
+        self.stdout = stdout
+        log_file = '%s_%d.log' % (self.__class__.__name__, os.getpid())
+        logging.basicConfig(filename=log_file, level=log_level)
+        self.log = logging
+
+    def run(self):
+        state = self._initial_state()
+        while True:
+            line = self.stdin.readline().strip()
+            if not line:
+                continue  # skip blank lines
+            tag,type,data = self._parse(line)
+            try:
+                self._process(tag, type, data, state)
+            except RunComplete:
+                break
+
+    def _parse(self, line):
+        self.log.debug('read: %s' % line)
+        fields = line.split(' ')
+        try:
+            tag  = fields[0]
+            type = fields[1]
+            data = fields[2:]
+        except:
+            self.log.debug('tag only: %s' % str(fields))
+            tag  = fields[0]
+            type = data = None
+        self.log.debug('parsed tag %s, type %s, data %s'
+                       % (repr(tag), repr(type), repr(data)))
+        return (tag, type, data)
+
+    def _process(self, tag, type, data, state):
+        if tag == 'END':
+            raise RunComplete
+        elif tag == 'MOVE':
+            bet = self._bet(state)
+            self.log.info('bet %s' % bet)
+            self.stdout.write('%s\n' % bet)
+            self.stdout.flush()
+        elif tag == 'INFO' and type == 'HOLE':
+            self._process_hole(data, state)
+            self.log.info('processed hole %s, state: %s' % (data, state))
+
+    def _initial_state(self):
+        return {'all_in': False}
+
+    def _bet(self, state):
+        if state['all_in']:
+            bet = 'A'
+        else:
+            bet = 'f'
+        state['all_in'] = False
+        return bet
+
+    def _process_hole(self, data, state):
+        raise NotImplementedError