-
-
Save pajadam/c172b8b377da9b696549763cc635cf8d to your computer and use it in GitHub Desktop.
Misja 008 - Gynvael Coldwind
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
import math | |
import time | |
import requests | |
from PIL import Image | |
from itertools import product | |
""" | |
Code quality may be... | |
""" | |
class Parser(): | |
def __init__(self, content): | |
content = content.split('\n') | |
self.posX = [int(s) for s in content[1].split() if s.isdigit()][0] | |
self.posY = [int(s) for s in content[1].split() if s.isdigit()][1] | |
self.data = [] | |
for idx in range(2, 38): | |
if isinstance(content[idx], str) and content[idx] == "inf": | |
content[idx] = "70.0000" | |
self.data += re.findall(r"[-+]?\d*\.\d+|\d+", content[idx]) | |
self.destination = [] | |
# East | |
self.destination += [content[38].split(' ')[1]] | |
# South | |
self.destination += [content[40].split(' ')[1]] | |
# West | |
self.destination += [content[39].split(' ')[1]] | |
# North | |
self.destination += [content[41].split(' ')[1]] | |
class Cache(): | |
def get(self, key): | |
""" Get cached location """ | |
if key in [f for f in os.listdir("data/")]: | |
file = open("data/" + key, "r") | |
data = file.read() | |
file.close() | |
return data | |
else: | |
return None | |
def store(self, key, content): | |
""" Store location in cache """ | |
file = open("data/" + key, "w") | |
file.write(content) | |
file.close() | |
CACHE = Cache() | |
class Location(): | |
global CACHE | |
def __init__(self): | |
self.radius = 6.6321243524 | |
self.last = None | |
def get(self, key): | |
if key == "not": | |
return None | |
requested_data = CACHE.get(key) | |
# Cache miss | |
if requested_data is None: | |
#print("Cache miss:", key) | |
while True: | |
try: | |
r = requests.get("http://gynvael.coldwind.pl/misja008_drone_io/scans/" + key) | |
break | |
except Exception as e: | |
print("Network error:", e) | |
if r.status_code != 200: | |
print("Error connecting to the server:", r.status_code) | |
return None | |
CACHE.store(key, r.content.decode("utf-8")) | |
self.last = Parser(r.content.decode("utf-8")) | |
return self.last | |
else: | |
#print("Used cache for:", key) | |
self.last = Parser(requested_data) | |
return self.last | |
def get_rays_pixels(self): | |
pixels = [] | |
for idx, value in enumerate(self.last.data): | |
if value != 0 and float(value) < 64: | |
a = (idx * 10) * math.pi / 180 | |
pX = self.last.posX + math.sin(a) * float(value) | |
pY = self.last.posY - math.cos(a) * float(value) | |
pixels += [(int(pX), int(pY))] | |
return pixels | |
LOCATION = Location() | |
class Renderer(): | |
global LOCATION | |
def __init__(self): | |
self.width = 1200 | |
self.height = 1000 | |
self.center = 50 | |
self.color_inc = 1 | |
self.timestamp = time.strftime("%Y%m%d-%H%M%S") | |
self.location_image = Image.new('RGB', (self.width, self.height)) | |
self.counter = 0 | |
def save(self): | |
self.location_image.save('img/' + self.timestamp + '_location_' + str(self.counter) + '.png') | |
self.counter += 1 | |
def render_location(self): | |
for idx in LOCATION.get_rays_pixels(): | |
pix = self.location_image.getpixel(( | |
idx[0] + self.center, idx[1] + self.center | |
)) | |
self.location_image.putpixel( | |
(idx[0] + self.center, idx[1] + self.center), | |
(pix[0], pix[1] + self.color_inc, pix[2] + self.color_inc) | |
) | |
RENDERER = Renderer() | |
class Finder(): | |
global RENDERER | |
def __init__(self, key, swap_finding=False, direction=0): | |
self.follow_wall = False | |
self.direction = direction | |
self.location = LOCATION.get(key) | |
self.angular = 0 | |
self.swap_finding = swap_finding | |
self.LOOP_COUNTER = 0 | |
def move(self, direction): | |
loc = LOCATION.get(self.location.destination[direction]) | |
if loc is None: | |
return False | |
self.location = loc | |
RENDERER.render_location() | |
return True | |
def turn_left(self): | |
self.direction = self.next_left() | |
self.angular -= 1 | |
def turn_right(self): | |
self.direction = self.next_right() | |
self.angular += 1 | |
def next_left(self): | |
if self.direction > 0: | |
return self.direction - 1 | |
else: | |
return 3 | |
def next_right(self): | |
if self.direction < 3: | |
return self.direction + 1 | |
else: | |
return 0 | |
def simple_ray(self): | |
loc = self.location | |
direction = self.next_right() | |
idx = 0 | |
while idx < 5: | |
if self.LOOP_COUNTER % 10 != 0: | |
idx += 1 | |
loc = LOCATION.get(loc.destination[direction]) | |
if loc is None: | |
break | |
RENDERER.render_location() | |
loc = self.location | |
direction = self.next_left() | |
idx = 0 | |
while idx < 5: | |
if self.LOOP_COUNTER % 10 != 0: | |
idx += 1 | |
loc = LOCATION.get(loc.destination[direction]) | |
if loc is None: | |
break | |
RENDERER.render_location() | |
def search(self): | |
self.LOOP_COUNTER += 1 | |
if self.LOOP_COUNTER >= 100000: | |
return True | |
if self.LOOP_COUNTER % 10 == 0: | |
self.simple_ray() | |
if self.follow_wall and self.angular == 0: | |
self.follow_wall = False | |
if not self.follow_wall: | |
if not self.move(self.direction): | |
self.follow_wall = True | |
if self.swap_finding: | |
self.turn_right() | |
else: | |
self.turn_left() | |
else: | |
if self.swap_finding: | |
left = self.next_left() | |
else: | |
left = self.next_right() | |
if self.move(left): | |
if self.swap_finding: | |
self.turn_left() | |
else: | |
self.turn_right() | |
else: | |
loop = 0 | |
while loop != 3: | |
if not self.move(self.direction): | |
if self.swap_finding: | |
self.turn_right() | |
else: | |
self.turn_left() | |
else: | |
break | |
loop += 1 | |
if loop == 3: | |
raise Exception("Infinite loop !") | |
return None | |
def main(): | |
# Top Left | |
finder_1 = Finder("955ab37b312b7191c7797d55edb914a5.txt", False, 0) | |
finder_2 = Finder("955ab37b312b7191c7797d55edb914a5.txt", True, 0) | |
# Drone Room | |
finder_3 = Finder("e1ab3075efbc0182fdedd3036a00285d.txt", False, 1) | |
finder_4 = Finder("e1ab3075efbc0182fdedd3036a00285d.txt", True, 1) | |
try: | |
while True: | |
if finder_1.search() or finder_2.search() or finder_3.search() or finder_4.search(): | |
break | |
if finder_1.LOOP_COUNTER % 50 == 0: | |
RENDERER.save() | |
except Exception as e: | |
print("Something went wrong :/\n", e) | |
RENDERER.save() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment