X-Git-Url: https://git.ucc.asn.au/?p=progcomp2012.git;a=blobdiff_plain;f=simulator%2Fsimulate.py;fp=simulator%2Fsimulate.py;h=0000000000000000000000000000000000000000;hp=32f2b4289f4372012cffcb1fd3240c4fcc118f7c;hb=e3b15cd5dea739f7523920d83bda592db95a7b93;hpb=7f7bc05439b70b3139086086608996de3c9ae2ed diff --git a/simulator/simulate.py b/simulator/simulate.py deleted file mode 100755 index 32f2b42..0000000 --- a/simulator/simulate.py +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/python -u - -''' - simulate.py - simulation script for the 2012 UCC Programming Competition - NOTE: This is not the manager program for a stratego game - It merely calls the manager program as appropriate, and records results - 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. - - - author Sam Moore (matches) [SZM] - website http://matches.ucc.asn.au/stratego - email progcomp@ucc.asn.au or matches@ucc.asn.au - git git.ucc.asn.au/progcomp2012.git -''' - -import os -import sys - -baseDirectory = "/home/sam/Documents/progcomp2012/" -resultsDirectory = baseDirectory+"results/" #Where results will go (results are in the form of text files of agent names and scores) -agentsDirectory = baseDirectory+"samples/" #Where agents are found (each agent has its own directory) -logDirectory = baseDirectory+"log/" #Where log files go -nGames = 10 #Number of games played by each agent against each opponent. Half will be played as RED, half as BLUE -managerPath = baseDirectory+"manager/stratego" #Path to the manager program - - -scores = {"VICTORY":(3,1), "DEFEAT":(1,3), "SURRENDER":(0,3), "DRAW":(2,2), "DRAW_DEFAULT":(1,1), "ILLEGAL":(-1,2), "DEFAULT":(2,-1), "BOTH_ILLEGAL":(-1,-1), "INTERNAL_ERROR":(0,0)} #Score dictionary - -verbose = True - - -#Make necessary directories -if os.path.exists(resultsDirectory) == False: - os.mkdir(resultsDirectory) #Make the results directory if it didn't exist -#Identify the round number by reading the results directory -roundNumber = len(os.listdir(resultsDirectory)) + 1 -if roundNumber > 1: - roundNumber -= 1 - -if os.path.exists(logDirectory) == False: - os.mkdir(logDirectory) #Make the log directory if it didn't exist - - - -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 "Simulating ROUND " +str(roundNumber) -print "Identifying possible agents in \""+agentsDirectory+"\"" - -#Get all agent names from agentsDirectory -agentNames = os.listdir(agentsDirectory) -agents = [] -for name in agentNames: - #sys.stdout.write("\nLooking at Agent: \""+ str(name)+"\"... ") - 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 - - 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 verbose: - sys.stdout.write(" Valid!") - #sys.stdout.write("OK") - #Convert the array of names to an array of triples - #agents[0] - The name of the agent (its directory) - #agents[1] - The path to the program for the agent (typically agentsDirectory/agent/agent). Read from agentsDirectory/agent/info file - #agents[2] - The score the agent achieved in _this_ round. Begins at zero - agentExecutable = agentsDirectory+name+"/"+(open(agentsDirectory+name+"/info").readline().strip()) - agents.append([name, agentExecutable, 0]) - if verbose: - sys.stdout.write(" (Run program \""+agentExecutable+"\")\n") - -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... ("+str(nGames)+" games per pairing * " + str(len(agents) * len(agents)-1) + " pairings = " + str((len(agents) * len(agents)-1) * nGames) + " games)" - - -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. -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 - 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[0]+"\" and \""+blue[0]+"\" playing game " + str(i) + "/"+str(nGames/2) + "... ") - logFile = logDirectory + "round"+str(roundNumber) + "/"+red[0]+"_vs_"+blue[0]+"_"+str(i) - outline = os.popen(managerPath + " -o " + logFile + " " + red[1] + " " + blue[1], "r").read() - results = outline.split(' ') - - if len(results) != 6: - if verbose: - sys.stdout.write("Garbage output! " + outline) - else: - if results[1] == "RED": - red[2] += scores[results[2]][0] - blue[2] += scores[results[2]][1] - elif results[1] == "BLUE": - red[2] += scores[results[2]][1] - blue[2] += scores[results[2]][0] - elif results[1] == "BOTH": - red[2] += scores[results[2]][0] - blue[2] += scores[results[2]][1] - red[2] += scores[results[2]][1] - blue[2] += scores[results[2]][0] - - if verbose: - sys.stdout.write(" " + outline) - - - - - - -if verbose: - print "Completed combat. Total of " + str(normalGames + draws + aiErrors + managerErrors) + " games played. " -if managerErrors != 0: - print "WARNING: Recieved "+str(managerErrors)+" garbage outputs. 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) + "... ") - -agents.sort(key = lambda e : e[2], reverse=True) #Sort the agents based on score - -resultsFile = open(resultsDirectory+"round"+str(roundNumber)+".results", "w") #Create a file to store all the scores for this round -for agent in agents: - resultsFile.write(agent[0] + " " + str(agent[2]) +"\n") #Write the agent names and scores into the file, in descending order - -if verbose: - sys.stdout.write(" Complete!\n") - sys.stdout.write("Updating total scores... "); - -#Now update the total scores -if os.path.exists(resultsDirectory+"total.scores"): - if verbose: - sys.stdout.write(" Reading from \""+resultsDirectory+"total.scores\" to update scores... ") - totalFile = open(resultsDirectory+"total.scores", "r") #Try to open the total.scores file - for line in totalFile: #For all entries, - data = line.split(' ') - for agent in agents: - if agent[0] == data[0]: - agent.append(agent[2]) #Store the score achieved this round at the end of the list - agent[2] += int(data[1]) #Simply increment the current score by the recorded total score of the matching file entry - break - totalFile.close() #Close the file, so we can delete it - os.remove(resultsDirectory+"total.scores") #Delete the file - #Sort the agents again - agents.sort(key = lambda e : e[2], reverse=True) - -else: - if verbose: - sys.stdout.write(" First round - creating \""+resultsDirectory+"total.scores\"... ") -if verbose: - sys.stdout.write(" Complete!\n") - print "Finished writing results for ROUND " + str(roundNumber) - print "" - - -print "RESULTS FOR ROUND " + str(roundNumber) -print "Agent: [name, path, total_score, recent_score]" - -totalFile = open(resultsDirectory+"total.scores", "w") #Recreate the file -for agent in agents: - totalFile.write(agent[0] + " " + str(agent[2]) +"\n") #Write the total scores in descending order - print "Agent: " + str(agent) - - -#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. -