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 from another process
31 class ExternalAgent(Player):
34 def __init__(self, name, colour):
35 Player.__init__(self, name, colour)
36 self.p = subprocess.Popen(name,bufsize=0,stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True,universal_newlines=True)
38 self.send_message(colour)
40 def send_message(self, s):
41 if agent_timeout > 0.0:
42 ready = select.select([], [self.p.stdin], [], agent_timeout)[1]
44 ready = [self.p.stdin]
45 if self.p.stdin in ready:
46 #sys.stderr.write("Writing \'" + s + "\' to " + str(self.p) + "\n")
48 self.p.stdin.write(s + "\n")
50 raise Exception("UNRESPONSIVE")
52 raise Exception("TIMEOUT")
54 def get_response(self):
55 if agent_timeout > 0.0:
56 ready = select.select([self.p.stdout], [], [], agent_timeout)[0]
58 ready = [self.p.stdout]
59 if self.p.stdout in ready:
60 #sys.stderr.write("Reading from " + str(self.p) + " 's stdout...\n")
62 result = self.p.stdout.readline().strip(" \t\r\n")
63 #sys.stderr.write("Read \'" + result + "\' from " + str(self.p) + "\n")
65 except: # Exception, e:
66 raise Exception("UNRESPONSIVE")
68 raise Exception("TIMEOUT")
72 self.send_message("SELECTION?")
73 line = self.get_response()
76 m = re.match("\s*(\d+)\s+(\d+)\s*", line)
77 result = map(int, [m.group(1), m.group(2)])
79 raise Exception("GIBBERISH \"" + str(line) + "\"")
82 def update(self, result):
83 #print "Update " + str(result) + " called for AgentPlayer"
84 self.send_message(result)
89 self.send_message("MOVE?")
90 line = self.get_response()
93 m = re.match("\s*(\d+)\s+(\d+)\s*", line)
94 result = map(int, [m.group(1), m.group(2)])
97 raise Exception("GIBBERISH \"" + str(line) + "\"")
100 def reset_board(self, s):
101 self.send_message("BOARD")
102 for line in s.split("\n"):
103 self.send_message(line.strip(" \r\n"))
104 self.send_message("END BOARD")
106 def quit(self, final_result):
108 self.send_message("QUIT " + final_result)
112 # So you want to be a player here?
113 class HumanPlayer(Player):
114 def __init__(self, name, colour):
115 Player.__init__(self, name, colour)
117 # Select your preferred account
119 if isinstance(graphics, GraphicsThread):
120 # Basically, we let the graphics thread do some shit and then return that information to the game thread
121 graphics.cond.acquire()
122 # We wait for the graphics thread to select a piece
123 while graphics.stopped() == False and graphics.state["select"] == None:
124 graphics.cond.wait() # The difference between humans and machines is that humans sleep
125 select = graphics.state["select"]
128 graphics.cond.release()
129 if graphics.stopped():
131 return [select.x, select.y]
133 # Since I don't display the board in this case, I'm not sure why I filled it in...
135 sys.stdout.write("SELECTION?\n")
137 p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
139 sys.stderr.write("ILLEGAL GIBBERISH\n")
141 # It's your move captain
143 if isinstance(graphics, GraphicsThread):
144 graphics.cond.acquire()
145 while graphics.stopped() == False and graphics.state["dest"] == None:
147 graphics.cond.release()
149 return graphics.state["dest"]
153 sys.stdout.write("MOVE?\n")
155 p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
157 sys.stderr.write("ILLEGAL GIBBERISH\n")
160 # Are you sure you want to quit?
161 def quit(self, final_result):
163 sys.stdout.write("QUIT " + final_result + "\n")
165 # Completely useless function
166 def update(self, result):
167 if isinstance(graphics, GraphicsThread):
170 sys.stdout.write(result + "\n")
174 # Default internal player (makes random moves)
175 class InternalAgent(Player):
176 def __init__(self, name, colour):
177 Player.__init__(self, name, colour)
180 self.board = Board(style = "agent")
184 def update(self, result):
186 self.board.update(result)
190 def reset_board(self, s):
191 self.board.reset_board(s)
193 def quit(self, final_result):
196 class AgentRandom(InternalAgent):
197 def __init__(self, name, colour):
198 InternalAgent.__init__(self, name, colour)
202 self.choice = self.board.pieces[self.colour][random.randint(0, len(self.board.pieces[self.colour])-1)]
204 # Check that the piece has some possibility to move
205 tmp = self.choice.current_type
206 if tmp == "unknown": # For unknown pieces, try both types
207 for t in self.choice.types:
210 self.choice.current_type = t
211 all_moves += self.board.possible_moves(self.choice)
213 all_moves = self.board.possible_moves(self.choice)
214 self.choice.current_type = tmp
215 if len(all_moves) > 0:
217 return [self.choice.x, self.choice.y]
220 moves = self.board.possible_moves(self.choice)
221 move = moves[random.randint(0, len(moves)-1)]
225 # Terrible, terrible hacks
227 def run_agent(agent):
228 #sys.stderr.write(sys.argv[0] + " : Running agent " + str(agent) + "\n")
230 line = sys.stdin.readline().strip(" \r\n")
231 if line == "SELECTION?":
232 #sys.stderr.write(sys.argv[0] + " : Make selection\n")
233 [x,y] = agent.select() # Gets your agent's selection
234 #sys.stderr.write(sys.argv[0] + " : Selection was " + str(agent.choice) + "\n")
235 sys.stdout.write(str(x) + " " + str(y) + "\n")
236 elif line == "MOVE?":
237 #sys.stderr.write(sys.argv[0] + " : Make move\n")
238 [x,y] = agent.get_move() # Gets your agent's move
239 sys.stdout.write(str(x) + " " + str(y) + "\n")
240 elif line.split(" ")[0] == "QUIT":
241 #sys.stderr.write(sys.argv[0] + " : Quitting\n")
242 agent.quit(" ".join(line.split(" ")[1:])) # Quits the game
244 elif line.split(" ")[0] == "BOARD":
246 line = sys.stdin.readline().strip(" \r\n")
247 while line != "END BOARD":
249 line = sys.stdin.readline().strip(" \r\n")
250 agent.board.reset_board(s)
253 agent.update(line) # Updates agent.board
259 class ExternalWrapper(ExternalAgent):
260 def __init__(self, agent):
261 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))\""
263 ExternalAgent.__init__(self, run, agent.colour)