109 lines
3.8 KiB
Python
109 lines
3.8 KiB
Python
import numpy as np
|
|
|
|
|
|
# TODO: if set to competition mode, get the seed from the api
|
|
|
|
def set_random_seed(seed: int):
|
|
np.random.seed(seed)
|
|
|
|
|
|
def get_random_number(min: int, max: int):
|
|
return np.random.randint(256 ** 4, dtype='<u4', size=1)[0] % (max - min + 1) + min
|
|
|
|
|
|
class Gamestate:
|
|
def __str__(self) -> str:
|
|
return f"""Seed: {self.seed}
|
|
Heu Color: {self.heu_color}
|
|
Material Pairs: {self.material_pairs}
|
|
Material Zones: {self.materials}
|
|
Logistic Plan: {self.logistic_plan}
|
|
Logistic Centers: {self.logistic_center}"""
|
|
|
|
def __init__(self, seed: int):
|
|
"""
|
|
Erstellt den Seeding "Gamestate" für den angegebenen Seed.
|
|
|
|
:param seed: Seed welcher zum Erstellen des Gamestates benutzt werden soll.
|
|
"""
|
|
self.seed = seed
|
|
set_random_seed(seed)
|
|
|
|
self.heu_color = get_random_number(1, 2)
|
|
|
|
self.materials = [0, 0, 0, 0]
|
|
self.material_pairs = []
|
|
for i in range(0, 4):
|
|
num1 = get_random_number(0, 3)
|
|
self.material_pairs.append([num1, num1])
|
|
while self.material_pairs[i][1] == num1:
|
|
self.material_pairs[i][1] = get_random_number(0, 3)
|
|
|
|
flat = [item for sublist in self.material_pairs for item in sublist]
|
|
for i in range(0, 4):
|
|
self.materials[i] = flat.count(i)
|
|
|
|
self.logistic_plan = [0 for i in range(0, 21)]
|
|
self.logistic_center = [[0, 0, 0, 0] for i in range(0, 4)]
|
|
visited = [5, 5, 5, 5]
|
|
|
|
def __logistic_plan_generator(i: int):
|
|
drive_to = get_random_number(0, 3)
|
|
for j in range(0, 4):
|
|
drive_to = (drive_to + j) % 4
|
|
if visited[drive_to] <= 0 or drive_to == self.logistic_plan[i - 1]:
|
|
continue
|
|
self.logistic_plan[i] = drive_to
|
|
|
|
visited[drive_to] -= 1
|
|
finished = True
|
|
for k in visited:
|
|
if k != 0:
|
|
finished = False
|
|
|
|
if finished and drive_to == 2:
|
|
visited[drive_to] += 1
|
|
continue
|
|
|
|
if finished:
|
|
return True
|
|
|
|
if i < len(self.logistic_plan):
|
|
if __logistic_plan_generator(i + 1):
|
|
return True
|
|
visited[drive_to] += 1
|
|
return False
|
|
|
|
self.logistic_plan[0] = 2
|
|
visited[2] -= 1
|
|
_ = __logistic_plan_generator(1)
|
|
|
|
self.logistic_plan[-1] = 2
|
|
for i in range(0, len(self.logistic_plan) - 1):
|
|
self.logistic_center[self.logistic_plan[i]][self.logistic_plan[i + 1]] += 1
|
|
|
|
self.logistic_plan = [x + 10 for x in self.logistic_plan]
|
|
|
|
def get_heuballen(self) -> int:
|
|
"""
|
|
Die Funktion gibt entweder die Zahl "1" oder "2" zurück. Wenn die Funktion "1" zurückgibt, dann liegen die Heuballen auf den gelben Linien. Wenn die Funktion "2" zurückgibt, dann liegen sie auf den blauen Flächen.
|
|
|
|
:return: Gibt entweder die Zahl 1 oder 2 zurück.
|
|
"""
|
|
return self.heu_color
|
|
|
|
def get_logistic_plan(self) -> []:
|
|
"""
|
|
Die Funktion gibt den "Logistik Plan" zurück. Also die Reihenfolge, in welcher der Roboter die Logistik Zonen Abfahren muss, um die Pakete welche dort liegen zu sortieren.
|
|
|
|
:return: Eine Liste an Zahlen zwischen 10 und 13.
|
|
"""
|
|
return self.logistic_plan
|
|
|
|
def get_material_deliveries(self) -> [[]]:
|
|
"""
|
|
Die Funktion gibt die einzelnen "Material Lieferungen" zurück. Da der Roboter immer zwei Paare an Materialien anliefern muss, gibt die Funktion eine Liste an Material Paaren zurück. Die Materialien werden dabei durch ihre Zonen-ID representiert. Also Holz ist z.B. "0" und die Ziegelsteine sind "3".
|
|
|
|
:return: Eine Liste and Material Paaren.
|
|
"""
|
|
return self.material_pairs
|