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 # Player that runs from another process
22 class ExternalAgent(Player):
25 def __init__(self, name, colour):
26 Player.__init__(self, name, colour)
27 self.p = subprocess.Popen(name,bufsize=0,stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True,universal_newlines=True)
29 self.send_message(colour)
31 def send_message(self, s):
32 if agent_timeout > 0.0:
33 ready = select.select([], [self.p.stdin], [], agent_timeout)[1]
35 ready = [self.p.stdin]
36 if self.p.stdin in ready:
37 #sys.stderr.write("Writing \'" + s + "\' to " + str(self.p) + "\n")
39 self.p.stdin.write(s + "\n")
41 raise Exception("UNRESPONSIVE")
43 raise Exception("TIMEOUT")
45 def get_response(self):
46 if agent_timeout > 0.0:
47 ready = select.select([self.p.stdout], [], [], agent_timeout)[0]
49 ready = [self.p.stdout]
50 if self.p.stdout in ready:
51 #sys.stderr.write("Reading from " + str(self.p) + " 's stdout...\n")
53 result = self.p.stdout.readline().strip("\r\n")
54 #sys.stderr.write("Read \'" + result + "\' from " + str(self.p) + "\n")
56 except: # Exception, e:
57 raise Exception("UNRESPONSIVE")
59 raise Exception("TIMEOUT")
63 self.send_message("SELECTION?")
64 line = self.get_response()
67 result = map(int, line.split(" "))
69 raise Exception("GIBBERISH \"" + str(line) + "\"")
72 def update(self, result):
73 #print "Update " + str(result) + " called for AgentPlayer"
74 self.send_message(result)
79 self.send_message("MOVE?")
80 line = self.get_response()
83 result = map(int, line.split(" "))
85 raise Exception("GIBBERISH \"" + str(line) + "\"")
88 def quit(self, final_result):
90 self.send_message("QUIT " + final_result)
94 # So you want to be a player here?
95 class HumanPlayer(Player):
96 def __init__(self, name, colour):
97 Player.__init__(self, name, colour)
99 # Select your preferred account
101 if isinstance(graphics, GraphicsThread):
102 # Basically, we let the graphics thread do some shit and then return that information to the game thread
103 graphics.cond.acquire()
104 # We wait for the graphics thread to select a piece
105 while graphics.stopped() == False and graphics.state["select"] == None:
106 graphics.cond.wait() # The difference between humans and machines is that humans sleep
107 select = graphics.state["select"]
110 graphics.cond.release()
111 if graphics.stopped():
113 return [select.x, select.y]
115 # Since I don't display the board in this case, I'm not sure why I filled it in...
117 sys.stdout.write("SELECTION?\n")
119 p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
121 sys.stderr.write("ILLEGAL GIBBERISH\n")
123 # It's your move captain
125 if isinstance(graphics, GraphicsThread):
126 graphics.cond.acquire()
127 while graphics.stopped() == False and graphics.state["dest"] == None:
129 graphics.cond.release()
131 return graphics.state["dest"]
135 sys.stdout.write("MOVE?\n")
137 p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
139 sys.stderr.write("ILLEGAL GIBBERISH\n")
142 # Are you sure you want to quit?
143 def quit(self, final_result):
145 sys.stdout.write("QUIT " + final_result + "\n")
147 # Completely useless function
148 def update(self, result):
149 if isinstance(graphics, GraphicsThread):
152 sys.stdout.write(result + "\n")
155 # Default internal player (makes random moves)
156 class InternalAgent(Player):
157 def __init__(self, name, colour):
158 Player.__init__(self, name, colour)
161 self.board = Board(style = "agent")
165 def update(self, result):
167 self.board.update(result)
170 def quit(self, final_result):
173 class AgentRandom(InternalAgent):
174 def __init__(self, name, colour):
175 InternalAgent.__init__(self, name, colour)
179 self.choice = self.board.pieces[self.colour][random.randint(0, len(self.board.pieces[self.colour])-1)]
181 # Check that the piece has some possibility to move
182 tmp = self.choice.current_type
183 if tmp == "unknown": # For unknown pieces, try both types
184 for t in self.choice.types:
187 self.choice.current_type = t
188 all_moves += self.board.possible_moves(self.choice)
190 all_moves = self.board.possible_moves(self.choice)
191 self.choice.current_type = tmp
192 if len(all_moves) > 0:
194 return [self.choice.x, self.choice.y]
197 moves = self.board.possible_moves(self.choice)
198 move = moves[random.randint(0, len(moves)-1)]
202 # Terrible, terrible hacks
204 def run_agent(agent):
205 #sys.stderr.write(sys.argv[0] + " : Running agent " + str(agent) + "\n")
207 line = sys.stdin.readline().strip(" \r\n")
208 if line == "SELECTION?":
209 #sys.stderr.write(sys.argv[0] + " : Make selection\n")
210 [x,y] = agent.select() # Gets your agent's selection
211 #sys.stderr.write(sys.argv[0] + " : Selection was " + str(agent.choice) + "\n")
212 sys.stdout.write(str(x) + " " + str(y) + "\n")
213 elif line == "MOVE?":
214 #sys.stderr.write(sys.argv[0] + " : Make move\n")
215 [x,y] = agent.get_move() # Gets your agent's move
216 sys.stdout.write(str(x) + " " + str(y) + "\n")
217 elif line.split(" ")[0] == "QUIT":
218 #sys.stderr.write(sys.argv[0] + " : Quitting\n")
219 agent.quit(" ".join(line.split(" ")[1:])) # Quits the game
222 agent.update(line) # Updates agent.board
228 class ExternalWrapper(ExternalAgent):
229 def __init__(self, agent):
230 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))\""
232 ExternalAgent.__init__(self, run, agent.colour)