1 '''externAgent.py - a bot shell for talking to external I/O bots.
2 Written by Daniel Axtens <
[email protected]> for the UCC Programming Competition in 2010.
4 Licensed under an MIT-style license: see the LICENSE file for details.
7 from uccProgComp import BaseAgent, LearningAgent, RandomAttack
9 #from pexpect import pexpect
11 import sys, subprocess
13 class externAgent (BaseAgent):
15 def __init__ (self, externName):
16 BaseAgent.__init__(self)
18 self.process = subprocess.Popen(externName, stdin=subprocess.PIPE,
19 stdout=subprocess.PIPE,
20 universal_newlines=True)
22 print ("Error spawning \"%s\": " % externName), e
24 self.process.stdin.write ( ' '.join( ["HI", repr(self.GetID()), "\r\n"] ) )
26 def stringToItem( self, str ):
31 elif str == "Scissors":
34 # Something has gone wrong!
35 print "Error: tried to convert \"%s\" into an item!" % str
36 raise ValueError( "tried to convert \"%s\" into an item!" % str );
39 def itemToString( self, item ):
40 return rpsStrings[item]
46 #elif item == Scissors:
49 # # Something has gone wrong!
50 # print "Error: tried to convert '%d' to Rock/Paper/Scissors string!" % item
51 # # raise an exception
52 # raise ValueError("tried to convert '%d' to Rock/Paper/Scissors string!" % item)
54 def resultToString( self, result ):
55 return adtStrings[result]
57 #if result == Attacker:
59 #elif result == Defender:
64 # # Something has gone wrong!
65 # print "Error: tried to convert '%d' to Attacker/Defender/Tie string!" % result
66 # # raise an exception
67 # raise ValueError("tried to convert '%d' to Attacker/Defender/Tie string!" % result)
69 def Attack (self, foe):
70 self.process.stdin.write ( ' '.join( ["ATTACK", repr(foe), "\r\n"] ) )
71 #print >>sys.stderr, self.process.stderr.readlines()
72 result = self.process.stdout.readline().split()
74 attack, bluff = self.stringToItem( result[1] ), self.stringToItem( result[2] )
78 print "Agent is insane:", self, self.GetID()
81 def Defend (self, foe, bluff ):
82 self.process.stdin.write ( ' '.join( ["DEFEND", repr(foe), self.itemToString( bluff ), "\r\n"] ) )
83 #print >>sys.stderr, self.process.stderr.readlines()
84 result = self.process.stdout.readline().split()
86 defence = self.stringToItem( result[1] )
90 print "Agent is insane:", self, self.GetID()
93 def Results (self, foe, isInstigatedByYou, winner, attItem, defItem, bluffItem, pointDelta):
95 BaseAgent.Results (self, foe, isInstigatedByYou, winner, attItem,
96 defItem, bluffItem, pointDelta)
98 string = ' '.join( [ "RESULTS", repr(foe), repr(isInstigatedByYou),
99 self.resultToString(winner),
100 self.itemToString( attItem ),
101 self.itemToString( defItem ),
102 self.itemToString( bluffItem ), repr(pointDelta),
105 #string = "RESULTS %s %s %s %s %s %s %d\r\n" % (foe, isInstigatedByYou,
106 # self.resultToString(winner),
107 # self.itemToString( attItem ),
108 # self.itemToString( defItem ),
109 # self.itemToString( bluffItem ), pointDelta)
112 self.process.stdin.write ( string )
113 self.process.stdout.readline() # read and discard (should be "OK")
115 # we kill off the process here because otherwise the class doesn't get
116 # destroyed until the end of the iteration. This causes us to hold more
117 # than MAX_TOTAL_AGENTS open for a period of time, which is a bad thing.
120 self.process.communicate( "BYE\r\n" )
122 print "Error in BYE:", self, ":", e
131 #unless we're being deleted unexpectedly, this is a no-op.
132 if self.process.poll() == None:
134 self.process.communicate( "BYE\r\n" )
136 print "Error in BYE:", self, ":", e