--- /dev/null
+#!/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