Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
""" This is a Twitter bot that lets you play Zork. Props to @jenesaisdiq for inspiration and @redroselet for moral support. To play, just twitter @zorker with a Zork move. For example: '@zorker attack troll with sword' Be cautioned, though, this bot takes it's time playing, and if everyone tries to move at once it'll all fall apart. """ __author__ = 'Scott Torborg (scotttorborg.com)' from twitter import Twitter from pprint import pprint import pexpect, re, time username = 'zorker' password = 'REDACTED' twitter = Twitter(username, password) class dfrotz(object): def __init__(self): self.dfrotz = pexpect.spawn('dfrotz zork1.z5') self.re = re.compile('\n((?P<location>.*)Score\:\ ' '(?P<score>\d+)\s*Moves\:\ ' '(?P<moves>\d+))?\s*(?P<text>.+)\>', re.DOTALL) def tell(self, line): self.dfrotz.sendline(line.strip()) def listen(self): resp = self._response() raw = self.re.search(resp).groupdict() for k in ['score', 'location', 'moves']: if k in raw and raw[k]: setattr(self, k, raw[k].strip()) return raw['text'].strip().replace('\n', ' ') def _response(self): res = [] c = None while c != '>': try: c = self.dfrotz.read_nonblocking(1, 0.1) res.append(c) except Exception, msg: break return ''.join(res).replace('\r\n', '\n') def parse_twitter(text): r = re.match('^(\@\S+\s)*(?P<msg>.+)$', text) if r: return r.group('msg') else: return None def twitter_short(s): print "twittering '%s'" % s twitter.statuses.update(status=s) def twitter_long(s): msg = '' for word in s.strip().split(' '): if len(msg) + len(word) > 139: twitter_short(msg) msg = word else: if msg == '': msg = word else: msg += ' ' + word twitter_short(msg) # wait 3 seconds between posting twitters time.sleep(3) # when we first launch, get all @replies to our username and store the # most recent id, so we ignore any @replies that are before this one. replies = twitter.statuses.replies() if len(replies) > 0: last_id = replies[0]['id'] else: last_id = None df = dfrotz() intro = df.listen() df._response() twitter_long('West of House You are standing in an open field west of a ' 'white house, with a boarded front door. There is a small ' 'mailbox here.') count = 0 while True: # get moves from twitter print "getting moves from twitter" if last_id: moves = twitter.statuses.replies(since_id=last_id) else: moves = twitter.statuses.replies() for move in moves: last_id = move['id'] reply = parse_twitter(move['text']) print "move is [%s]" % reply if reply and reply != '': # send move to frotz df.tell(reply) # twitter response from frotz twitter_long(df.listen()) # every 15 moves, twitter with the current loc, score, moves. if (count % 15) == 0: tweet = ('Location: %s, Score: %s, Moves: %s' % (df.location, df.score, df.moves)) twitter_long(tweet) count += 1 else: print "ignoring empty reply" time.sleep(120)
This paste will be private.
From the Design Piracy series on my blog: