This repository has been archived on 2025-06-01. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
compLIB/compLib/Seeding.py
Konstantin Lampalzer c02cfcd71c Move client foler
2022-12-17 23:59:06 +01:00

124 lines
4.4 KiB
Python

import logging
import os
import numpy as np
# TODO: if set to competition mode, get the seed from the api
FORCE_SEED = int(os.getenv("FORCE_SEED", "-1"))
logger = logging.getLogger("complib-logger")
class Gamestate:
@staticmethod
def __set_random_seed(seed: int):
logger.debug(f"Seeding seed to: {seed}")
np.random.seed(seed)
@staticmethod
def __get_random_number(min: int, max: int):
return np.random.randint(256 ** 4, dtype='<u4', size=1)[0] % (max - min + 1) + min
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.
"""
if FORCE_SEED == -1:
self.seed = seed
else:
print(f"Wettkampfmodus, zufälliger Seed wird verwendet: Seed={FORCE_SEED}")
self.seed = FORCE_SEED
logger.debug(f"Creating gamestate with seed: {self.seed}")
self.__set_random_seed(self.seed)
self.heu_color = self.__get_random_number(1, 2)
self.materials = [0, 0, 0, 0]
self.material_pairs = []
for i in range(0, 4):
num1 = self.__get_random_number(0, 3)
self.material_pairs.append([num1, num1])
while self.material_pairs[i][1] == num1:
self.material_pairs[i][1] = self.__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 = self.__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]
logger.debug(f"Created gamesate: {str(self)}")
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