first commit

This commit is contained in:
marcinljablonski 2019-05-06 12:51:41 +02:00
commit f868b53e7e
7 changed files with 425 additions and 0 deletions

55
Cucumber.py Normal file
View File

@ -0,0 +1,55 @@
from Plant import Plant
class Cucumber(Plant):
def __init__(self):
self.__is_alive = True
self.__ttl = 40
self.__hydration = 40
self.__soil_level = 40
self.__dehydration_ratio = 0.8
self.__desoil_ratio = 0.7
self.__max_soil_lvl = 40
self.__max_hydration_lvl = 40
self.__ready = 11
def get_symbol(self):
if not self.__is_alive:
return ('x', None)
elif self.__hydration > (self.__max_hydration_lvl / 2) \
and self.__soil_level > (self.__max_soil_lvl / 2):
return ('o', "green") if (self.__ttl > self.__ready) \
else ('O', "green")
else:
return ('o', "yellow") if (self.__ttl > self.__ready) \
else ('O', "yellow")
def tick(self, n):
self.decrease_ttl(n)
self.decrase_hydration(n)
self.decrease_soillevel(n)
def decrease_ttl(self, n):
self.__ttl -= n
if self.__ttl == 0:
self.__is_alive == False
def increase_hydration(self, n):
self.__hydration += n
if self.__hydration > 40:
self.__is_alive = False
def decrase_hydration(self, n):
self.__hydration -= n * self.__dehydration_ratio
if self.__hydration < 1:
self.__is_alive = False
def increase_soillevel(self, n):
self.__soil_level += n
if self.__soil_level > 40:
self.__is_alive = False
def decrease_soillevel(self, n):
self.__soil_level -= n * self.__desoil_ratio
if self.__soil_level < 1:
self.__is_alive = False

11
Plant.py Normal file
View File

@ -0,0 +1,11 @@
class Plant():
def get_symbol(self):
raise NotImplementedError("Please Implement this method")
def tick(self, n):
raise NotImplementedError("Please Implement this method")
def get_stats(self):
#np. touple'a z info czy żyje, ile ma wody i nawozu
raise NotImplementedError("Please Implement this method")

17
Point.py Normal file
View File

@ -0,0 +1,17 @@
class Point:
def __init__(self, cord):
self.x = cord[0]
self.y = cord[1]
def get_cord(self):
return (self.x, self.y)
def get_x(self):
return self.x
def get_y(self):
return self.y
def set_cord(self, cord):
self.x = cord[0]
self.y = cord[1]

55
Tomato.py Normal file
View File

@ -0,0 +1,55 @@
from Plant import Plant
class Tomato(Plant):
def __init__(self):
self.__is_alive = True
self.__ttl = 38
self.__hydration = 41
self.__soil_level = 41
self.__dehydration_ratio = 0.7
self.__desoil_ratio = 0.8
self.__max_soil_lvl = 40
self.__max_hydration_lvl = 40
self.__ready = 10
def get_symbol(self):
if not self.__is_alive:
return ('x', None)
elif self.__hydration > (self.__max_hydration_lvl / 2) \
and self.__soil_level > (self.__max_soil_lvl / 2):
return ('p', "green") if (self.__ttl > self.__ready) \
else ('P', "green")
else:
return ('p', "yellow") if (self.__ttl > self.__ready) \
else ('P', "yellow")
def tick(self, n):
self.decrease_ttl(n)
self.decrase_hydration(n)
self.decrease_soillevel(n)
def decrease_ttl(self, n):
self.__ttl -= n
if self.__ttl == 0:
self.__is_alive == False
def increase_hydration(self, n):
self.__hydration += n
if self.__hydration > 40:
self.__is_alive = False
def decrase_hydration(self, n):
self.__hydration -= n * self.__dehydration_ratio
if self.__hydration < 1:
self.__is_alive = False
def increase_soillevel(self, n):
self.__soil_level += n
if self.__soil_level > 40:
self.__is_alive = False
def decrease_soillevel(self, n):
self.__soil_level -= n * self.__desoil_ratio
if self.__soil_level < 1:
self.__is_alive = False

41
Trac.py Normal file
View File

@ -0,0 +1,41 @@
from Point import Point
class Trac:
def __init__(self, rotation, position):
self.__position = Point(position.get_cord())
self.__rotation = rotation
def get_symbol(self):
if self.__rotation == 'S':
return 'v'
elif self.__rotation == 'N':
return '^'
elif self.__rotation == 'E':
return '>'
else:
return '<'
def set_rotation(self, rotation):
self.__rotation = rotation
def set_position(self, position):
self.__position.set_cord(position)
def get_position(self):
return self.__position
def get_rotation(self):
return self.__rotation
def move(self):
x = self.get_position().get_x()
y = self.get_position().get_y()
if self.__rotation == 'N':
self.set_position((x - 1 ,y))
elif self.__rotation == 'S':
self.set_position((x + 1 ,y))
elif self.__rotation == 'W':
self.set_position((x, y - 1))
else:
self.set_position((x, y + 1))

134
env.py Normal file
View File

@ -0,0 +1,134 @@
import string
import sys
import os
import time
import asyncio
from Tomato import Tomato
from Cucumber import Cucumber
from Plant import Plant
from Point import Point
from Trac import Trac
string.ascii_letters = 'oOpPx'
string.ascii_numbers = '01'
OKGREEN = '\033[92m'
OKBLUE = '\033[94m'
OKRED = '\033[91m'
ENDC = '\033[0m'
def initialize_field():
field = []
for i in range(11):
row = []
for j in range(7):
if i == 0 or i == 10 or j == 0 \
or j == 3 or j == 6:
row.append(None)
elif j < 3:
row.append(Cucumber())
else:
row.append(Tomato())
field.append(row)
return field
def print_field(field, tractor):
if sys.platform == "win32":
os.system("cls")
else:
os.system("clear")
sys.stdout.write(OKBLUE)
sys.stdout.write("$")
sys.stdout.write(" ")
sys.stdout.write("\n")
for x, row in enumerate(field):
for y, i in enumerate(row):
if not i:
if tractor.get_position().get_x() == x \
and tractor.get_position().get_y() == y:
sys.stdout.write(OKBLUE)
sys.stdout.write(tractor.get_symbol())
sys.stdout.write(" ")
else:
sys.stdout.write(" ")
else:
symbol = i.get_symbol()
if symbol[1] == "green":
sys.stdout.write(OKGREEN)
sys.stdout.write(symbol[0])
sys.stdout.write(" ")
else:
sys.stdout.write(OKRED)
sys.stdout.write(symbol[0])
sys.stdout.write(" ")
sys.stdout.write("\n")
def update_state(field):
for row in field:
for i in row:
if i:
i.tick(1)
def try_move(field, tractor):
x = tractor.get_position().get_x()
y = tractor.get_position().get_y()
rotation = tractor.get_rotation()
if rotation == 'N':
x -= 1
elif rotation == 'S':
x += 1
elif rotation == 'W':
y -= 1
else:
y += 1
if x >= 0 and x < len(field) \
and y >= 0 and y < len(field[0]) \
and not field[x][y]:
print(str(x) + " " + str(y))
return True
return False
if __name__ == "__main__":
field = initialize_field()
tractor = Trac('N', Point((0,0)))
async def handle_echo(reader, writer):
data = await reader.readline()
message = data.decode().split()
if message[0] == "rotate":
tractor.set_rotation(message[1])
writer.write("OK\n".encode())
elif message[0] == "try":
if try_move(field, tractor):
writer.write("OK\n".encode())
else:
writer.write("FAIL\n".encode())
else:
tractor.move()
writer.write(("OK\n").encode())
# print_field(field, tractor)
# print(tractor.get_position().get_x())
# print(tractor.get_position().get_y())
# print(tractor.get_rotation())
update_state(field)
await writer.drain()
writer.close()
async def main():
server = await asyncio.start_server(
handle_echo, '127.0.0.1', 8888)
addr = server.sockets[0].getsockname()
async with server:
await server.serve_forever()
asyncio.run(main())

112
tractor.py Normal file
View File

@ -0,0 +1,112 @@
import asyncio
import sys
import time
from queue import PriorityQueue
def heuristic(a, b):
(x1, y1) = a
(x2, y2) = b
return abs(x1 - x2) + abs(y1 - y2)
def addnode(current, direction):
if direction == 'N':
return (current[0] - 1, current[1])
elif direction == 'S':
return (current[0] + 1, current[1])
elif direction == 'W':
return (current[0], current[1] - 1)
else:
return (current[0], current[1] + 1)
def getrotation(a, b):
y = b[0] - a[0]
x = b[1] - a[1]
if y > 0:
return 'S'
elif y < 0:
return 'N'
elif x > 0:
return 'E'
else:
return 'W'
async def move_tractor(start_position, goal):
directions = ['N', 'W', 'S', 'E']
current_rotation = 'N'
last_node = None
current_position = start_position
frontier = PriorityQueue()
frontier.put(start, 0)
cost_so_far = {}
cost_so_far[start] = 0
start_flag = True
while not frontier.empty():
local_graph = []
for direction in directions:
if direction == last_node:
continue
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
writer.write(("rotate " + direction + "\n").encode())
await reader.readline()
time.sleep(0.7)
writer.close()
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
writer.write("try\n".encode())
data = await reader.readline()
result = data.decode()
time.sleep(0.7)
writer.close()
if result == "OK\n":
print("~~~~~~~~~~")
print(current_position)
print(direction)
print("~~~~~~~~~~")
local_graph.append(addnode(current_position, direction))
current_rotation = directions[(directions.index(current_rotation) - 1) % 4]
current = frontier.get()
if not start_flag:
rotation = getrotation(current_position, current)
if rotation != current_rotation:
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
writer.write(("rotate " + rotation + "\n").encode())
await reader.readline()
current_rotation = rotation
time.sleep(0.7)
writer.close()
last_node = directions[(directions.index(rotation) - 2) % 4]
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
writer.write("move\n".encode())
await reader.readline()
time.sleep(0.7)
writer.close()
current_position = current
if current == goal:
break
for next in local_graph:
new_cost = cost_so_far[current] + 1
if next not in cost_so_far or new_cost < cost_so_far[next]:
cost_so_far[next] = new_cost
priority = new_cost + heuristic(goal, next)
frontier.put(next, priority)
start_flag = False
writer.close()
if __name__ == "__main__":
start = (0,0)
goal = (10,6)
asyncio.run(move_tractor(start, goal))