Final Commit
[progcomp2013.git] / qchess / src / game.py
1
2
3
4         
5
6 # A thread that runs the game
7 class GameThread(StoppableThread):
8         def __init__(self, board, players, server = True):
9                 StoppableThread.__init__(self)
10                 self.board = board
11                 self.players = players
12                 self.state = {"turn" : None} # The game state
13                 self.error = 0 # Whether the thread exits with an error
14                 self.lock = threading.RLock() #lock for access of self.state
15                 self.cond = threading.Condition() # conditional for some reason, I forgot
16                 self.final_result = ""
17                 self.server = server
18                 self.retry_illegal = False
19                 
20                 
21         
22
23         # Run the game (run in new thread with start(), run in current thread with run())
24         def run(self):
25                 result = ""
26                 while not self.stopped():
27                         
28                         for p in self.players:
29                                 with self.lock:
30                                         self.state["turn"] = p.base_player()
31                                 try:
32                                 #if True:
33                                         [x,y] = p.select() # Player selects a square
34                                         if self.stopped():
35                                                 #debug("Quitting in select")
36                                                 break
37                                                 
38                                         if isinstance(p, NetworkPlayer):
39                                                 if p.network.server == True:
40                                                         result = self.board.select(x, y, colour = p.colour)
41                                                 else:
42                                                         result = None
43                                                         
44                                         else:
45                                                 result = self.board.select(x, y, colour = p.colour)
46                                         
47                                         result = p.update(result)
48                                         if self.stopped():
49                                                 break
50                                         for p2 in self.players:
51                                                 if p2 == p:
52                                                         continue
53                                                 p2.update(result) # Inform players of what happened
54                                                 if self.stopped():
55                                                         break
56                                         
57                                         if self.stopped():
58                                                 break
59
60
61                                         log(result)
62
63                                         target = self.board.grid[x][y]
64                                         if isinstance(graphics, GraphicsThread):
65                                                 with graphics.lock:
66                                                         graphics.state["moves"] = self.board.possible_moves(target)
67                                                         graphics.state["select"] = target
68
69                                         time.sleep(turn_delay)
70
71
72                                         if len(self.board.possible_moves(target)) == 0:
73                                                 #print "Piece cannot move"
74                                                 target.deselect()
75                                                 if isinstance(graphics, GraphicsThread):
76                                                         with graphics.lock:
77                                                                 graphics.state["moves"] = None
78                                                                 graphics.state["select"] = None
79                                                                 graphics.state["dest"] = None
80                                                 continue
81
82                                         #try:
83                                         [x2,y2] = p.get_move() # Player selects a destination
84                                         #except:
85                                         #       self.stop()
86
87                                         if self.stopped():
88                                                 #debug("Quitting in get_move")
89                                                 break
90                                         
91                                         if isinstance(p, NetworkPlayer):
92                                                 if p.network.server == True:
93                                                         result = str(x) + " " + str(y) + " -> " + str(x2) + " " + str(y2)
94                                                         self.board.update_move(x, y, x2, y2)
95                                                 else:
96                                                         result = None
97                                                         
98                                         else:
99                                                 result = str(x) + " " + str(y) + " -> " + str(x2) + " " + str(y2)
100                                                 self.board.update_move(x, y, x2, y2)
101                                         
102                                         result = p.update(result)
103                                         if self.stopped():
104                                                 break
105                                         for p2 in self.players:
106                                                 if p2 == p:
107                                                         continue
108                                                 p2.update(result) # Inform players of what happened
109                                                 if self.stopped():
110                                                         break
111                                         
112                                         if self.stopped():
113                                                 break
114                                         
115                                         
116                                                                                         
117                                         log(result)
118
119
120                                                                                 
121
122                                         if isinstance(graphics, GraphicsThread):
123                                                 with graphics.lock:
124                                                         graphics.state["moves"] = [[x2,y2]]
125
126                                         time.sleep(turn_delay)
127
128                                         if isinstance(graphics, GraphicsThread):
129                                                 with graphics.lock:
130                                                         graphics.state["select"] = None
131                                                         graphics.state["dest"] = None
132                                                         graphics.state["moves"] = None
133
134                         
135                                         end = self.board.end_condition()
136                                         if end != None:         
137                                                 with self.lock:
138                                                         if end == "DRAW":
139                                                                 self.final_result = self.state["turn"].colour + " " + end
140                                                         else:
141                                                                 self.final_result = end
142                                                 self.stop()
143                                 
144                                         if self.stopped():
145                                                 break
146                                 except Exception,e:
147                                 #if False:
148
149                                         
150                                         result = e.message
151                                         if self.retry_illegal:
152                                                 self.state["turn"].update(result);
153                                         else:
154                                                 sys.stderr.write("qchess.py exception: "+result + "\n")
155                                                 self.stop()
156                                                 with self.lock:
157                                                         self.final_result = self.state["turn"].colour + " " + e.message
158                                                 break
159
160
161
162                 for p2 in self.players:
163                         p2.quit(self.final_result)
164
165                 log(self.final_result)
166
167                 if isinstance(graphics, GraphicsThread):
168                         graphics.stop()
169
170         
171 # A thread that replays a log file
172 class ReplayThread(GameThread):
173         def __init__(self, players, src, end=False,max_moves=None):
174                 self.board = Board(style="empty")
175                 self.board.max_moves = max_moves
176                 GameThread.__init__(self, self.board, players)
177                 self.src = src
178                 self.end = end
179
180                 self.reset_board(self.src.readline())
181
182         def reset_board(self, line):
183                 agent_str = ""
184                 self_str = ""
185                 while line != "# Start game" and line != "# EOF":
186                         
187                         while line == "":
188                                 line = self.src.readline().strip(" \r\n")
189                                 continue
190
191                         if line[0] == '#':
192                                 line = self.src.readline().strip(" \r\n")
193                                 continue
194
195                         self_str += line + "\n"
196
197                         if self.players[0].name == "dummy" and self.players[1].name == "dummy":
198                                 line = self.src.readline().strip(" \r\n")
199                                 continue
200                         
201                         tokens = line.split(" ")
202                         types = map(lambda e : e.strip("[] ,'"), tokens[2:4])
203                         for i in range(len(types)):
204                                 if types[i][0] == "?":
205                                         types[i] = "unknown"
206
207                         agent_str += tokens[0] + " " + tokens[1] + " " + str(types) + " ".join(tokens[4:]) + "\n"
208                         line = self.src.readline().strip(" \r\n")
209
210                 for p in self.players:
211                         p.reset_board(agent_str)
212                 
213                 
214                 self.board.reset_board(self_str)
215
216         
217         def run(self):
218                 move_count = 0
219                 last_line = ""
220                 line = self.src.readline().strip(" \r\n")
221                 while line != "# EOF":
222
223
224                         if self.stopped():
225                                 break
226                         
227                         if len(line) <= 0:
228                                 continue
229                                         
230
231                         if line[0] == '#':
232                                 last_line = line
233                                 line = self.src.readline().strip(" \r\n")
234                                 continue
235
236                         tokens = line.split(" ")
237                         if tokens[0] == "white" or tokens[0] == "black":
238                                 self.reset_board(line)
239                                 last_line = line
240                                 line = self.src.readline().strip(" \r\n")
241                                 continue
242
243                         move = line.split(":")
244                         move = move[len(move)-1].strip(" \r\n")
245                         tokens = move.split(" ")
246                         
247                         
248                         try:
249                                 [x,y] = map(int, tokens[0:2])
250                         except:
251                                 last_line = line
252                                 self.stop()
253                                 break
254
255                         log(move)
256
257                         target = self.board.grid[x][y]
258                         with self.lock:
259                                 if target.colour == "white":
260                                         self.state["turn"] = self.players[0]
261                                 else:
262                                         self.state["turn"] = self.players[1]
263                         
264                         move_piece = (tokens[2] == "->")
265                         if move_piece:
266                                 [x2,y2] = map(int, tokens[len(tokens)-2:])
267
268                         if isinstance(graphics, GraphicsThread):
269                                 with graphics.lock:
270                                         graphics.state["select"] = target
271                                         
272                         if not move_piece:
273                                 self.board.update_select(x, y, int(tokens[2]), tokens[len(tokens)-1])
274                                 if isinstance(graphics, GraphicsThread):
275                                         with graphics.lock:
276                                                 if target.current_type != "unknown":
277                                                         graphics.state["moves"] = self.board.possible_moves(target)
278                                                 else:
279                                                         graphics.state["moves"] = None
280                                         time.sleep(turn_delay)
281                         else:
282                                 self.board.update_move(x, y, x2, y2)
283                                 if isinstance(graphics, GraphicsThread):
284                                         with graphics.lock:
285                                                 graphics.state["moves"] = [[x2,y2]]
286                                         time.sleep(turn_delay)
287                                         with graphics.lock:
288                                                 graphics.state["select"] = None
289                                                 graphics.state["moves"] = None
290                                                 graphics.state["dest"] = None
291                         
292
293                         
294                         
295                         
296                         for p in self.players:
297                                 p.update(move)
298
299                         last_line = line
300                         line = self.src.readline().strip(" \r\n")
301                         
302                         
303                         end = self.board.end_condition()
304                         if end != None:
305                                 self.final_result = end
306                                 self.stop()
307                                 break
308                                         
309                                                 
310                                                 
311
312                         
313                                         
314
315
316                         
317
318                                 
319                         
320
321                 
322
323                 if self.end and isinstance(graphics, GraphicsThread):
324                         #graphics.stop()
325                         pass # Let the user stop the display
326                 elif not self.end and self.board.end_condition() == None:
327                         global game
328                         # Work out the last move
329                                         
330                         t = last_line.split(" ")
331                         if t[len(t)-2] == "black":
332                                 self.players.reverse()
333                         elif t[len(t)-2] == "white":
334                                 pass
335                         elif self.state["turn"] != None and self.state["turn"].colour == "white":
336                                 self.players.reverse()
337
338
339                         game = GameThread(self.board, self.players)
340                         game.run()
341                 else:
342                         pass
343
344                 
345
346 def opponent(colour):
347         if colour == "white":
348                 return "black"
349         else:
350                 return "white"

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