Commit 9b5054e5 authored by Sam Moore's avatar Sam Moore

cgi-script almost working

parent 93279737
#!/usr/bin/python
# CGI wrapper to qchess
import sys
import os
import cgi
import subprocess
import time
import threading
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
def run(self):
self.result = open(name, mode)
w = Worker()
w.start()
start = time.time()
while time.time() - start < timeout:
if w.is_alive() == False:
w.join()
return w.result
time.sleep(0.1)
if w.is_alive():
#sys.stderr.write("FIFO_TIMEOUT!\n")
if mode == "r":
f = open(name, "w")
else:
f = open(name, "r")
#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()
return w.result
def quit():
try:
fifo_out = open_fifo("../cgi-data/"+client+".in", "w", 5)
except:
pass
else:
fifo_out.write("quit\n")
fifo_out.close()
try:
fifo_in = open_fifo("../cgi-data/"+client+".out", "w", 5)
except:
pass
else:
s = fifo_in.readline().strip(" \r\n")
while s != "":
#print s
s = fifo_in.readline().strip(" \r\n")
fifo_in.close()
time.sleep(0.5)
def main(argv):
global client
#form = cgi.FieldStorage()
#client = cgi.escape(os.environ["REMOTE_ADDR"])
client = "127.0.0.1"
print "Content-Type: text/plain\r\n\r\n"
try:
request = argv[1]
except:
request = None
try:
x = int(argv[1])
y = int(argv[2])
except:
if request == "quit":
quit()
return 0
if os.path.exists("../cgi-bin/"+client+".in") and os.path.exists("../cgi-bin/"+client+".out"):
print "Error: Game in progress expects x and y"
return 1
else:
print "NEW GAME"
args = ["./qchess.py"]
if request == None:
args += ["@fifo:../cgi-data/"+client, "@internal:AgentBishop"]
elif request == "eigengame":
args += ["--server=progcomp.ucc.asn.au", "@fifo:../cgi-data/"+client]
subprocess.Popen(args)
time.sleep(1)
else:
fifo_out = open_fifo("../cgi-data/"+client+".in", "w")
fifo_out.write("%d %d\n" % (x, y))
fifo_out.close()
sys.stderr.write("\ncgi read from fifo here\n")
try:
fifo_in = open_fifo("../cgi-data/"+client+".out", "r")
except:
quit()
else:
sys.stderr.write("Opened fine\n")
s = fifo_in.readline().strip(" \r\n")
while s != "SELECT?" and s != "MOVE?" and s.split(" ")[0] not in ["white", "black"]:
if s != "":
print s
s = fifo_in.readline().strip(" \r\n")
print s
fifo_in.close()
if s.split(" ")[0] in ["white", "black"]:
quit()
sys.stderr.write("Done\n")
return 0
if __name__ == "__main__":
try:
sys.exit(main(sys.argv))
except Exception, e:
print "Exception: ", e
sys.exit(1)
...@@ -651,9 +651,60 @@ class Player(): ...@@ -651,9 +651,60 @@ class Player():
def base_player(self): def base_player(self):
return 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
def run(self):
self.result = open(name, mode)
w = Worker()
w.start()
start = time.time()
while time.time() - start < timeout:
if w.is_alive() == False:
w.join()
return w.result
time.sleep(0.1)
if w.is_alive():
#sys.stderr.write("FIFO_TIMEOUT!\n")
if mode == "r":
f = open(name, "w")
else:
f = open(name, "r")
#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()
return w.result
# Player that runs through a fifo # Player that runs through a fifo
class FifoPlayer(Player): class FifoPlayer(Player):
timeout = 300
def __init__(self, name, colour): def __init__(self, name, colour):
Player.__init__(self, name, colour) Player.__init__(self, name, colour)
os.mkfifo(self.name+".in") os.mkfifo(self.name+".in")
...@@ -665,37 +716,58 @@ class FifoPlayer(Player): ...@@ -665,37 +716,58 @@ class FifoPlayer(Player):
def update(self, result): def update(self, result):
sys.stderr.write("update fifo called\n") sys.stderr.write("update fifo called\n")
self.fifo_out = open(self.name+".out", "w") try:
self.fifo_out.write(result +"\n") self.fifo_out = open_fifo(self.name+".out", "w", FifoPlayer.timeout)
self.fifo_out.close() except:
return result raise Exception("FIFO_TIMEOUT")
else:
self.fifo_out.write(result +"\n")
self.fifo_out.close()
return result
def select(self): def select(self):
sys.stderr.write("select fifo called\n") sys.stderr.write("select fifo called\n")
self.fifo_out = open(self.name+".out", "w") try:
self.fifo_out.write("SELECT?\n") self.fifo_out = open_fifo(self.name+".out", "w", FifoPlayer.timeout)
self.fifo_out.close() except:
self.fifo_in = open(self.name+".in", "r") #sys.stderr.write("TIMEOUT\n")
s = map(int, self.fifo_in.readline().strip(" \r\n").split(" ")) raise Exception("FIFO_TIMEOUT")
self.fifo_in.close() else:
return s
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): def get_move(self):
sys.stderr.write("get_move fifo called\n") sys.stderr.write("get_move fifo called\n")
self.fifo_out = open(self.name+".out", "w") try:
self.fifo_out.write("MOVE?\n") self.fifo_out = open_fifo(self.name+".out", "w", FifoPlayer.timeout)
self.fifo_out.close() except:
self.fifo_in = open(self.name+".in", "r") raise Exception("FIFO_TIMEOUT")
s = map(int, self.fifo_in.readline().strip(" \r\n").split(" ")) else:
self.fifo_in.close() self.fifo_out.write("MOVE?\n")
return s 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): def quit(self, result):
self.fifo_out = open(self.name+".out", "w") try:
self.fifo_out.write(result + "\n") self.fifo_out = open_fifo(self.name+".out", "w", FifoPlayer.timeout)
self.fifo_out.close() except:
os.remove(self.name+".in") os.remove(self.name+".in")
os.remove(self.name+".out") 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 # Player that runs from another process
class ExternalAgent(Player): class ExternalAgent(Player):
...@@ -1136,8 +1208,11 @@ class Worker(multiprocessing.Process): ...@@ -1136,8 +1208,11 @@ class Worker(multiprocessing.Process):
self.q = q self.q = q
def run(self): def run(self):
#print str(self) + " runs " + str(self.function) + " with args " + str(self.args) #print str(self) + " runs " + str(self.function) + " with args " + str(self.args)
#try:
self.q.put(self.function(*self.args)) self.q.put(self.function(*self.args))
#except IOError:
# pass
...@@ -1158,7 +1233,7 @@ def TimeoutFunction(function, args, timeout): ...@@ -1158,7 +1233,7 @@ def TimeoutFunction(function, args, timeout):
w.terminate() w.terminate()
s.join() s.join()
raise Exception("TIMEOUT") raise Exception("TIMEOUT")
time.sleep(0.1)
...@@ -1383,8 +1458,7 @@ class StoppableThread(threading.Thread): ...@@ -1383,8 +1458,7 @@ class StoppableThread(threading.Thread):
self._stop.set() self._stop.set()
def stopped(self): def stopped(self):
return self._stop.isSet() return self._stop.isSet()# --- thread_util.py --- #
# --- thread_util.py --- #
log_files = [] log_files = []
import datetime import datetime
import urllib2 import urllib2
...@@ -1600,8 +1674,8 @@ class GameThread(StoppableThread): ...@@ -1600,8 +1674,8 @@ class GameThread(StoppableThread):
for p in self.players: for p in self.players:
with self.lock: with self.lock:
self.state["turn"] = p.base_player() self.state["turn"] = p.base_player()
#try: try:
if True: #if True:
[x,y] = p.select() # Player selects a square [x,y] = p.select() # Player selects a square
if self.stopped(): if self.stopped():
#debug("Quitting in select") #debug("Quitting in select")
...@@ -1703,28 +1777,31 @@ class GameThread(StoppableThread): ...@@ -1703,28 +1777,31 @@ class GameThread(StoppableThread):
graphics.state["dest"] = None graphics.state["dest"] = None
graphics.state["moves"] = None graphics.state["moves"] = None
# Commented out exception stuff for now, because it makes it impossible to tell if I made an IndentationError somewhere
# except Exception,e: end = self.board.end_condition()
# result = e.message if end != None:
# #sys.stderr.write(result + "\n") with self.lock:
# if end == "DRAW":
# self.stop() self.final_result = self.state["turn"].colour + " " + end
# with self.lock: else:
# self.final_result = self.state["turn"].colour + " " + e.message self.final_result = end
self.stop()
end = self.board.end_condition()
if end != None:
with self.lock:
if end == "DRAW":
self.final_result = self.state["turn"].colour + " " + end
else:
self.final_result = end
self.stop()
if self.stopped(): if self.stopped():
break
except Exception,e:
#if False:
result = e.message
#sys.stderr.write(result + "\n")
self.stop()
with self.lock:
self.final_result = self.state["turn"].colour + " " + e.message
break break
for p2 in self.players: for p2 in self.players:
p2.quit(self.final_result) p2.quit(self.final_result)
...@@ -2501,7 +2578,7 @@ def dedicated_server(): ...@@ -2501,7 +2578,7 @@ def dedicated_server():
return 0 return 0
def client(addr): def client(addr, player="@human"):
...@@ -2516,9 +2593,9 @@ def client(addr): ...@@ -2516,9 +2593,9 @@ def client(addr):
s.close() s.close()
if colour == "white": if colour == "white":
p = subprocess.Popen(["python", "qchess.py", "@human", "@network:"+addr+":"+port]) p = subprocess.Popen(["python", "qchess.py", player, "@network:"+addr+":"+port])
else: else:
p = subprocess.Popen(["python", "qchess.py", "@network:"+addr+":"+port, "@human"]) p = subprocess.Popen(["python", "qchess.py", "@network:"+addr+":"+port, player])
p.wait() p.wait()
return 0# --- server.py --- # return 0# --- server.py --- #
#!/usr/bin/python -u #!/usr/bin/python -u
...@@ -2722,7 +2799,13 @@ def main(argv): ...@@ -2722,7 +2799,13 @@ def main(argv):
if server_addr == True: if server_addr == True:
return dedicated_server() return dedicated_server()
else: else:
return client(server_addr) if len(players) > 1:
sys.stderr.write("Only a single player may be provided when --server is used\n")
return 1
if len(players) == 1:
return client(server_addr, players[0].name)
else:
return client(server_addr)
# Create the board # Create the board
...@@ -2891,4 +2974,4 @@ if __name__ == "__main__": ...@@ -2891,4 +2974,4 @@ if __name__ == "__main__":
# --- main.py --- # # --- main.py --- #
# EOF - created from make on Thu May 16 23:54:28 WST 2013 # EOF - created from make on Sun May 19 00:54:03 WST 2013
...@@ -2,10 +2,9 @@ ...@@ -2,10 +2,9 @@
class AgentBishop(AgentRandom): # Inherits from AgentRandom (in qchess) class AgentBishop(AgentRandom): # Inherits from AgentRandom (in qchess)
def __init__(self, name, colour): def __init__(self, name, colour,value={"pawn" : 1, "bishop" : 3, "knight" : 3, "rook" : 5, "queen" : 9, "king" : 100, "unknown" : 2}):
InternalAgent.__init__(self, name, colour) InternalAgent.__init__(self, name, colour)
self.value = {"pawn" : 1, "bishop" : 3, "knight" : 3, "rook" : 5, "queen" : 9, "king" : 100, "unknown" : 4} self.value = value
self.aggression = 2.0 # Multiplier for scoring due to aggressive actions self.aggression = 2.0 # Multiplier for scoring due to aggressive actions
self.defence = 1.0 # Multiplier for scoring due to defensive actions self.defence = 1.0 # Multiplier for scoring due to defensive actions
......
...@@ -332,6 +332,12 @@ class Board(): ...@@ -332,6 +332,12 @@ class Board():
return result return result
def prob_is_type(self, p, state): def prob_is_type(self, p, state):
if p.current_type != 0:
if state == p.current_type:
return 1.0
else:
return 0.0
prob = 0.5 prob = 0.5
result = 0 result = 0
for i in range(len(p.types)): for i in range(len(p.types)):
...@@ -487,6 +493,8 @@ class Board(): ...@@ -487,6 +493,8 @@ class Board():
def on_board(self, x, y): def on_board(self, x, y):
return (x >= 0 and x < w) and (y >= 0 and y < h) return (x >= 0 and x < w) and (y >= 0 and y < h)
# Pushes a move temporarily # Pushes a move temporarily
def push_move(self, piece, x, y): def push_move(self, piece, x, y):
target = self.grid[x][y] target = self.grid[x][y]
...@@ -512,5 +520,5 @@ class Board(): ...@@ -512,5 +520,5 @@ class Board():
self.grid[x2][y2] = target self.grid[x2][y2] = target
for p in self.pieces["white"] + self.pieces["black"]: for p in self.pieces["white"] + self.pieces["black"]:
p.possible_moves = None p.possible_moves = None
...@@ -29,8 +29,8 @@ class GameThread(StoppableThread): ...@@ -29,8 +29,8 @@ class GameThread(StoppableThread):
for p in self.players: for p in self.players:
with self.lock: with self.lock:
self.state["turn"] = p.base_player() self.state["turn"] = p.base_player()
#try: try:
if True: #if True:
[x,y] = p.select() # Player selects a square [x,y] = p.select() # Player selects a square
if self.stopped(): if self.stopped():
#debug("Quitting in select") #debug("Quitting in select")
...@@ -80,10 +80,10 @@ class GameThread(StoppableThread): ...@@ -80,10 +80,10 @@ class GameThread(StoppableThread):
graphics.state["dest"] = None graphics.state["dest"] = None
continue continue
try: #try:
[x2,y2] = p.get_move() # Player selects a destination [x2,y2] = p.get_move() # Player selects a destination
except: #except:
self.stop() # self.stop()
if self.stopped(): if self.stopped():
#debug("Quitting in get_move") #debug("Quitting in get_move")
...@@ -132,28 +132,31 @@ class GameThread(StoppableThread): ...@@ -132,28 +132,31 @@ class GameThread(StoppableThread):
graphics.state["dest"] = None graphics.state["dest"] = None
graphics.state["moves"] = None graphics.state["moves"] = None
# Commented out exception stuff for now, because it makes it impossible to tell if I made an IndentationError somewhere
# except Exception,e: end = self.board.end_condition()
# result = e.message if end != None:
# #sys.stderr.write(result + "\n") with self.lock:
# if end == "DRAW":
# self.stop() self.final_result = self.state["turn"].colour + " " + end
# with self.lock: else:
# self.final_result = self.state["turn"].colour + " " + e.message self.final_result = end
self.stop()
end = self.board.end_condition()
if end != None:
with self.lock:
if end == "DRAW":
self.final_result = self.state["turn"].colour + " " + end
else:
self.final_result = end
self.stop()
if self.stopped(): if self.stopped():
break
except Exception,e:
#if False:
result = e.message
#sys.stderr.write(result + "\n")
self.stop()
with self.lock:
self.final_result = self.state["turn"].colour + " " + e.message