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

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