Skip to content

Instantly share code, notes, and snippets.

@pajadam

pajadam/main.py Secret

Created July 17, 2017 17:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pajadam/c172b8b377da9b696549763cc635cf8d to your computer and use it in GitHub Desktop.
Save pajadam/c172b8b377da9b696549763cc635cf8d to your computer and use it in GitHub Desktop.
Misja 008 - Gynvael Coldwind
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