X-Git-Url: https://git.ucc.asn.au/?p=progcomp2013.git;a=blobdiff_plain;f=qchess%2Fsrc%2Fplayer.py;h=a5749957fd20a3bc454f54351247f5fcd9177364;hp=d0f6cfb8d8c66c16e989666759b933283cb97f4c;hb=HEAD;hpb=5287b4f869be70ddae4b59a44c448be33f95ccda diff --git a/qchess/src/player.py b/qchess/src/player.py index d0f6cfb..a574995 100644 --- a/qchess/src/player.py +++ b/qchess/src/player.py @@ -16,10 +16,155 @@ class Player(): self.colour = colour def update(self, result): - pass + return result def reset_board(self, s): pass + + def __str__(self): + return self.name + "<"+str(self.colour)+">" + + def base_player(self): + return self + + + + + +def open_fifo(name, mode, timeout=None): + if timeout == None: + return open(name, mode) + + + class Worker(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + self.result = None + self.exception = None + + + def run(self): + try: + self.result = open(name, mode) + except Exception, e: + self.exception = e + self.result = None + + + w = Worker() + w.start() + + start = time.time() + while time.time() - start < timeout: + if w.is_alive() == False: + w.join() + if w.exception != None: + raise w.exception + return w.result + time.sleep(0.1) + + + if w.is_alive(): + #sys.stderr.write("FIFO_TIMEOUT!\n") + # Recursive to deal with possible race condition + try: + if mode == "r": + f = open_fifo(name, "w", 1) + else: + f = open_fifo(name, "r", 1) + except: + pass + + #sys.stderr.write("Opened other end!\n") + while w.is_alive(): + time.sleep(0.1) + + w.join() + f.close() + w.result.close() + raise Exception("FIFO_TIMEOUT") + else: + w.join() + if w.exception != None: + raise w.exception + return w.result + + +# Player that runs through a fifo +class FifoPlayer(Player): + + timeout = 300 + + def __init__(self, name, colour): + Player.__init__(self, name, colour) + os.mkfifo(self.name+".in") + os.mkfifo(self.name+".out") + + + try: + self.fifo_out = open_fifo(self.name+".out","w", FifoPlayer.timeout) + except: + raise Exception("FIFO_TIMEOUT") + else: + self.fifo_out.write("START "+colour+"\n") + self.fifo_out.close() + + + def update(self, result): + sys.stderr.write("update fifo called\n") + try: + self.fifo_out = open_fifo(self.name+".out", "w", FifoPlayer.timeout) + except: + raise Exception("FIFO_TIMEOUT") + else: + self.fifo_out.write(result +"\n") + self.fifo_out.close() + return result + + def select(self): + sys.stderr.write("select fifo called\n") + try: + self.fifo_out = open_fifo(self.name+".out", "w", FifoPlayer.timeout) + except: + #sys.stderr.write("TIMEOUT\n") + raise Exception("FIFO_TIMEOUT") + else: + + self.fifo_out.write("SELECT?\n") + self.fifo_out.close() + self.fifo_in = open_fifo(self.name+".in", "r", FifoPlayer.timeout) + s = map(int, self.fifo_in.readline().strip(" \r\n").split(" ")) + self.fifo_in.close() + return s + + def get_move(self): + sys.stderr.write("get_move fifo called\n") + try: + self.fifo_out = open_fifo(self.name+".out", "w", FifoPlayer.timeout) + except: + raise Exception("FIFO_TIMEOUT") + else: + self.fifo_out.write("MOVE?\n") + self.fifo_out.close() + self.fifo_in = open_fifo(self.name+".in", "r", FifoPlayer.timeout) + s = map(int, self.fifo_in.readline().strip(" \r\n").split(" ")) + self.fifo_in.close() + return s + + def quit(self, result): + try: + self.fifo_out = open_fifo(self.name+".out", "w", FifoPlayer.timeout) + except: + pass + else: + self.fifo_out.write(result + "\n") + self.fifo_out.close() + + try: + os.remove(self.name+".in") + os.remove(self.name+".out") + except OSError: + pass # Player that runs from another process class ExternalAgent(Player): @@ -27,6 +172,7 @@ class ExternalAgent(Player): def __init__(self, name, colour): Player.__init__(self, name, colour) + #raise Exception("waht") self.p = subprocess.Popen(name,bufsize=0,stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True,universal_newlines=True) self.send_message(colour) @@ -76,7 +222,7 @@ class ExternalAgent(Player): def update(self, result): #print "Update " + str(result) + " called for AgentPlayer" self.send_message(result) - + return result def get_move(self): @@ -108,6 +254,7 @@ class HumanPlayer(Player): def __init__(self, name, colour): Player.__init__(self, name, colour) + # Select your preferred account def select(self): if isinstance(graphics, GraphicsThread): @@ -129,9 +276,11 @@ class HumanPlayer(Player): sys.stdout.write("SELECTION?\n") try: p = map(int, sys.stdin.readline().strip("\r\n ").split(" ")) + return p except: sys.stderr.write("ILLEGAL GIBBERISH\n") continue + # It's your move captain def get_move(self): if isinstance(graphics, GraphicsThread): @@ -147,6 +296,7 @@ class HumanPlayer(Player): sys.stdout.write("MOVE?\n") try: p = map(int, sys.stdin.readline().strip("\r\n ").split(" ")) + return p except: sys.stderr.write("ILLEGAL GIBBERISH\n") continue @@ -162,6 +312,7 @@ class HumanPlayer(Player): pass else: sys.stdout.write(result + "\n") + return result # Default internal player (makes random moves) @@ -172,12 +323,14 @@ class InternalAgent(Player): self.board = Board(style = "agent") - + def argForm(self): + return "@internal:"+self.name def update(self, result): self.board.update(result) - self.board.verify() + #self.board.verify() + return result def reset_board(self, s): self.board.reset_board(s)