210 lines
6.9 KiB
Python
210 lines
6.9 KiB
Python
from icfprequests import LibRequests
|
|
import json
|
|
import os.path
|
|
import sys
|
|
import random
|
|
|
|
class ExploreError(Exception):
|
|
pass
|
|
|
|
class LibraryMap:
|
|
|
|
def __init__(self, problemName:str, no_of_rooms:int, startRoom):
|
|
self.no_of_rooms = no_of_rooms
|
|
self.problemName = problemName
|
|
self.rooms = [ startRoom ]
|
|
self.startRoom = startRoom
|
|
self.candidateRooms = []
|
|
|
|
def addRoom(self,room):
|
|
if len(self.rooms)<self.no_of_rooms:
|
|
self.rooms.append(room)
|
|
|
|
|
|
class Room:
|
|
|
|
def __init__(self, room_id, isStart=False):
|
|
self.isStart = isStart
|
|
self.id = room_id
|
|
self.reachedby_id = None
|
|
self.doors = [None for _ in range(6)]
|
|
|
|
def completed(self):
|
|
for door in self.doors:
|
|
if door is None:
|
|
return False
|
|
if self.id is None:
|
|
return False
|
|
return True
|
|
|
|
def setRoomForDoor(self,door:int,room):
|
|
self.doors[door]=room
|
|
|
|
def createRoomForDoor(self,door, id):
|
|
self.doors[door]=Room(id)
|
|
|
|
class RoomPath:
|
|
|
|
def __init__(self, from_id, from_door, room_id, to_door, to_id ):
|
|
self.from_id = from_id
|
|
self.from_door = from_door
|
|
self.room_id = room_id
|
|
self.to_door = to_door
|
|
self.to_id = to_id
|
|
|
|
def getFromId(self):
|
|
return self.from_id + str(self.from_door) + self.room_id
|
|
|
|
def getToId(self):
|
|
return self.room_id + str(self.to_door)+ self.to_id
|
|
|
|
def getFullId(self):
|
|
return str(self.from_id) + str(self.from_door) + str(self.room_id) + str(self.to_door)+ str(self.to_id)
|
|
|
|
def __str__(self):
|
|
return self.getFullId()
|
|
|
|
def __repr__(self):
|
|
return self.getFullId()
|
|
|
|
|
|
class LibMapper:
|
|
|
|
def __init__(self, problemName:str, no_of_rooms:int, processmode:str):
|
|
self.no_of_rooms = no_of_rooms
|
|
self.problemName = problemName
|
|
self.processmode = processmode
|
|
self.requester = LibRequests()
|
|
self.libmap = None
|
|
|
|
def start(self):
|
|
response = self.requester.select(self.problemName)
|
|
if self.problemName != response:
|
|
print("Select Request failed")
|
|
else:
|
|
self.explore_map()
|
|
self.submit_guess()
|
|
|
|
def createRandomPlan(self,direction):
|
|
plan = str(direction)
|
|
# planzero = str(direction)+"[0]"
|
|
for x in range(6*self.no_of_rooms-1):
|
|
randdir = str(random.randint(0,5))
|
|
plan += randdir
|
|
return plan
|
|
|
|
def createAllDoorPlan(self):
|
|
return "024135" * self.no_of_rooms
|
|
|
|
def createZeroedPlan(self, plan):
|
|
zeroed_plan = ""
|
|
for direction in plan:
|
|
zeroed_plan += direction + "[0]"
|
|
return zeroed_plan
|
|
|
|
def createinvertedPlans(self, plan_base, result_base):
|
|
print(str(len(plan_base))+ " : "+str(len(result_base)))
|
|
if len(plan_base) == len(result_base):
|
|
inverted_plans = []
|
|
for i in range(len(plan_base)):
|
|
iplan = "[" + str(result_base[i][0]^3) + "]"
|
|
for j in range(len(plan_base[i])):
|
|
iplan += plan_base[i][j] + "[" + str(result_base[i][j+1]^3) + "]"
|
|
inverted_plans.append(iplan)
|
|
return inverted_plans
|
|
else:
|
|
print("Incompatible Input Array Dimensions")
|
|
|
|
def acquireExploreData(self):
|
|
# acquire data
|
|
print("Acquire")
|
|
startdirections = [random.randint(0, 5)]
|
|
plan_base = [self.createAllDoorPlan()]
|
|
# [self.createRandomPlan(direction) for direction in startdirections]
|
|
# plan_zero_base = [self.createZeroedPlan(plan) for plan in plan_base]
|
|
plans = plan_base # + plan_zero_base
|
|
print("Plans: " + str(plans))
|
|
result = self.requester.explore(plans)
|
|
print(result)
|
|
result_base = result["results"][0:1]
|
|
#startRoomId = result_base[0][0]
|
|
print(result_base)
|
|
# create inverted plan (every id will be xored with 3 and set as current Room Id)
|
|
plan_inverted_base = self.createinvertedPlans(plan_base, result_base)
|
|
print(plan_inverted_base)
|
|
result_inverted = self.requester.explore(plan_inverted_base)
|
|
print(result_inverted)
|
|
result_inverted_base = result_inverted["results"][0:1]
|
|
print(result_inverted_base)
|
|
return result_base[0], result_inverted_base[0], plan_inverted_base[0]
|
|
|
|
def explore_map(self):
|
|
result_base, result_inverted_base = [] , []
|
|
plan_inverted_base = ""
|
|
if self.processmode != "cache":
|
|
result_base, result_inverted_base, plan_inverted_base = self.acquireExploreData()
|
|
if self.processmode == "store":
|
|
self.storeResult(result_base, result_inverted_base, plan_inverted_base)
|
|
if self.processmode == "cache":
|
|
print("loading Data ...")
|
|
result_base, result_inverted_base , plan_inverted_base= self.loadResults()
|
|
print(result_base)
|
|
print(result_inverted_base)
|
|
print(plan_inverted_base)
|
|
# calculate map
|
|
print("Caluclate")
|
|
print("-- Preperations")
|
|
plan_base, inversions = self.splitInvertedPlan(plan_inverted_base)
|
|
print(plan_base)
|
|
print(inversions)
|
|
room_pathes_base = self.createBaseRoomPathes(result_base,plan_base)
|
|
print(room_pathes_base)
|
|
#room_pathes_inverted = self.createRoomPathes(result_inverted_base, plan_base)
|
|
#print(room_pathes_inverted)
|
|
|
|
def createBaseRoomPathes(self, result, plan):
|
|
spliced = str(result[0])
|
|
roompathes =[]
|
|
for i in range(0, len(plan)):
|
|
spliced += plan[i] + str(result[i+1])
|
|
print(spliced + " : " + str(len(spliced)))
|
|
for i in range(0,len(spliced)-4,2):
|
|
roompathes.append(RoomPath(spliced[i],spliced[i+1],spliced[i+2],spliced[i+3],spliced[i+4]))
|
|
return roompathes
|
|
|
|
|
|
def splitInvertedPlan(self, plan_inverted_base):
|
|
return plan_inverted_base[3::4], plan_inverted_base[1::4]
|
|
|
|
def submit_guess(self):
|
|
pass
|
|
|
|
def storeResult(self, result_base, result_inverted_base,plan_inverted_base):
|
|
dump = [ result_base , result_inverted_base , plan_inverted_base ]
|
|
with open("result_dump.json", "w") as h:
|
|
h.write(json.dumps(dump))
|
|
|
|
def loadResults(self):
|
|
dump = {}
|
|
try:
|
|
with open("result_dump.json") as h:
|
|
dump = json.loads(h.read())
|
|
except OSError:
|
|
pass
|
|
return dump[0], dump[1], dump[2]
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
problem = sys.argv[1]
|
|
processmode = sys.argv[2] # normal (webcall), store (Store Callresult), cache (skip Webcall and load stored data)
|
|
|
|
with open(os.path.join("..", "problems.json")) as h:
|
|
problems = json.loads(h.read())
|
|
|
|
problems = {p["problem"]: {"size": p["size"]} for p in problems}
|
|
|
|
if problem not in problems:
|
|
raise ExploreError(f"unknown problem {problem}")
|
|
mapper = LibMapper(problem,problems[problem]["size"], processmode)
|
|
mapper.start() |