Attempt at fixing memory mess.
[progcomp10.git] / src / link / externAgent.py
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.
3
4 Licensed under an MIT-style license: see the LICENSE file for details.
5 '''
6
7 from uccProgComp import BaseAgent, LearningAgent, RandomAttack
8 from rpsconst import *
9 #from pexpect import pexpect
10
11 import sys, subprocess
12
13 class externAgent (BaseAgent):
14
15     def __init__ (self, externName):
16         BaseAgent.__init__(self)
17         try:
18             self.process = subprocess.Popen(externName, stdin=subprocess.PIPE, 
19                                             stdout=subprocess.PIPE,
20                                             universal_newlines=True)
21         except Exception, e:
22             print ("Error spawning \"%s\": " % externName), e
23            
24         self.process.stdin.write ( ' '.join( ["HI", repr(self.GetID()), "\r\n"] ) )
25
26     def stringToItem( self, str ):
27         if str == "Rock":
28             return Rock
29         elif str == "Paper":
30             return Paper
31         elif str == "Scissors":
32             return Scissors
33         else:
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 );
37             return None
38
39     def itemToString( self, item ):
40         return rpsStrings[item]
41         
42         #if item == Rock:
43         #    return "Rock"
44         #elif item == Paper:
45         #    return "Paper"
46         #elif item == Scissors:
47         #    return "Scissors"
48         #else:
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)
53         
54     def resultToString( self, result ):
55         return adtStrings[result]
56     
57         #if result == Attacker:
58         #    return "Attacker"
59         #elif result == Defender:
60         #    return "Defender"
61         #elif result == Tie:
62         #    return "Tie"
63         #else:
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)
68         
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()
73         try:
74             attack, bluff = self.stringToItem( result[1] ), self.stringToItem( result[2] )
75             return attack, bluff
76         except:
77             #agent is insane
78             print "Agent is insane:", self, self.GetID()
79             pass
80         
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()
85         try:
86             defence = self.stringToItem( result[1] )
87             return defence
88         except:
89             #agent is insane
90             print "Agent is insane:", self, self.GetID()
91             pass
92
93     def Results (self, foe, isInstigatedByYou, winner, attItem, defItem, bluffItem, pointDelta):
94         
95         BaseAgent.Results (self, foe, isInstigatedByYou, winner, attItem, 
96                            defItem, bluffItem, pointDelta)
97         
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),
103                              "\r\n" ] )
104         
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)
110         #print string
111         
112         self.process.stdin.write ( string )
113         self.process.stdout.readline() # read and discard (should be "OK")
114         
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.
118         if self.IsDead():
119             try:
120                 self.process.communicate( "BYE\r\n" )
121             except Exception, e:
122                 print "Error in BYE:", self, ":", e
123             
124             try:
125                 self.process.kill()
126             except:
127                 None
128
129
130     def __del__(self):
131         #unless we're being deleted unexpectedly, this is a no-op.
132         if self.process.poll() == None:
133             try:
134                 self.process.communicate( "BYE\r\n" )
135             except Exception, e:
136                 print "Error in BYE:", self, ":", e
137             
138             try:
139                 self.process.kill()
140             except:
141                 None

UCC git Repository :: git.ucc.asn.au