Messing with log files
[progcomp2013.git] / qchess / src / player.py
1 import subprocess
2 import select
3 import platform
4
5
6 agent_timeout = -1.0 # Timeout in seconds for AI players to make moves
7                         # WARNING: Won't work for windows based operating systems
8
9 if platform.system() == "Windows":
10         agent_timeout = -1 # Hence this
11
12 # A player who can't play
13 class Player():
14         def __init__(self, name, colour):
15                 self.name = name
16                 self.colour = colour
17
18         def update(self, result):
19                 pass
20
21         def reset_board(self, s):
22                 pass
23
24 # Player that runs from another process
25 class ExternalAgent(Player):
26
27
28         def __init__(self, name, colour):
29                 Player.__init__(self, name, colour)
30                 self.p = subprocess.Popen(name,bufsize=0,stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True,universal_newlines=True)
31                 
32                 self.send_message(colour)
33
34         def send_message(self, s):
35                 if agent_timeout > 0.0:
36                         ready = select.select([], [self.p.stdin], [], agent_timeout)[1]
37                 else:
38                         ready = [self.p.stdin]
39                 if self.p.stdin in ready:
40                         #sys.stderr.write("Writing \'" + s + "\' to " + str(self.p) + "\n")
41                         try:
42                                 self.p.stdin.write(s + "\n")
43                         except:
44                                 raise Exception("UNRESPONSIVE")
45                 else:
46                         raise Exception("TIMEOUT")
47
48         def get_response(self):
49                 if agent_timeout > 0.0:
50                         ready = select.select([self.p.stdout], [], [], agent_timeout)[0]
51                 else:
52                         ready = [self.p.stdout]
53                 if self.p.stdout in ready:
54                         #sys.stderr.write("Reading from " + str(self.p) + " 's stdout...\n")
55                         try:
56                                 result = self.p.stdout.readline().strip("\r\n")
57                                 #sys.stderr.write("Read \'" + result + "\' from " + str(self.p) + "\n")
58                                 return result
59                         except: # Exception, e:
60                                 raise Exception("UNRESPONSIVE")
61                 else:
62                         raise Exception("TIMEOUT")
63
64         def select(self):
65
66                 self.send_message("SELECTION?")
67                 line = self.get_response()
68                 
69                 try:
70                         result = map(int, line.split(" "))
71                 except:
72                         raise Exception("GIBBERISH \"" + str(line) + "\"")
73                 return result
74
75         def update(self, result):
76                 #print "Update " + str(result) + " called for AgentPlayer"
77                 self.send_message(result)
78
79
80         def get_move(self):
81                 
82                 self.send_message("MOVE?")
83                 line = self.get_response()
84                 
85                 try:
86                         result = map(int, line.split(" "))
87                 except:
88                         raise Exception("GIBBERISH \"" + str(line) + "\"")
89                 return result
90
91         def reset_board(self, s):
92                 self.send_message("BOARD")
93                 for line in s.split("\n"):
94                         self.send_message(line.strip(" \r\n"))
95                 self.send_message("END BOARD")
96
97         def quit(self, final_result):
98                 try:
99                         self.send_message("QUIT " + final_result)
100                 except:
101                         self.p.kill()
102
103 # So you want to be a player here?
104 class HumanPlayer(Player):
105         def __init__(self, name, colour):
106                 Player.__init__(self, name, colour)
107                 
108         # Select your preferred account
109         def select(self):
110                 if isinstance(graphics, GraphicsThread):
111                         # Basically, we let the graphics thread do some shit and then return that information to the game thread
112                         graphics.cond.acquire()
113                         # We wait for the graphics thread to select a piece
114                         while graphics.stopped() == False and graphics.state["select"] == None:
115                                 graphics.cond.wait() # The difference between humans and machines is that humans sleep
116                         select = graphics.state["select"]
117                         
118                         
119                         graphics.cond.release()
120                         if graphics.stopped():
121                                 return [-1,-1]
122                         return [select.x, select.y]
123                 else:
124                         # Since I don't display the board in this case, I'm not sure why I filled it in...
125                         while True:
126                                 sys.stdout.write("SELECTION?\n")
127                                 try:
128                                         p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
129                                 except:
130                                         sys.stderr.write("ILLEGAL GIBBERISH\n")
131                                         continue
132         # It's your move captain
133         def get_move(self):
134                 if isinstance(graphics, GraphicsThread):
135                         graphics.cond.acquire()
136                         while graphics.stopped() == False and graphics.state["dest"] == None:
137                                 graphics.cond.wait()
138                         graphics.cond.release()
139                         
140                         return graphics.state["dest"]
141                 else:
142
143                         while True:
144                                 sys.stdout.write("MOVE?\n")
145                                 try:
146                                         p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
147                                 except:
148                                         sys.stderr.write("ILLEGAL GIBBERISH\n")
149                                         continue
150
151         # Are you sure you want to quit?
152         def quit(self, final_result):
153                 if graphics == None:            
154                         sys.stdout.write("QUIT " + final_result + "\n")
155
156         # Completely useless function
157         def update(self, result):
158                 if isinstance(graphics, GraphicsThread):
159                         pass
160                 else:
161                         sys.stdout.write(result + "\n") 
162
163
164 # Default internal player (makes random moves)
165 class InternalAgent(Player):
166         def __init__(self, name, colour):
167                 Player.__init__(self, name, colour)
168                 self.choice = None
169
170                 self.board = Board(style = "agent")
171
172
173
174         def update(self, result):
175                 
176                 self.board.update(result)
177                 self.board.verify()
178
179         def reset_board(self, s):
180                 self.board.reset_board(s)
181
182         def quit(self, final_result):
183                 pass
184
185 class AgentRandom(InternalAgent):
186         def __init__(self, name, colour):
187                 InternalAgent.__init__(self, name, colour)
188
189         def select(self):
190                 while True:
191                         self.choice = self.board.pieces[self.colour][random.randint(0, len(self.board.pieces[self.colour])-1)]
192                         all_moves = []
193                         # Check that the piece has some possibility to move
194                         tmp = self.choice.current_type
195                         if tmp == "unknown": # For unknown pieces, try both types
196                                 for t in self.choice.types:
197                                         if t == "unknown":
198                                                 continue
199                                         self.choice.current_type = t
200                                         all_moves += self.board.possible_moves(self.choice)
201                         else:
202                                 all_moves = self.board.possible_moves(self.choice)
203                         self.choice.current_type = tmp
204                         if len(all_moves) > 0:
205                                 break
206                 return [self.choice.x, self.choice.y]
207
208         def get_move(self):
209                 moves = self.board.possible_moves(self.choice)
210                 move = moves[random.randint(0, len(moves)-1)]
211                 return move
212
213
214 # Terrible, terrible hacks
215
216 def run_agent(agent):
217         #sys.stderr.write(sys.argv[0] + " : Running agent " + str(agent) + "\n")
218         while True:
219                 line = sys.stdin.readline().strip(" \r\n")
220                 if line == "SELECTION?":
221                         #sys.stderr.write(sys.argv[0] + " : Make selection\n")
222                         [x,y] = agent.select() # Gets your agent's selection
223                         #sys.stderr.write(sys.argv[0] + " : Selection was " + str(agent.choice) + "\n")
224                         sys.stdout.write(str(x) + " " + str(y) + "\n")                          
225                 elif line == "MOVE?":
226                         #sys.stderr.write(sys.argv[0] + " : Make move\n")
227                         [x,y] = agent.get_move() # Gets your agent's move
228                         sys.stdout.write(str(x) + " " + str(y) + "\n")
229                 elif line.split(" ")[0] == "QUIT":
230                         #sys.stderr.write(sys.argv[0] + " : Quitting\n")
231                         agent.quit(" ".join(line.split(" ")[1:])) # Quits the game
232                         break
233                 elif line.split(" ")[0] == "BOARD":
234                         s = ""
235                         line = sys.stdin.readline().strip(" \r\n")
236                         while line != "END BOARD":
237                                 s += line + "\n"
238                                 line = sys.stdin.readline().strip(" \r\n")
239                         agent.board.reset_board(s)
240                         
241                 else:
242                         agent.update(line) # Updates agent.board
243         return 0
244
245
246 # Sort of works?
247
248 class ExternalWrapper(ExternalAgent):
249         def __init__(self, agent):
250                 run = "python -u -c \"import sys;import os;from qchess import *;agent = " + agent.__class__.__name__ + "('" + agent.name + "','"+agent.colour+"');sys.stdin.readline();sys.exit(run_agent(agent))\""
251                 # str(run)
252                 ExternalAgent.__init__(self, run, agent.colour)
253
254         
255

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