X-Git-Url: https://git.ucc.asn.au/?p=progcomp2013.git;a=blobdiff_plain;f=qchess%2Fsrc%2Fplayer.py;h=99d36165412e76c21173a57427679e7da4943018;hp=3e6fabadb566b04e856d3ea4e9709345b7498558;hb=639646adb020e0be9433da7b3d5ef6b987c99f71;hpb=444244d5c7698bb7861cdb7c0ec6bfb0e8cebfb7 diff --git a/qchess/src/player.py b/qchess/src/player.py index 3e6faba..99d3616 100644 --- a/qchess/src/player.py +++ b/qchess/src/player.py @@ -1,7 +1,7 @@ import subprocess import select import platform - +import re agent_timeout = -1.0 # Timeout in seconds for AI players to make moves # WARNING: Won't work for windows based operating systems @@ -15,13 +15,19 @@ class Player(): self.name = name self.colour = colour + def update(self, result): + return result + + def reset_board(self, s): + pass + # Player that runs from another process -class AgentPlayer(Player): +class ExternalAgent(Player): def __init__(self, name, colour): Player.__init__(self, name, colour) - self.p = subprocess.Popen(name, stdin=subprocess.PIPE, stdout=subprocess.PIPE,stderr=subprocess.PIPE) + self.p = subprocess.Popen(name,bufsize=0,stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True,universal_newlines=True) self.send_message(colour) @@ -31,13 +37,13 @@ class AgentPlayer(Player): else: ready = [self.p.stdin] if self.p.stdin in ready: - #print "Writing to p.stdin" + #sys.stderr.write("Writing \'" + s + "\' to " + str(self.p) + "\n") try: self.p.stdin.write(s + "\n") except: raise Exception("UNRESPONSIVE") else: - raise Exception("UNRESPONSIVE") + raise Exception("TIMEOUT") def get_response(self): if agent_timeout > 0.0: @@ -45,13 +51,15 @@ class AgentPlayer(Player): else: ready = [self.p.stdout] if self.p.stdout in ready: - #print "Reading from p.stdout" + #sys.stderr.write("Reading from " + str(self.p) + " 's stdout...\n") try: - return self.p.stdout.readline().strip("\r\n") + result = self.p.stdout.readline().strip(" \t\r\n") + #sys.stderr.write("Read \'" + result + "\' from " + str(self.p) + "\n") + return result except: # Exception, e: raise Exception("UNRESPONSIVE") else: - raise Exception("UNRESPONSIVE") + raise Exception("TIMEOUT") def select(self): @@ -59,7 +67,8 @@ class AgentPlayer(Player): line = self.get_response() try: - result = map(int, line.split(" ")) + m = re.match("\s*(\d+)\s+(\d+)\s*", line) + result = map(int, [m.group(1), m.group(2)]) except: raise Exception("GIBBERISH \"" + str(line) + "\"") return result @@ -67,7 +76,7 @@ class AgentPlayer(Player): def update(self, result): #print "Update " + str(result) + " called for AgentPlayer" self.send_message(result) - + return result def get_move(self): @@ -75,11 +84,19 @@ class AgentPlayer(Player): line = self.get_response() try: - result = map(int, line.split(" ")) + m = re.match("\s*(\d+)\s+(\d+)\s*", line) + result = map(int, [m.group(1), m.group(2)]) + except: raise Exception("GIBBERISH \"" + str(line) + "\"") return result + def reset_board(self, s): + self.send_message("BOARD") + for line in s.split("\n"): + self.send_message(line.strip(" \r\n")) + self.send_message("END BOARD") + def quit(self, final_result): try: self.send_message("QUIT " + final_result) @@ -145,16 +162,35 @@ class HumanPlayer(Player): pass else: sys.stdout.write(result + "\n") + return result -# Player that makes random moves -class AgentRandom(Player): +# Default internal player (makes random moves) +class InternalAgent(Player): def __init__(self, name, colour): Player.__init__(self, name, colour) self.choice = None self.board = Board(style = "agent") + + + def update(self, result): + + self.board.update(result) + #self.board.verify() + return result + + def reset_board(self, s): + self.board.reset_board(s) + + def quit(self, final_result): + pass + +class AgentRandom(InternalAgent): + def __init__(self, name, colour): + InternalAgent.__init__(self, name, colour) + def select(self): while True: self.choice = self.board.pieces[self.colour][random.randint(0, len(self.board.pieces[self.colour])-1)] @@ -179,12 +215,46 @@ class AgentRandom(Player): move = moves[random.randint(0, len(moves)-1)] return move - def update(self, result): - #sys.stderr.write(sys.argv[0] + " : Update board for AgentRandom\n") - self.board.update(result) - self.board.verify() - def quit(self, final_result): - pass +# Terrible, terrible hacks + +def run_agent(agent): + #sys.stderr.write(sys.argv[0] + " : Running agent " + str(agent) + "\n") + while True: + line = sys.stdin.readline().strip(" \r\n") + if line == "SELECTION?": + #sys.stderr.write(sys.argv[0] + " : Make selection\n") + [x,y] = agent.select() # Gets your agent's selection + #sys.stderr.write(sys.argv[0] + " : Selection was " + str(agent.choice) + "\n") + sys.stdout.write(str(x) + " " + str(y) + "\n") + elif line == "MOVE?": + #sys.stderr.write(sys.argv[0] + " : Make move\n") + [x,y] = agent.get_move() # Gets your agent's move + sys.stdout.write(str(x) + " " + str(y) + "\n") + elif line.split(" ")[0] == "QUIT": + #sys.stderr.write(sys.argv[0] + " : Quitting\n") + agent.quit(" ".join(line.split(" ")[1:])) # Quits the game + break + elif line.split(" ")[0] == "BOARD": + s = "" + line = sys.stdin.readline().strip(" \r\n") + while line != "END BOARD": + s += line + "\n" + line = sys.stdin.readline().strip(" \r\n") + agent.board.reset_board(s) + + else: + agent.update(line) # Updates agent.board + return 0 + + +# Sort of works? + +class ExternalWrapper(ExternalAgent): + def __init__(self, agent): + run = "python -u -c \"import sys;import os;from qchess import *;agent = " + agent.__class__.__name__ + "('" + agent.name + "','"+agent.colour+"');sys.stdin.readline();sys.exit(run_agent(agent))\"" + # str(run) + ExternalAgent.__init__(self, run, agent.colour) +