README 排名评定 游戏教程 安装使用教程 开发指南 Lua接口文档 Python接口文档 C/C++接口文档 地图编辑器说明 自动评测教程

自动评测教程

本教程介绍了如何使用autoMatch.py进行自动评测。协会也将使用此脚本进行评测。

使用说明

​ 本部分仅介绍如何自动评测,具体实现原理请看运行逻辑以及函数介绍

### 步骤一:

加入地图文件夹

​ 将下载的地图文件夹,如maps_2player/3player等拖进Commander根目录,如图所示:

​ 注:目前请不要使用自己编辑的地图。

### 步骤二:

#### 修改autoMatch.py

##### 1.matchNumber

`python class autoMatch(object): matchNumber = 5 `

​ 修改matchNumber可以改变对局次数,请不要超过100次.

​ ##### 2.AI

`python AI = ["Python", "Lua", "C++"] AIwinnings = [[], [], []] `

​ AI代表参与游戏的智能体列表,可以设置2~4个,上面的例子是设置了3个,此时会在地图中读取文件夹下的三个AI(Core.py,Core.lua,API.cpp)进行比赛。如果有相同的,如["Lua","Lua"],则两个AI逻辑相同。

​ AIwinnings为智能体获胜记录,数量应与上方的智能体数匹配。

##### 3.map

`python # 游戏使用的地图目录,地图中玩家数应与上方的智能体数匹配 mapDict = "maps_3player" mapName = "" `

​ mapDict为游戏使用的地图目录,地图中玩家数应与上方的智能体数匹配,若步骤一中拖入的是maps2player,则应修改为:mapDict = "maps2player"。mapName会自动匹配不必修改。自动评测时会从文件夹下的第一个地图开始依次使用地图来评测。

##### 4.saveDict

`python saveDict = "IGCA" saveName = "" `

​ saveDict存为存档文件夹名,可以自己取名。如例子中就会在Commander根目录下建立一个叫IGCA的文件夹,自动评测的结果(回放文件,胜负情况,胜率)会在其中生成。

​ saveName不必改动。

修改Client和Server中的main.lua

##### 1.dt

​ 在Client和Server文件夹下都有一个main.lua文件,其中函数love.update中都有一句注释:-- dt = dt * 10,这里可以修改时间倍率,这里建议取消注释后就使用10倍速,在笔记本电脑上较为流畅。

下面是实现原理,只是评测可以不用继续查看。

运行逻辑

` 循环对战的次数 定义服务端的启动选项,写入到ServerTask.txt 启动一个服务端的实例 循环AI数量-1次 定义客户端的启动选项,写入到ClientTask.txt 启动一个客户端的实例 等待直到ServerTask.txt被删除或到达超时时间 删除ClientTask.txt 读取存档文件中的steps.txt,获取胜利者 统计胜率,写入根目录下的matchResult.txt `

函数介绍

所有函数都属于autoMatch类。类变量定义见注释。被注释的mapDict是评测时使用的地图目录,此处注释换成default是为了更方便地查看脚本运行是否正常。同理,自动对战超时时间设为了20秒。

1. init

`Python def __init__(self): self.startTime = time.strftim("%Y-%m-%d_%H:%M:%S", time.localtime()) return ` 此函数在类实例化时被调用,获取时间作为评测的开始时间。

2. creatClientTask

`Python def creatClientTask(self, index):

fp = open("ClientTask.txt", 'w')

fp.write("[autoMatch]\n")
fp.write("true\n")  # 是否为自动对战任务
fp.write("[timeOut]\n")
fp.write(str(self.timeOut)+"\n")
fp.write("[mapDict]\n")
fp.write(self.mapDict+"\n")
fp.write("[mapName]\n")
fp.write(self.mapName+"\n")
fp.write("[AIlang]\n")
fp.write(self.AI[index]+"\n")
fp.close()
return

` 此函数以写入模式打开了ClientTask.txt(若不存在将被创建,若存在将被覆盖),然后按顺序写入启动选项。此函数有一个传入参数index,决定了将要使用哪一个AI。

3. creatServerTask

`Python def creatServerTask(self):

fp = open("ServerTask.txt", 'w')

fp.write("[autoMatch]\n")
fp.write("true\n")  # 是否为自动对战任务
fp.write("[timeOut]\n")
fp.write(str(self.timeOut)+"\n")
fp.write("[mapDict]\n")
fp.write(self.mapDict+"\n")
fp.write("[mapName]\n")
fp.write(self.mapName+"\n")
fp.write("[saveName]\n")
fp.write(self.saveName+"\n")
fp.write("[saveDict]\n")
fp.write(self.saveDict+"\n")
fp.close()
return

` 类似creatClientTask,不过没有传入参数。

4. startMatch

`Python def startMatch(self, index): #self.mapName = str(index)+".map" self.mapName = "default" self.saveName = "round"+str(index) self.creatServerTask() if self.runWithConsol == True: os.system('cd Server&start lovec .') else: os.system('cd Server&start love .') time.sleep(self.timeDelay) for i in range(len(self.AI)-1): self.creatClientTask(i+1) if self.runWithConsol == True: os.system("cd Client&start lovec .") else: os.system("cd Client&start love .") time.sleep(self.timeDelay) return ` 创建Task文件并启动程序以开始自动对战。被注释的行会按序号加载地图,改为默认地图是为了更方便地查看脚本运行是否正常。

5. waitUntilMatchOver

`Python def waitUntilMatchOver(self): roundStartTime = time.time() while True: if os.path.exists("ServerTask.txt"): if time.time()-roundStartTime > self.timeOut: os.remove("ServerTask.txt") break time.sleep(1) else: break os.remove("ClientTask.txt") time.sleep(self.timeDelay) return ` 如果ServerTask.txt中的[autoMatch]项为true,服务端将会在游戏结束后删除ServerTask.txt;脚本依此判断对战是否已经完成。对战也会因为超时而结束。结束后,脚本将删除ServerTask.txt和ClientTask.txt。

6. getMatchResult

`Python def getMatchResult(self, index): fp = open(self.saveDict+"/"+self.saveName+"/steps.txt", 'r') lines = fp.readlines() fp.close() if lines[-1][3] == 3 and lines[-1][6] == 3: self.AIwinnings[lines[-1][0]].append(index) return 此函数获取输入参数index,对战的局数,然后检查steps.txt的最后一行是否为获胜信息。如果某一方获胜了,最后一行应为armyID -3 -3 0 0 0`。查询到获胜信息后将对应的局数存入对应AI的胜场列表中。因超时而结束的对局不会产生胜者。

7. saveMatchResult

`Python def saveMatchResult(self): self.endTime = time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime()) fp = open("matchResult.txt", 'w') fp.write("match start: "+self.startTime+"\n") fp.write("match end: "+self.endTime+"\n") fp.write("total round: "+str(self.matchNumber)+"\n") fp.write("savedata: "+self.saveDict+"\n\n\n") for i in range(len(self.AI)-1): fp.write("armyID: "+str(i+1)+"\n") fp.write("AI: "+self.AI[i+1]+"\n") fp.write("winning: "+str(self.AIwinnings[i+1])+"\n") fp.write("winning rate: " + str(len(self。AIwinnings[i+1])/self.matchNumber)+"\n\n") fp.close() return ` 此函数在所有对局结束后被调用,它将此次评测的统计信息、每个AI的胜场和胜率写入根目录下的matchResult.txt。

8. match

`Python def match(self): for i in range(self.matchNumber): self.startMatch(i) self.waitUntilMatchOver() self.getMatchResult(i) self.saveMatchResult() return ` 此函数进行自动评测。运行时,脚本将先创建autoMatch类的实例am,然后调用am的match成员函数。