X-Git-Url: https://git.ucc.asn.au/?p=progcomp2013.git;a=blobdiff_plain;f=qchess%2Fqchess.py;h=d2ec1bb6eda440a9a3573bc69aedf721e7070955;hp=02a724ab2ea05a25dce5ea6e31d748c0a8d42f64;hb=a238aa7acac990bae67644d1dc7f518ce3e2e8c6;hpb=a35e4dc5f4fb6325785b6f8b123266976107b748 diff --git a/qchess/qchess.py b/qchess/qchess.py index 02a724a..d2ec1bb 100755 --- a/qchess/qchess.py +++ b/qchess/qchess.py @@ -1199,29 +1199,143 @@ class StoppableThread(threading.Thread): def stopped(self): return self._stop.isSet() # --- thread_util.py --- # - - log_file = None +import datetime +import urllib2 -def log(s): - if log_file != None: - import datetime - log_file.write(str(datetime.datetime.now()) + " : " + s + "\n") +class LogFile(): + def __init__(self, log): + + self.log = log + self.logged = [] + self.log.write("# Log starts " + str(datetime.datetime.now()) + "\n") -def log_init(board, players): - if log_file != None: - import datetime - log_file.write("# Log starts " + str(datetime.datetime.now()) + "\n") + def write(self, s): + now = datetime.datetime.now() + self.log.write(str(now) + " : " + s + "\n") + self.logged.append((now, s)) + + def setup(self, board, players): + for p in players: - log_file.write("# " + p.colour + " : " + p.name + "\n") + self.log.write("# " + p.colour + " : " + p.name + "\n") - log_file.write("# Initial board\n") + self.log.write("# Initial board\n") for x in range(0, w): for y in range(0, h): if board.grid[x][y] != None: - log_file.write(str(board.grid[x][y]) + "\n") + self.log.write(str(board.grid[x][y]) + "\n") + + self.log.write("# Start game\n") + + def close(self): + self.log.write("# EOF\n") + self.log.close() + +class HttpLog(LogFile): + def __init__(self, file_name): + LogFile.__init__(self, open(file_name, "w", 0)) + self.file_name = file_name + self.phase = 0 + + def write(self, s): + now = datetime.datetime.now() + self.logged.append((now, s)) + + if self.phase == 0: + self.log.close() + self.log = open(self.file_name, "w", 0) + self.log.write("# Short log updated " + str(datetime.datetime.now()) + "\n") + LogFile.setup(self, game.board, game.players) + + elif self.phase == 1: + for message in self.logged[len(self.logged)-2:]: + self.log.write(str(message[0]) + " : " + message[1] + "\n") + + self.phase = (self.phase + 1) % 2 + + def close(self): + self.log.write("# EOF\n") + self.log.close() + + +class HeadRequest(urllib2.Request): + def get_method(self): + return "HEAD" + +class HttpGetter(StoppableThread): + def __init__(self, address): + StoppableThread.__init__(self) + self.address = address + self.log = urllib2.urlopen(address) + self.lines = [] + self.lock = threading.RLock() #lock for access of self.state + self.cond = threading.Condition() # conditional + + def run(self): + while not self.stopped(): + line = self.log.readline() + if line == "": + date_mod = datetime.datetime.strptime(self.log.headers['last-modified'], "%a, %d %b %Y %H:%M:%S GMT") + self.log.close() + + next_log = urllib2.urlopen(HeadRequest(self.address)) + date_new = datetime.datetime.strptime(next_log.headers['last-modified'], "%a, %d %b %Y %H:%M:%S GMT") + while date_new <= date_mod and not self.stopped(): + next_log = urllib2.urlopen(HeadRequest(self.address)) + date_new = datetime.datetime.strptime(next_log.headers['last-modified'], "%a, %d %b %Y %H:%M:%S GMT") + if self.stopped(): + break + + self.log = urllib2.urlopen(self.address) + line = self.log.readline() + + self.cond.acquire() + self.lines.append(line) + self.cond.notifyAll() + self.cond.release() + + #sys.stderr.write(" HttpGetter got \'" + str(line) + "\'\n") + + self.log.close() + + + + + +class HttpReplay(): + def __init__(self, address): + self.getter = HttpGetter(address) + self.getter.start() + + def readline(self): + self.getter.cond.acquire() + while len(self.getter.lines) == 0: + self.getter.cond.wait() + + result = self.getter.lines[0] + self.getter.lines = self.getter.lines[1:] + self.getter.cond.release() + + return result + + + def close(self): + self.getter.stop() + +def log(s): + if log_file != None: + log_file.write(s) + + +def log_init(board, players): + if log_file != None: + log_file.setup(board, players) + +# --- log.py --- # + + - log_file.write("# Start game\n") # A thread that runs the game @@ -1292,12 +1406,15 @@ class GameThread(StoppableThread): if self.stopped(): break - self.board.update_move(x, y, x2, y2) result = str(x) + " " + str(y) + " -> " + str(x2) + " " + str(y2) + log(result) + + self.board.update_move(x, y, x2, y2) + for p2 in self.players: p2.update(result) # Inform players of what happened - log(result) + if isinstance(graphics, GraphicsThread): with graphics.lock: @@ -1343,7 +1460,8 @@ class GameThread(StoppableThread): log(self.final_result) - graphics.stop() + if isinstance(graphics, GraphicsThread): + graphics.stop() # A thread that replays a log file @@ -1356,98 +1474,133 @@ class ReplayThread(GameThread): self.line_number = 0 self.end = end - try: - while self.src.readline().strip(" \r\n") != "# Initial board": - self.line_number += 1 + self.reset_board(self.src.readline()) + + def reset_board(self, line): + pieces = {"white" : [], "black" : []} + king = {"white" : None, "black" : None} + grid = [[None] * w for _ in range(h)] + for x in range(w): + for y in range(h): + self.board.grid[x][y] = None + while line != "# Start game": + if line[0] == "#": + line = self.src.readline().strip(" \r\n") + continue + + tokens = line.split(" ") + [x, y] = map(int, tokens[len(tokens)-1].split(",")) + current_type = tokens[1] + types = map(lambda e : e.strip("'[], "), (tokens[2]+tokens[3]).split(",")) + + target = Piece(tokens[0], x, y, types) + target.current_type = current_type + + try: + target.choice = types.index(current_type) + except: + target.choice = -1 + + pieces[tokens[0]].append(target) + if target.current_type == "king": + king[tokens[0]] = target + grid[x][y] = target line = self.src.readline().strip(" \r\n") - - while line != "# Start game": - #print "Reading line " + str(line) - self.line_number += 1 - [x,y] = map(int, line.split("at")[1].strip(" \r\n").split(",")) - colour = line.split(" ")[0] - current_type = line.split(" ")[1] - types = map(lambda e : e.strip(" [],'"), line.split(" ")[2:4]) - p = Piece(colour, x, y, types) - if current_type != "unknown": - p.current_type = current_type - p.choice = types.index(current_type) - - self.board.pieces[colour].append(p) - self.board.grid[x][y] = p - if current_type == "king": - self.board.king[colour] = p - line = self.src.readline().strip(" \r\n") - - except Exception, e: - raise Exception("FILE line: " + str(self.line_number) + " \""+str(line)+"\"") #\n" + e.message) + self.board.pieces = pieces + self.board.king = king + self.board.grid = grid + + # Update the player's boards def run(self): - i = 0 - phase = 0 - count = 0 + move_count = 0 line = self.src.readline().strip(" \r\n") while line != "# EOF": - count += 1 - if self.max_lines != None and count > self.max_lines: - self.stop() - if self.stopped(): break - with self.lock: - self.state["turn"] = self.players[i] + + + if line[0] == '#': + line = self.src.readline().strip(" \r\n") + continue - line = line.split(":") - result = line[len(line)-1].strip(" \r\n") - log(result) + tokens = line.split(" ") + if tokens[0] == "white" or tokens[0] == "black": + self.reset_board(line) + line = self.src.readline().strip(" \r\n") + continue + move = line.split(":") + move = move[len(move)-1].strip(" \r\n") + tokens = move.split(" ") + + try: - self.board.update(result) + [x,y] = map(int, tokens[0:2]) except: - self.final_result = result self.stop() break - [x,y] = map(int, result.split(" ")[0:2]) + log(move) + target = self.board.grid[x][y] + with self.lock: + if target.colour == "white": + self.state["turn"] = self.players[0] + else: + self.state["turn"] = self.players[1] + + move_piece = (tokens[2] == "->") + if move_piece: + [x2,y2] = map(int, tokens[len(tokens)-2:]) if isinstance(graphics, GraphicsThread): - if phase == 0: + with graphics.lock: + graphics.state["select"] = target + + if not move_piece: + self.board.update_select(x, y, int(tokens[2]), tokens[len(tokens)-1]) + if isinstance(graphics, GraphicsThread): with graphics.lock: graphics.state["moves"] = self.board.possible_moves(target) - graphics.state["select"] = target - - if self.end: - time.sleep(turn_delay) - - elif phase == 1: - [x2,y2] = map(int, result.split(" ")[3:5]) + time.sleep(turn_delay) + else: + self.board.update_move(x, y, x2, y2) + if isinstance(graphics, GraphicsThread): with graphics.lock: graphics.state["moves"] = [[x2,y2]] - - if self.end: - time.sleep(turn_delay) - + time.sleep(turn_delay) with graphics.lock: graphics.state["select"] = None - graphics.state["dest"] = None graphics.state["moves"] = None - + graphics.state["dest"] = None + + + + + + for p in self.players: + p.update(move) + line = self.src.readline().strip(" \r\n") + + + + + + + + - for p in self.players: - p.update(result) - phase = (phase + 1) % 2 - if phase == 0: - i = (i + 1) % 2 - line = self.src.readline().strip(" \r\n") + + if self.max_lines != None and self.max_lines > count: sys.stderr.write(sys.argv[0] + " : Replaying from file; stopping at last line (" + str(count) + ")\n") @@ -1470,7 +1623,10 @@ def opponent(colour): else: return "white" # --- game.py --- # -import pygame +try: + import pygame +except: + pass import os # Dictionary that stores the unicode character representations of the different pieces @@ -1552,7 +1708,7 @@ class GraphicsThread(StoppableThread): #print "Test font" pygame.font.Font(os.path.join(os.path.curdir, "data", "DejaVuSans.ttf"), 32).render("Hello", True,(0,0,0)) - #create_images(grid_sz) + #load_images() create_images(grid_sz) """ @@ -2079,17 +2235,25 @@ def main(argv): if len(arg[2:].split("=")) == 1: src_file = sys.stdin else: - src_file = open(arg[2:].split("=")[1].split(":")[0]) + f = arg[2:].split("=")[1] + if f[0] == '@': + src_file = HttpReplay("http://" + f.split(":")[0][1:]) + else: + src_file = open(f.split(":")[0], "r", 0) - if len(arg[2:].split(":")) == 2: - max_lines = int(arg[2:].split(":")[1]) + if len(f.split(":")) == 2: + max_lines = int(f.split(":")[1]) elif (arg[1] == '-' and arg[2:].split("=")[0] == "log"): # Log file if len(arg[2:].split("=")) == 1: - log_file = sys.stdout + log_file = LogFile(sys.stdout) else: - log_file = open(arg[2:].split("=")[1], "w") + f = arg[2:].split("=")[1] + if f[0] == '@': + log_file = HttpLog(f[1:]) + else: + log_file = LogFile(open(f, "w", 0)) elif (arg[1] == '-' and arg[2:].split("=")[0] == "delay"): # Delay if len(arg[2:].split("=")) == 1: @@ -2219,7 +2383,6 @@ def main(argv): if log_file != None and log_file != sys.stdout: - log_file.write("# EOF\n") log_file.close() if src_file != None and src_file != sys.stdin: @@ -2245,4 +2408,4 @@ if __name__ == "__main__": sys.exit(102) # --- main.py --- # -# EOF - created from make on Wed Jan 30 00:45:46 WST 2013 +# EOF - created from make on Wed Jan 30 21:00:29 WST 2013