Trying to fix bug with fifo and network players
[progcomp2013.git] / qchess / src / player.py
index d0f6cfb..37cca67 100644 (file)
@@ -16,10 +16,154 @@ 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:
+                       os.remove(self.name+".in")
+                       os.remove(self.name+".out")
+                       #raise Exception("FIFO_TIMEOUT")
+                       
+               else:
+                       self.fifo_out.write(result + "\n")
+                       self.fifo_out.close()
+                       os.remove(self.name+".in")
+                       os.remove(self.name+".out")
 
 # Player that runs from another process
 class ExternalAgent(Player):
@@ -76,7 +220,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):
                
@@ -129,9 +273,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 +293,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 +309,7 @@ class HumanPlayer(Player):
                        pass
                else:
                        sys.stdout.write(result + "\n") 
+               return result
 
 
 # Default internal player (makes random moves)
@@ -177,7 +325,8 @@ class InternalAgent(Player):
        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)

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