Commit 0c7750e6 authored by Sam Moore's avatar Sam Moore

Continuing with prettified results

Now generating html files for each agent showing the results for each round as the rounds are played.
parent 6515461b
......@@ -7,6 +7,8 @@
Plays exactly ONE round, but does not overwrite previously played rounds
eg: run once to generate round1.results, twice to generate round2.results etc
Also generates total.scores based on results from every round.
Now (sortof) generates .html files to display results in a prettiful manner.
author Sam Moore (matches) [SZM]
......@@ -49,9 +51,9 @@ if len(sys.argv) >= 5:
scores = {"VICTORY":(3,1, "DEFEAT"), "DEFEAT":(1,3, "VICTORY"), "SURRENDER":(1,3, "VICTORY"), "DRAW":(2,2, "DRAW"), "DRAW_DEFAULT":(1,1, "DRAW_DEFAULT"), "ILLEGAL":(-1,2, "DEFAULT"), "DEFAULT":(2,-1, "ILLEGAL"), "BOTH_ILLEGAL":(-1,-1, "BOTH_ILLEGAL"), "INTERNAL_ERROR":(0,0, "INTERNAL_ERROR"), "BAD_SETUP":(0,0,"BAD_SETUP")}
#Verbose - print lots of useless stuff about what you are doing (kind of like matches in irc...)
#Verbose - print lots of useless stuff about what you are doing (kind of like matches talking on irc...)
verbose = True
makePrettyResults = False
#Check the manager program exists TODO: And is executable!
......@@ -74,74 +76,105 @@ if os.path.exists(logDirectory) == False:
startTime = time() #Record time at which simulation starts
#Do each round...
for roundNumber in range(totalRounds, totalRounds + nRounds):
if os.path.exists(logDirectory + "round"+str(roundNumber)) == False:
os.mkdir(logDirectory + "round"+str(roundNumber)) #Check there is a directory for this round's logs
if verbose:
if nRounds > 1:
print "Simulating " + str(nRounds) + " rounds (" + str(totalRounds) + " to " + str(totalRounds + nRounds-1) + ")"
else:
print "Simulating one round."
print ""
print "Identifying possible agents in \""+agentsDirectory+"\""
#Get all agent names from agentsDirectory
#TODO: Move this part outside the loop? It only has to happen once
agentNames = os.listdir(agentsDirectory)
agents = []
for name in agentNames:
if verbose:
print "Simulating ROUND " +str(roundNumber)
print "Identifying possible agents in \""+agentsDirectory+"\""
#Get all agent names from agentsDirectory
#TODO: Move this part outside the loop? It only has to happen once
agentNames = os.listdir(agentsDirectory)
agents = []
for name in agentNames:
#sys.stdout.write("\nLooking at Agent: \""+ str(name)+"\"... ")
sys.stdout.write("Scan \""+name+"\"... ")
if os.path.isdir(agentsDirectory+name) == False: #Remove non-directories
if verbose:
sys.stdout.write("Scan \""+name+"\"... ")
if os.path.isdir(agentsDirectory+name) == False: #Remove non-directories
if verbose:
sys.stdout.write(" Invalid! (Not a directory)\n")
continue
sys.stdout.write(" Invalid! (Not a directory)\n")
continue
if os.path.exists(agentsDirectory+name+"/info") == False: #Try and find the special "info" file in each directory; ignore if it doesn't exist
if verbose:
sys.stdout.write(" Invalid! (No \"info\" file found)\n")
continue
if os.path.exists(agentsDirectory+name+"/info") == False: #Try and find the special "info" file in each directory; ignore if it doesn't exist
if verbose:
sys.stdout.write(" Invalid! (No \"info\" file found)\n")
continue
agentExecutable = agentsDirectory+name+"/"+(open(agentsDirectory+name+"/info").readline().strip())
agentExecutable = agentsDirectory+name+"/"+(open(agentsDirectory+name+"/info").readline().strip())
if os.path.exists(agentExecutable) == False:
if verbose:
sys.stdout.write(" Invalid! (File \""+agentExecutable+"\" does not exist!)\n")
continue
if os.path.exists(agentExecutable) == False:
if verbose:
sys.stdout.write(" Invalid! (Path: \""+agentExecutable+"\" does not exist!)\n")
continue
if verbose:
sys.stdout.write(" Valid! (To run: \""+agentExecutable+"\")\n")
#Convert array of valid names into array of dictionaries containing information about each agent
#I'm starting to like python...
agents.append({"name":name, "path":agentExecutable,"score":[0], "totalScore":0, "VICTORY":[], "DEFEAT":[], "DRAW":[], "ILLEGAL":[], "INTERNAL_ERROR":[]})
if len(agents) == 0:
print "Couldn't find any agents! Check paths (Edit this script) or generate \"info\" files for agents."
sys.exit(0)
if verbose:
print "Total: " + str(len(agents)) + " valid agents found (From "+str(len(agentNames))+" possibilities)"
print ""
print "Commencing ROUND " + str(roundNumber) + " combat! This could take a while... "
sys.stdout.write(" Valid! (Path: \""+agentExecutable+"\")\n")
#Convert array of valid names into array of dictionaries containing information about each agent
#I'm starting to like python...
agents.append({"name":name, "path":agentExecutable,"score":[0], "totalScore":0, "VICTORY":[], "DEFEAT":[], "DRAW":[], "ILLEGAL":[], "INTERNAL_ERROR":[], "ALL":[]})
if len(agents) == 0:
print "Couldn't find any agents! Check paths (Edit this script) or generate \"info\" files for agents."
sys.exit(0)
if verbose:
print "Total: " + str(len(agents)) + " valid agents found (From "+str(len(agentNames))+" possibilities)"
print ""
#Prepare the pretty .html files if they don't exist
htmlDir = resultsDirectory + "pretty/"
if os.path.exists(htmlDir) == False:
os.mkdir(htmlDir)
if os.path.exists(htmlDir) == False:
print "Couldn't create directory \""+htmlDir+"\"."
sys.exit(1)
for agent in agents:
if os.path.exists(htmlDir+agent["name"] + ".html") == False:
agentFile = open(htmlDir+agent["name"] + ".html", "w")
agentFile.write("<html>\n<head>\n <title> " + agent["name"] + " results</title>\n</head>\n<body>\n<h1> Results for " + agent["name"]+" </h1>\n</body>\n</html>\n")
agentFile.close()
os.rename(htmlDir+agent["name"] + ".html", "tmpfile")
oldFile = open("tmpfile")
agentFile = open(htmlDir+agent["name"] + ".html", "w")
for line in oldFile:
if line.strip() == "</body>":
break
agentFile.write(line + "\n")
oldFile.close()
agentFile.close()
os.remove("tmpfile")
#Do each round...
totalGames = nGames/2 * len(agents) * (len(agents)-1)
for roundNumber in range(totalRounds, totalRounds + nRounds):
if os.path.exists(logDirectory + "round"+str(roundNumber)) == False:
os.mkdir(logDirectory + "round"+str(roundNumber)) #Check there is a directory for this round's logs
print "Commencing ROUND " + str(roundNumber) + " combat!"
print "Total: " + str(totalGames) + " games to be played. This could take a while... (Estimate 60s/game)"
normalGames = 0
draws = 0
aiErrors = 0
managerErrors = 0
#This double for loop simulates a round robin, with each agent getting the chance to play as both red and blue against every other agent.
gameID = 0
gameNumber = 0
for red in agents: #for each agent playing as red,
for blue in agents: #against each other agent, playing as blue
if red == blue:
continue #Exclude battles against self
gameID += 1
gameNumber += 1
gameID = str(roundNumber) + "." + str(gameNumber)
for i in range(1, nGames/2 + 1):
#Play a game and read the result. Note the game is logged to a file based on the agent's names
if verbose:
sys.stdout.write("Agents: \""+red["name"]+"\" and \""+blue["name"]+"\" playing game " + str(i) + "/"+str(nGames/2) + "... ")
sys.stdout.write("Agents: \""+red["name"]+"\" and \""+blue["name"]+"\" playing game (ID: " + gameID + ") ... ")
logFile = logDirectory + "round"+str(roundNumber) + "/"+red["name"]+".vs."+blue["name"]+"."+str(i)
outline = os.popen(managerPath + " -o " + logFile + " " + red["path"] + " " + blue["path"], "r").read()
results = outline.split(' ')
......@@ -149,24 +182,40 @@ for roundNumber in range(totalRounds, totalRounds + nRounds):
if len(results) != 6:
if verbose:
sys.stdout.write("Garbage output! \"" + outline + "\"\n")
red["manager_errors"].append((gameID, blue["name"]))
red["INTERNAL_ERROR"].append((blue["name"], gameID, scores["INTERNAL_ERROR"][0]))
blue["INTERNAL_ERROR"].append((red["name"], gameID, scores["INTERNAL_ERROR"][0]))
red["ALL"].append((blue["name"], gameID, scores["INTERNAL_ERROR"][0], "INTERNAL_ERROR"))
blue["ALL"].append((red["name"], gameID, scores["INTERNAL_ERROR"][0], "INTERNAL_ERROR"))
managerErrors += 1
else:
if results[1] == "RED":
endColour = red
otherColour = blue
endStr = "RED"
otherStr = "BLUE"
elif results[1] == "BLUE":
endColour = blue
otherColour = red
endStr = "BLUE"
otherStr = "RED"
if results[1] == "BOTH":
pass
red["INTERNAL_ERROR"].append((blue["name"], gameID, scores["INTERNAL_ERROR"][0]))
blue["INTERNAL_ERROR"].append((red["name"], gameID, scores["INTERNAL_ERROR"][0]))
red["ALL"].append((blue["name"], gameID, scores["INTERNAL_ERROR"][0], "INTERNAL_ERROR", "RED"))
blue["ALL"].append((red["name"], gameID, scores["INTERNAL_ERROR"][0], "INTERNAL_ERROR", "BLUE"))
managerErrors += 1
else:
endColour["score"].insert(0,endColour["score"][0] + scores[results[2]][0])
endColour[results[2]].append((otherColour["name"], gameID, scores[results[2]][0]))
endColour["ALL"].append((otherColour["name"], gameID, scores[results[2]][0], results[2], endStr))
otherColour["score"].insert(0, otherColour["score"][0] + scores[results[2]][1])
otherColour[scores[results[2]][2]].append((endColour["name"], gameID, scores[results[2]][1]))
otherColour["ALL"].append((endColour["name"], gameID, scores[results[2]][1], scores[results[2]][2], otherStr))
if verbose:
sys.stdout.write(" Result \"")
for ii in range(1, len(results)):
......@@ -176,16 +225,16 @@ for roundNumber in range(totalRounds, totalRounds + nRounds):
sys.stdout.write("\"\n")
if verbose:
print "Completed combat. Total of " + str(normalGames + draws + aiErrors + managerErrors) + " games played. "
print "Completed combat. Total of " + str(gameNumber) + " games played. "
if managerErrors != 0:
print "WARNING: Recieved "+str(managerErrors)+" garbage outputs. Check the manager program."
print "WARNING: Registered "+str(managerErrors)+" errors. Check the manager program."
if verbose:
print ""
#We should now have complete score values.
if verbose:
sys.stdout.write("Creating results files for ROUND " + str(roundNumber) + "... ")
sys.stdout.write("Creating raw results files for ROUND " + str(roundNumber) + "... ")
agents.sort(key = lambda e : e["score"], reverse=True) #Sort the agents based on score
......@@ -221,24 +270,51 @@ for roundNumber in range(totalRounds, totalRounds + nRounds):
print "Finished writing results for ROUND " + str(roundNumber)
print ""
print "RESULTS FOR ROUND " + str(roundNumber)
if verbose:
print "RESULTS FOR ROUND " + str(roundNumber)
totalFile = open(resultsDirectory+"total.scores", "w") #Recreate the file
for agent in agents:
for agent in agents:
totalFile.write(agent["name"] + " " + str(agent["totalScore"]) +"\n") #Write the total scores in descending order
print "Agent: " + str(agent)
if verbose:
print "Agent: " + str(agent)
if verbose:
print "Updating pretty .html files... "
#I just want to say the even though I still think python is evil, it is much better than bash. Using bash makes me cry.
endTime = time()
print "Completed simulating " + str(nRounds) + " rounds in " + str(endTime - startTime) + " seconds."
if makePrettyResults:
if verbose:
print "Now creating prettiful .html files..."
for agent in agents:
agentFile = open(htmlDir + agent["name"]+".html", "a")
agentFile.write("<h2> Round " + str(roundNumber) + "</h2>\n")
agentFile.write("<h3> Summary </h3>\n")
agentFile.write("<table border=\"0\" cellpadding=\"10\">\n")
agentFile.write("<tr> <th> Score </th> <th> Wins </th> <th> Losses </th> <th> Draws </th> <th> Illegal </th> <th> Errors </th></tr>\n")
agentFile.write("<tr> <td> "+str(agent["score"][0])+" </td> <td> "+str(len(agent["VICTORY"]))+" </td> <td> "+str(len(agent["DEFEAT"]))+" </td> <td> "+str(len(agent["DRAW"]))+" </td> <td> "+str(len(agent["ILLEGAL"]))+" </td> <td> " +str(len(agent["INTERNAL_ERROR"]))+" </td> </tr>\n")
agentFile.write("</table>\n")
agentFile.write("<h3> Detailed </h3>\n")
agentFile.write("<table border=\"0\" cellpadding=\"10\">\n")
agentFile.write("<tr> <th> Game ID </th> <th> Opponent </th> <th> Played as </th> <th> Outcome </th> <th> Score </th> <th> Accumulated Score </th> </tr> </th>\n")
for index in range(0, len(agent["ALL"])):
agentFile.write("<tr> <td> " + str(agent["ALL"][index][1]) + " </td> <td> <a href="+agent["ALL"][index][0]+".html>"+agent["ALL"][index][0] + " </a> </td> <td> " + agent["ALL"][index][4] + " </td> <td> " + agent["ALL"][index][3] + " </td> <td> " + str(agent["ALL"][index][2]) + "</td> <td> " + str(agent["score"][len(agent["score"])-index -2]) + " </td> </tr> </th>\n")
agentFile.write("</table>\n")
agentFile.close()
if verbose:
print "Finalising .html files... "
for agent in agents:
agentFile = open(htmlDir + agent["name"]+".html", "a")
agentFile.write("</body>\n<!-- Results file for \"" + agent["name"] + "\" autogenerated by \"" + sys.argv[0] + "\" at time " + str(time()) + " -->\n</html>\n\n")
agentFile.close()
if verbose:
print "Done!"
endTime = time()
print "Completed simulating " + str(nRounds) + " rounds in " + str(endTime - startTime) + " seconds."
sys.exit(0)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment