6 agent_timeout = -1.0 # Timeout in seconds for AI players to make moves
7 # WARNING: Won't work for windows based operating systems
9 if platform.system() == "Windows":
10 agent_timeout = -1 # Hence this
12 # A player who can't play
14 def __init__(self, name, colour):
18 def update(self, result):
21 def reset_board(self, s):
25 return self.name + "<"+str(self.colour)+">"
27 def base_player(self):
30 # Player that runs through a fifo
31 class FifoPlayer(Player):
32 def __init__(self, name, colour):
33 Player.__init__(self, name, colour)
34 os.mkfifo(self.name+".in")
35 os.mkfifo(self.name+".out")
41 def update(self, result):
42 sys.stderr.write("update fifo called\n")
43 self.fifo_out = open(self.name+".out", "w")
44 self.fifo_out.write(result +"\n")
49 sys.stderr.write("select fifo called\n")
50 self.fifo_out = open(self.name+".out", "w")
51 self.fifo_out.write("SELECT?\n")
53 self.fifo_in = open(self.name+".in", "r")
54 s = map(int, self.fifo_in.readline().strip(" \r\n").split(" "))
59 sys.stderr.write("get_move fifo called\n")
60 self.fifo_out = open(self.name+".out", "w")
61 self.fifo_out.write("MOVE?\n")
63 self.fifo_in = open(self.name+".in", "r")
64 s = map(int, self.fifo_in.readline().strip(" \r\n").split(" "))
68 def quit(self, result):
69 self.fifo_out = open(self.name+".out", "w")
70 self.fifo_out.write(result + "\n")
72 os.remove(self.name+".in")
73 os.remove(self.name+".out")
75 # Player that runs from another process
76 class ExternalAgent(Player):
79 def __init__(self, name, colour):
80 Player.__init__(self, name, colour)
81 self.p = subprocess.Popen(name,bufsize=0,stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True,universal_newlines=True)
83 self.send_message(colour)
85 def send_message(self, s):
86 if agent_timeout > 0.0:
87 ready = select.select([], [self.p.stdin], [], agent_timeout)[1]
89 ready = [self.p.stdin]
90 if self.p.stdin in ready:
91 #sys.stderr.write("Writing \'" + s + "\' to " + str(self.p) + "\n")
93 self.p.stdin.write(s + "\n")
95 raise Exception("UNRESPONSIVE")
97 raise Exception("TIMEOUT")
99 def get_response(self):
100 if agent_timeout > 0.0:
101 ready = select.select([self.p.stdout], [], [], agent_timeout)[0]
103 ready = [self.p.stdout]
104 if self.p.stdout in ready:
105 #sys.stderr.write("Reading from " + str(self.p) + " 's stdout...\n")
107 result = self.p.stdout.readline().strip(" \t\r\n")
108 #sys.stderr.write("Read \'" + result + "\' from " + str(self.p) + "\n")
110 except: # Exception, e:
111 raise Exception("UNRESPONSIVE")
113 raise Exception("TIMEOUT")
117 self.send_message("SELECTION?")
118 line = self.get_response()
121 m = re.match("\s*(\d+)\s+(\d+)\s*", line)
122 result = map(int, [m.group(1), m.group(2)])
124 raise Exception("GIBBERISH \"" + str(line) + "\"")
127 def update(self, result):
128 #print "Update " + str(result) + " called for AgentPlayer"
129 self.send_message(result)
134 self.send_message("MOVE?")
135 line = self.get_response()
138 m = re.match("\s*(\d+)\s+(\d+)\s*", line)
139 result = map(int, [m.group(1), m.group(2)])
142 raise Exception("GIBBERISH \"" + str(line) + "\"")
145 def reset_board(self, s):
146 self.send_message("BOARD")
147 for line in s.split("\n"):
148 self.send_message(line.strip(" \r\n"))
149 self.send_message("END BOARD")
151 def quit(self, final_result):
153 self.send_message("QUIT " + final_result)
157 # So you want to be a player here?
158 class HumanPlayer(Player):
159 def __init__(self, name, colour):
160 Player.__init__(self, name, colour)
162 # Select your preferred account
164 if isinstance(graphics, GraphicsThread):
165 # Basically, we let the graphics thread do some shit and then return that information to the game thread
166 graphics.cond.acquire()
167 # We wait for the graphics thread to select a piece
168 while graphics.stopped() == False and graphics.state["select"] == None:
169 graphics.cond.wait() # The difference between humans and machines is that humans sleep
170 select = graphics.state["select"]
173 graphics.cond.release()
174 if graphics.stopped():
176 return [select.x, select.y]
178 # Since I don't display the board in this case, I'm not sure why I filled it in...
180 sys.stdout.write("SELECTION?\n")
182 p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
184 sys.stderr.write("ILLEGAL GIBBERISH\n")
186 # It's your move captain
188 if isinstance(graphics, GraphicsThread):
189 graphics.cond.acquire()
190 while graphics.stopped() == False and graphics.state["dest"] == None:
192 graphics.cond.release()
194 return graphics.state["dest"]
198 sys.stdout.write("MOVE?\n")
200 p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
202 sys.stderr.write("ILLEGAL GIBBERISH\n")
205 # Are you sure you want to quit?
206 def quit(self, final_result):
208 sys.stdout.write("QUIT " + final_result + "\n")
210 # Completely useless function
211 def update(self, result):
212 if isinstance(graphics, GraphicsThread):
215 sys.stdout.write(result + "\n")
219 # Default internal player (makes random moves)
220 class InternalAgent(Player):
221 def __init__(self, name, colour):
222 Player.__init__(self, name, colour)
225 self.board = Board(style = "agent")
229 def update(self, result):
231 self.board.update(result)
235 def reset_board(self, s):
236 self.board.reset_board(s)
238 def quit(self, final_result):
241 class AgentRandom(InternalAgent):
242 def __init__(self, name, colour):
243 InternalAgent.__init__(self, name, colour)
247 self.choice = self.board.pieces[self.colour][random.randint(0, len(self.board.pieces[self.colour])-1)]
249 # Check that the piece has some possibility to move
250 tmp = self.choice.current_type
251 if tmp == "unknown": # For unknown pieces, try both types
252 for t in self.choice.types:
255 self.choice.current_type = t
256 all_moves += self.board.possible_moves(self.choice)
258 all_moves = self.board.possible_moves(self.choice)
259 self.choice.current_type = tmp
260 if len(all_moves) > 0:
262 return [self.choice.x, self.choice.y]
265 moves = self.board.possible_moves(self.choice)
266 move = moves[random.randint(0, len(moves)-1)]
270 # Terrible, terrible hacks
272 def run_agent(agent):
273 #sys.stderr.write(sys.argv[0] + " : Running agent " + str(agent) + "\n")
275 line = sys.stdin.readline().strip(" \r\n")
276 if line == "SELECTION?":
277 #sys.stderr.write(sys.argv[0] + " : Make selection\n")
278 [x,y] = agent.select() # Gets your agent's selection
279 #sys.stderr.write(sys.argv[0] + " : Selection was " + str(agent.choice) + "\n")
280 sys.stdout.write(str(x) + " " + str(y) + "\n")
281 elif line == "MOVE?":
282 #sys.stderr.write(sys.argv[0] + " : Make move\n")
283 [x,y] = agent.get_move() # Gets your agent's move
284 sys.stdout.write(str(x) + " " + str(y) + "\n")
285 elif line.split(" ")[0] == "QUIT":
286 #sys.stderr.write(sys.argv[0] + " : Quitting\n")
287 agent.quit(" ".join(line.split(" ")[1:])) # Quits the game
289 elif line.split(" ")[0] == "BOARD":
291 line = sys.stdin.readline().strip(" \r\n")
292 while line != "END BOARD":
294 line = sys.stdin.readline().strip(" \r\n")
295 agent.board.reset_board(s)
298 agent.update(line) # Updates agent.board
304 class ExternalWrapper(ExternalAgent):
305 def __init__(self, agent):
306 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))\""
308 ExternalAgent.__init__(self, run, agent.colour)