Compare commits
10
Commits
4ddc2b83ab
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
777fd3669b | ||
|
|
aafa607a93 | ||
|
|
b9dafcf241 | ||
|
|
bc8c3a90d5 | ||
|
|
91658b26df | ||
|
|
119371f0d2 | ||
|
|
1da60b893a | ||
|
|
cfeaf81bda | ||
|
|
36316a01d7 | ||
|
|
0f842bb938 |
+2
-1
@@ -1,4 +1,5 @@
|
||||
/.idea
|
||||
/.venv
|
||||
/Graphs
|
||||
/__pycache__
|
||||
/__pycache__
|
||||
/other
|
||||
+280000
File diff suppressed because it is too large
Load Diff
@@ -1,301 +1,272 @@
|
||||
import pygame as pg
|
||||
#import time
|
||||
MAP_SIZE = 9
|
||||
start = (0, 0)
|
||||
neo = start
|
||||
keymaker = ()
|
||||
|
||||
class Cell:
|
||||
coordinates = (0, 0)
|
||||
position = (0, 0)
|
||||
size = 50
|
||||
perceptor = None
|
||||
content = None
|
||||
rect = pg.Rect(0, 0, size, size)
|
||||
border_width = 2
|
||||
closed = False
|
||||
g = 1
|
||||
h = 2
|
||||
f = g + h
|
||||
def __init__(self, position):
|
||||
self.set_position(position)
|
||||
self.rect = pg.Rect(self.coordinates[0], self.coordinates[1],
|
||||
self.size - self.border_width, self.size - self.border_width)
|
||||
def set_position(self, position):
|
||||
self.position = position
|
||||
self.coordinates = (self.position[0] * self.size,
|
||||
self.position[1] * self.size)
|
||||
def set_content(self, content):
|
||||
self.content = content
|
||||
self.content
|
||||
def set_perceptor(self, perceptor):
|
||||
self.perceptor = perceptor
|
||||
def clear_perceptor(self):
|
||||
self.perceptor = None
|
||||
def draw(self):
|
||||
pg.draw.rect(screen, "white", self.rect)
|
||||
|
||||
if self.perceptor == None:
|
||||
pg.draw.rect(screen, "white", self.rect)
|
||||
else:
|
||||
pg.draw.rect(screen, self.perceptor.color, self.rect)
|
||||
|
||||
g_font = pg.font.Font(None, 14)
|
||||
text = g_font.render((str)(self.g), True, "black")
|
||||
screen.blit(text, ((self.coordinates[0] + self.size * 0.05, self.coordinates[1] + self.size * 0.75)))
|
||||
|
||||
h_font = pg.font.Font(None, 14)
|
||||
text = h_font.render((str)(self.h), True, "black")
|
||||
screen.blit(text, ((self.coordinates[0] + self.size * 0.8, self.coordinates[1] + self.size * 0.75)))
|
||||
|
||||
f_font = pg.font.Font(None, 16)
|
||||
text = f_font.render((str)(self.f), True, "maroon")
|
||||
screen.blit(text, ((self.coordinates[0] + self.size * 0.425, self.coordinates[1] + self.size * 0.7)))
|
||||
|
||||
def calculate_cost(self):
|
||||
self.g = abs(self.position[0] - neo.position[0]) + abs(self.position[1] - neo.position[1])
|
||||
def calculate_heuristic(self):
|
||||
self.h = abs(self.position[0] - keymaker.position[0]) + abs(self.position[1] - keymaker.position[1])
|
||||
def calculate_estimated(self):
|
||||
self.f = self.g + self.h
|
||||
open_set = []
|
||||
closed_set = []
|
||||
blocked_set = []
|
||||
|
||||
class Map:
|
||||
cell_matrix = []
|
||||
dimensions = (8, 8)
|
||||
def __init__(self, dimensions:tuple):
|
||||
self.dimensions = dimensions
|
||||
for x in range(dimensions[0]):
|
||||
column = []
|
||||
for y in range(dimensions[1]):
|
||||
column.append(Cell((x,y)))
|
||||
self.cell_matrix.append(column)
|
||||
def get_cell(self, x, y):
|
||||
if (x < self.dimensions[0] and y < self.dimensions[1]):
|
||||
return self.cell_matrix[x][y]
|
||||
def calculate_costs(self):
|
||||
for x in range(self.dimensions[0]):
|
||||
for y in range(self.dimensions[1]):
|
||||
self.get_cell(x, y).calculate_cost()
|
||||
self.get_cell(x, y).calculate_heuristic()
|
||||
self.get_cell(x, y).calculate_estimated()
|
||||
def draw(self):
|
||||
for x in range(self.dimensions[0]):
|
||||
for y in range(self.dimensions[1]):
|
||||
self.get_cell(x, y).draw()
|
||||
|
||||
steps_count = 0
|
||||
|
||||
map_dict = dict()
|
||||
|
||||
class Entity:
|
||||
coordinates = (0, 0)
|
||||
position = (0, 0)
|
||||
offset = (0, 0)
|
||||
cell = None
|
||||
name = ""
|
||||
color = "black"
|
||||
font_size = 32
|
||||
def __init__(self, cell_position):
|
||||
self.set_cell(map.get_cell(cell_position[0], cell_position[1]))
|
||||
def set_cell(self, cell):
|
||||
self.cell = cell
|
||||
self.position = cell.position
|
||||
self.coordinates = (self.cell.coordinates[0] + self.offset[0],
|
||||
self.cell.coordinates[1] + self.offset[1])
|
||||
self.cell.set_content(self)
|
||||
def set_position(self, x, y):
|
||||
self.set_cell(map.get_cell(x, y))
|
||||
def draw(self):
|
||||
font = pg.font.Font(None, self.font_size)
|
||||
text = font.render(self.name, True, self.color)
|
||||
screen.blit(text, ((self.cell.coordinates[0] + self.offset[0], self.cell.coordinates[1] + self.offset[1])))
|
||||
def initialize_map_dict():
|
||||
for x in range(MAP_SIZE):
|
||||
for y in range(MAP_SIZE):
|
||||
map_dict[(x,y)] = [1000000, 0, ".", None] #g h status previous_cell
|
||||
|
||||
def calculate_all_h_for_target(target:tuple):
|
||||
for item in map_dict.items():
|
||||
item[1][1] = abs(target[0] - item[0][0]) + abs(target[1] - item[0][1])
|
||||
|
||||
def print_map():
|
||||
global neo, keymaker
|
||||
map_str = ""
|
||||
|
||||
|
||||
|
||||
pass
|
||||
class Actor(Entity):
|
||||
perception_radius = 1
|
||||
percepted_cells = []
|
||||
pass
|
||||
for x in range(MAP_SIZE):
|
||||
for y in range(MAP_SIZE):
|
||||
if (x,y) == neo:
|
||||
map_str += " n "
|
||||
elif (x,y) == keymaker:
|
||||
map_str += " k "
|
||||
#elif (x,y) == (3,7):
|
||||
# map_str += " m "
|
||||
else:
|
||||
map_str += f" {map_dict[(x, y)][2]} "
|
||||
map_str += "\n"
|
||||
print(map_str)
|
||||
|
||||
class Neo(Actor):
|
||||
def print_cells_parameters(cells:list):
|
||||
str = ""
|
||||
for cell in cells:
|
||||
str += f"({cell[0]},{cell[1]}): {map_dict[cell][0]} + {map_dict[cell][1]} = {map_dict[cell][0] + map_dict[cell][1]} ({map_dict[cell][2]}) prev:{map_dict[cell][3]} | "
|
||||
print(str)
|
||||
|
||||
def get_walkable_cells_list(actor:tuple):
|
||||
potential_positions = [
|
||||
(actor[0], actor[1] + 1), (actor[0], actor[1] - 1),
|
||||
(actor[0] - 1, actor[1]), (actor[0] + 1, actor[1])
|
||||
]
|
||||
return [pos for pos in potential_positions if pos[0] in range(MAP_SIZE) and pos[1] in range(MAP_SIZE)]
|
||||
|
||||
def get_open_set_list():
|
||||
open_set = []
|
||||
def __init__(self, cell_position):
|
||||
super().__init__(cell_position)
|
||||
self.color = (100, 100, 255)
|
||||
self.name = "neo"
|
||||
def set_position(self, x, y):
|
||||
map.get_cell(x, y).closed = True
|
||||
self.update_open_set()
|
||||
return super().set_position(x, y)
|
||||
def update_open_set(self):
|
||||
|
||||
self.open_set = []
|
||||
|
||||
estimated_cells = []
|
||||
estimated_cells.append((self.position[0] + 1, self.position[1]))
|
||||
estimated_cells.append((self.position[0] - 1, self.position[1]))
|
||||
estimated_cells.append((self.position[0], self.position[1] + 1))
|
||||
estimated_cells.append((self.position[0], self.position[1] - 1))
|
||||
for i in estimated_cells:
|
||||
if 0 <= i[0] < map.dimensions[0] and 0 <= i[1] < map.dimensions[1]:
|
||||
if (map.get_cell(i[0], i[0]).closed == False):
|
||||
self.open_set.append(map.get_cell(i[0], i[1]))
|
||||
|
||||
|
||||
def percept(self):
|
||||
#clear percepted celles
|
||||
for i in self.percepted_cells:
|
||||
if (i != None):
|
||||
i.clear_perceptor()
|
||||
self.percepted_cells = []
|
||||
|
||||
self.open_set = []
|
||||
|
||||
for x in range(self.position[0] - self.perception_radius,
|
||||
self.position[0] + self.perception_radius + 1):
|
||||
for y in range(self.position[1] - self.perception_radius,
|
||||
self.position[1] + self.perception_radius + 1):
|
||||
if 0 <= x < map.dimensions[0] and 0 <= y < map.dimensions[1]:
|
||||
if (x != self.position[0] or y != self.position[1]):
|
||||
self.percepted_cells.append(map.get_cell(x, y)) #set current percieved cells
|
||||
|
||||
|
||||
#set perceptors
|
||||
for i in self.percepted_cells:
|
||||
if (i != None):
|
||||
i.set_perceptor(self)
|
||||
map.draw()
|
||||
pg.display.update()
|
||||
|
||||
pass
|
||||
class Smith(Actor):
|
||||
def __init__(self, cell_position):
|
||||
super().__init__(cell_position)
|
||||
self.color = "red"
|
||||
self.name = "smith"
|
||||
self.font_size = 26
|
||||
def percept(self):
|
||||
#clear percepted celles
|
||||
for i in self.percepted_cells:
|
||||
i.clear_perceptor()
|
||||
self.percepted_cells = []
|
||||
|
||||
for x in range(self.position[0] - self.perception_radius,
|
||||
self.position[0] + self.perception_radius + 1):
|
||||
for y in range(self.position[1] - self.perception_radius,
|
||||
self.position[1] + self.perception_radius + 1):
|
||||
if (x != self.position[0] or y != self.position[1]):
|
||||
self.percepted_cells.append(map.get_cell(x, y)) #set current percieved cells
|
||||
|
||||
#set perceptors
|
||||
for i in self.percepted_cells:
|
||||
i.set_perceptor(self)
|
||||
pass
|
||||
class Sentinel(Actor):
|
||||
def __init__(self, cell_position):
|
||||
super().__init__(cell_position)
|
||||
self.color = "orange"
|
||||
self.name = "sentinel"
|
||||
self.font_size = 18
|
||||
def percept(self):
|
||||
#clear percepted celles
|
||||
for i in self.percepted_cells:
|
||||
i.clear_perceptor()
|
||||
self.percepted_cells = []
|
||||
|
||||
stencil_cells_positions = []
|
||||
stencil_cells_positions.append((self.position[0], self.position[1] + 1))
|
||||
stencil_cells_positions.append((self.position[0] - 1, self.position[1]))
|
||||
stencil_cells_positions.append((self.position[0], self.position[1]))
|
||||
stencil_cells_positions.append((self.position[0] + 1, self.position[1]))
|
||||
stencil_cells_positions.append((self.position[0], self.position[1] - 1))
|
||||
|
||||
for i in stencil_cells_positions:
|
||||
if (i[0] != self.position[0] or i[1] != self.position[1]):
|
||||
self.percepted_cells.append(map.get_cell(i[0], i[1])) #set current percieved cells
|
||||
|
||||
#set perceptors
|
||||
for i in self.percepted_cells:
|
||||
i.set_perceptor(self)
|
||||
pass
|
||||
class Keymaker(Entity):
|
||||
def __init__(self, cell_position):
|
||||
super().__init__(cell_position)
|
||||
self.color = "green"
|
||||
self.name = "key maker"
|
||||
self.font_size = 14
|
||||
pass
|
||||
class Backdoor_key(Entity):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def read_initial_inputs():
|
||||
neo.perception_radius = (int)(input())
|
||||
keymaker_position = input().split(" ")
|
||||
keymaker.set_position((int)(keymaker_position[0]), (int)(keymaker_position[1]))
|
||||
|
||||
def read_input():
|
||||
inpt = input().split(" ")
|
||||
return inpt
|
||||
for item in map_dict.items():
|
||||
if item[1][2] == "+":
|
||||
open_set.append(item[0])
|
||||
return open_set
|
||||
|
||||
def move(x, y):
|
||||
for i in neo.open_set:
|
||||
print(i.position)
|
||||
if map.get_cell(x, y) in neo.open_set: #TODO: FIX CHECK
|
||||
neo.set_position(x, y)
|
||||
print(f"m {x} {y}")
|
||||
def get_closed_set_list():
|
||||
closed_set = []
|
||||
for item in map_dict.items():
|
||||
if item[1][2] == "-":
|
||||
closed_set.append(item[0])
|
||||
return closed_set
|
||||
|
||||
def make_opened(cell:tuple):
|
||||
map_dict[cell][2] = "+"
|
||||
|
||||
def make_closed(cell:tuple):
|
||||
map_dict[cell][2] = "-"
|
||||
|
||||
def make_blocked(cell:tuple):
|
||||
map_dict[cell][2] = "="
|
||||
|
||||
def get_status(cell:tuple):
|
||||
return map_dict[cell][2]
|
||||
|
||||
def get_g(cell:tuple):
|
||||
return map_dict[cell][0]
|
||||
|
||||
def get_h(cell:tuple):
|
||||
return map_dict[cell][1]
|
||||
|
||||
def get_f(cell:tuple):
|
||||
return map_dict[cell][0] + map_dict[cell][1]
|
||||
|
||||
def set_g(cell:tuple, value):
|
||||
map_dict[cell][0] = value
|
||||
|
||||
def set_h(cell:tuple, value):
|
||||
map_dict[cell][1] = value
|
||||
|
||||
def add_g(cell:tuple, value):
|
||||
map_dict[cell][0] += value
|
||||
|
||||
def add_h(cell:tuple, value):
|
||||
map_dict[cell][1] += value
|
||||
|
||||
def assign_previous(cell:tuple, previous_cell:tuple):
|
||||
map_dict[cell][3] = previous_cell
|
||||
|
||||
def get_previous(cell:tuple):
|
||||
return map_dict[cell][3]
|
||||
|
||||
def calculate_cell_with_minimal_g(cells:list, filter=None):
|
||||
selected_cells = []
|
||||
if filter == None:
|
||||
for cell in cells:
|
||||
if get_status(cell) != "=":
|
||||
selected_cells.append(cell)
|
||||
else:
|
||||
print("ERROR: CAN'T MOVE HERE")
|
||||
neo.update_open_set()
|
||||
for cell in cells:
|
||||
if get_status(cell) == filter and get_status(cell) != "=":
|
||||
selected_cells.append(cell)
|
||||
|
||||
gs = []
|
||||
for cell in selected_cells:
|
||||
gs.append(get_g(cell)) # get_f(cell, accumulated_g)
|
||||
min_g = min(gs)
|
||||
|
||||
min_cells_by_g = []
|
||||
for cell in selected_cells:
|
||||
if get_g(cell) == min_g: # get_f(cell, accumulated_g)
|
||||
min_cells_by_g.append(cell)
|
||||
|
||||
|
||||
next_cell = min_cells_by_g[0]
|
||||
return next_cell
|
||||
|
||||
|
||||
map = Map((8, 8))
|
||||
neo = Neo((3, 3))
|
||||
neo.perception_radius = 2
|
||||
smith = Smith((1,1))
|
||||
sentinel = Sentinel((3,4))
|
||||
keymaker = Keymaker((5,5))
|
||||
pg.init()
|
||||
screen = pg.display.set_mode([1124,1124])
|
||||
pg.display.set_caption("Matrix Universe")
|
||||
running = True
|
||||
#pg.time.delay(7000)
|
||||
neo.set_position(0, 0) #TODO: ITS TEMPORARY
|
||||
neo.update_open_set()
|
||||
move(0, 0)
|
||||
read_initial_inputs()
|
||||
pg.time.delay(1500)
|
||||
while running:
|
||||
for event in pg.event.get():
|
||||
if event.type == pg.QUIT:
|
||||
running = False
|
||||
screen.fill("black")
|
||||
map.calculate_costs()
|
||||
map.draw()
|
||||
neo.percept()
|
||||
neo.draw()
|
||||
def calculate_minimal_cell(cells:list, filter=None):
|
||||
selected_cells = []
|
||||
if filter == None:
|
||||
for cell in cells:
|
||||
if get_status(cell) != "=":
|
||||
selected_cells.append(cell)
|
||||
else:
|
||||
for cell in cells:
|
||||
if get_status(cell) == filter and get_status(cell) != "=":
|
||||
selected_cells.append(cell)
|
||||
|
||||
fs = []
|
||||
for cell in selected_cells:
|
||||
fs.append(get_f(cell)) # get_f(cell, accumulated_g)
|
||||
min_f = min(fs)
|
||||
|
||||
keymaker.draw()
|
||||
pg.display.update()
|
||||
min_cells_by_f = []
|
||||
for cell in selected_cells:
|
||||
if get_f(cell) == min_f: # get_f(cell, accumulated_g)
|
||||
min_cells_by_f.append(cell)
|
||||
|
||||
move_input = read_input()
|
||||
pg.time.delay(1500)
|
||||
|
||||
move((int)(move_input[0]), (int)(move_input[1]))
|
||||
hs = []
|
||||
for cell in min_cells_by_f:
|
||||
hs.append(get_h(cell)) #get_h(cell)
|
||||
min_h = min(hs)
|
||||
|
||||
min_cells_by_h = []
|
||||
for cell in min_cells_by_f:
|
||||
if get_h(cell) == min_h: #get_h(cell)
|
||||
min_cells_by_h.append(cell)
|
||||
|
||||
for cell in min_cells_by_h:
|
||||
if get_status(cell) == "+":
|
||||
next_cell = cell
|
||||
return next_cell
|
||||
next_cell = min_cells_by_h[0]
|
||||
return next_cell
|
||||
|
||||
pg.display.update()
|
||||
'''
|
||||
|
||||
|
||||
|
||||
neo.set_position(5,6)
|
||||
|
||||
smith.draw()
|
||||
smith.percept()
|
||||
|
||||
sentinel.draw()
|
||||
sentinel.percept()
|
||||
|
||||
keymaker.draw()
|
||||
|
||||
'''
|
||||
|
||||
|
||||
#pg.time.delay(1000)
|
||||
'''def roll_back(looking_for_cell:tuple):
|
||||
global neo
|
||||
time.sleep(0.1)
|
||||
while(get_previous(neo) != None and looking_for_cell not in get_walkable_cells_list(neo)):
|
||||
print_cells_paremeters(get_walkable_cells_list(neo))
|
||||
print_map()
|
||||
neo = get_previous(neo)
|
||||
time.sleep(0.1)'''
|
||||
|
||||
def roll_back(looking_for_cell:tuple):
|
||||
global neo
|
||||
#time.sleep(0.1)
|
||||
while(get_previous(neo) != None and looking_for_cell not in get_walkable_cells_list(neo)):
|
||||
#print_cells_parameters(get_walkable_cells_list(neo))
|
||||
#print("roll back")
|
||||
#print(f"target: ({looking_for_cell[0]},{looking_for_cell[1]})")
|
||||
#print_map()
|
||||
inputs = read_system()
|
||||
neo = get_previous(neo)
|
||||
steps_count += 1
|
||||
print(f"m {neo[0]} {neo[1]}")
|
||||
#time.sleep(0.1)
|
||||
|
||||
def get_position_input():
|
||||
position_input_list = input().split(" ")
|
||||
return int(position_input_list[0]), int(position_input_list[1])
|
||||
|
||||
def read_system():
|
||||
number_of_items = int(input())
|
||||
if number_of_items == 0:
|
||||
return False
|
||||
items = {}
|
||||
for _ in range(number_of_items):
|
||||
x, y, status = input().split(' ')
|
||||
items[(int(x), int(y))] = status
|
||||
return items
|
||||
|
||||
# TODO MAYBE MAKE A FUNCTION THAT RECALCULATES ALL "PREVIOSES" ON THE MAP USING assign_previous(cell, calculate_cell_with_minimal_g(get_walkable_cells_list(cell), "-"))
|
||||
keymaker = (5,6)
|
||||
|
||||
initialize_map_dict()
|
||||
calculate_all_h_for_target(keymaker)
|
||||
|
||||
make_blocked((0,1))
|
||||
make_blocked((1,0))
|
||||
|
||||
#make_blocked((4,6))
|
||||
|
||||
#make_blocked((6,6))
|
||||
|
||||
#make_blocked((4,8))
|
||||
print_map()
|
||||
|
||||
#print_cells_parameters(get_walkable_cells_list(neo))
|
||||
#time.sleep(0.1)
|
||||
finish = False
|
||||
seeking_for_target = False
|
||||
perception_radius = input()
|
||||
keymaster = get_position_input()
|
||||
print("m 0 0")
|
||||
while (finish == False):
|
||||
inputs = read_system()
|
||||
if inputs != False:
|
||||
for inpt in inputs.items():
|
||||
if inpt[1] == "P":
|
||||
make_blocked(inpt[0])
|
||||
|
||||
make_closed(neo)
|
||||
for cell in get_walkable_cells_list(neo):
|
||||
if get_status(cell) == ".":
|
||||
make_opened(cell)
|
||||
# TODO find and connect to minimum f|h closed in its own walkable radius
|
||||
if get_status(cell) == "+":
|
||||
if (get_g(neo) + 1) < get_g(cell) or get_g(cell) == 1000000:
|
||||
set_g(cell, (get_g(neo) + 1)) # TODO MAKE A CHECK IF EXISTING g SMALLER THAN NEW ONE
|
||||
|
||||
target_cell = calculate_minimal_cell(list(map_dict.keys()), "+")
|
||||
|
||||
if target_cell in get_walkable_cells_list(neo):
|
||||
seeking_for_target = False
|
||||
if target_cell not in get_walkable_cells_list(neo) and not seeking_for_target:
|
||||
roll_back(target_cell)
|
||||
seeking_for_target = True
|
||||
if target_cell in get_walkable_cells_list(neo):
|
||||
next_cell = target_cell
|
||||
seeking_for_target = False
|
||||
else:
|
||||
next_cell = calculate_minimal_cell(get_walkable_cells_list(neo))
|
||||
else:
|
||||
next_cell = calculate_minimal_cell(get_walkable_cells_list(neo))
|
||||
assign_previous(next_cell, calculate_cell_with_minimal_g(get_walkable_cells_list(next_cell), "-"))
|
||||
previous = get_previous(next_cell)
|
||||
#print_cells_parameters(get_walkable_cells_list(neo))
|
||||
print_map()
|
||||
neo = next_cell
|
||||
steps_count += 1
|
||||
print(f"m {neo[0]} {neo[1]}")
|
||||
#time.sleep(0.2)
|
||||
if neo == keymaker:
|
||||
finish = True
|
||||
# TODO MAKE CHECK IF NO PATH EXISTS
|
||||
print(f"e {steps_count}")
|
||||
@@ -125,7 +125,7 @@ while not finish:
|
||||
next_cell = min(min_f_cell_list, key=lambda cell: get_h(cell))
|
||||
neo = next_cell
|
||||
accumulated_g += 1 # TODO ENSURE THAT g WORKS PROPERLY
|
||||
closed_cells.append(next_cell)
|
||||
closed_cells.append(next_cell) # TODO DELETE
|
||||
passed_cells.append(next_cell)
|
||||
print(f"m {next_cell[1]} {next_cell[0]}") # TODO FIX OR ENSURE THAT x,y OR y,x DOES NOT MAKE ANY DIFFERENCE
|
||||
steps_count += 1
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
import time
|
||||
MAP_SIZE = 9
|
||||
start = (0, 0)
|
||||
neo = start
|
||||
observer = neo
|
||||
keymaster = ()
|
||||
|
||||
green_cells = [] #open cells +
|
||||
red_cells = [] #closed cells -
|
||||
black_cells = [] #blocked cells =
|
||||
blue_cells = [] #traversed cells #
|
||||
|
||||
steps_count = 0
|
||||
#accumulated_g = 0
|
||||
map_dict = dict()
|
||||
|
||||
def initialize_weighted_map_dict():
|
||||
for x in range(MAP_SIZE):
|
||||
for y in range(MAP_SIZE):
|
||||
map_dict[(x, y)] = [0, 0, 0, '.'] # (x,y) : (h, g, f, status) ??? [float("inf"), float("inf"), float("inf"), '.']
|
||||
|
||||
|
||||
def print_map():
|
||||
map_str = ""
|
||||
|
||||
for x in range(MAP_SIZE):
|
||||
for y in range(MAP_SIZE):
|
||||
if map_dict[(x,y)][3] in "kon":
|
||||
set_status((x,y), '.')
|
||||
|
||||
for x in range(MAP_SIZE):
|
||||
for y in range(MAP_SIZE):
|
||||
|
||||
set_status(keymaster, 'k')
|
||||
set_status(observer, 'o')
|
||||
set_status(neo, 'n')
|
||||
|
||||
map_str += " " + map_dict[(x, y)][3] + " "
|
||||
map_str += "\n"
|
||||
print(map_str)
|
||||
|
||||
def get_g(cell): # TODO MAYBE FIX NEEDED
|
||||
#new_g = accumulated_g + 1
|
||||
#if accumulated_g + 1 < map_dict[cell][1]:
|
||||
# new_g = map_dict[cell][1]
|
||||
return map_dict[cell][1] + 1
|
||||
|
||||
def get_h(cell):
|
||||
return abs(keymaster[0] - cell[0]) + abs(keymaster[1] - cell[1])
|
||||
|
||||
def get_f(cell):
|
||||
if map_dict[cell][3] == '=':
|
||||
return float("inf")
|
||||
return get_g(cell) + get_h(cell)
|
||||
|
||||
def get_walkable_cells(actor:tuple):
|
||||
potential_positions = [
|
||||
(actor[0], actor[1] + 1), (actor[0], actor[1] - 1),
|
||||
(actor[0] - 1, actor[1]), (actor[0] + 1, actor[1])
|
||||
]
|
||||
return [pos for pos in potential_positions if pos[0] in range(MAP_SIZE) and pos[1] in range(MAP_SIZE)]
|
||||
|
||||
def get_position_input():
|
||||
position_input_list = input().split(" ")
|
||||
return int(position_input_list[0]), int(position_input_list[1])
|
||||
|
||||
def set_status(position:tuple, status:str):
|
||||
if status == ".":
|
||||
map_dict[position] = [0, 0, 0, '.']
|
||||
else:
|
||||
map_dict[position][3] = status
|
||||
|
||||
def print_cells_paremeters(cells:list):
|
||||
str = ""
|
||||
for cell in cells:
|
||||
str += f"({cell[0]},{cell[1]}): {map_dict[cell][0]} + {map_dict[cell][1]} = {map_dict[cell][2]} ({map_dict[cell][3]}) | "
|
||||
print(str)
|
||||
|
||||
def print_cells_dict_paremeters(cells_dict:dict):
|
||||
str = ""
|
||||
for cell in cells_dict.items():
|
||||
str += f"({cell[0][0]},{cell[0][1]}): {cell[1][0]} + {cell[1][1]} = {cell[1][2]} ({cell[1][3]}) | "
|
||||
print(str)
|
||||
|
||||
def get_local_walkable_cells(actor):
|
||||
local_walkable_cells = dict()
|
||||
for cell in get_walkable_cells(actor):
|
||||
if actor == observer and map_dict[cell][3] == "=":
|
||||
local_walkable_cells[cell] = [map_dict[cell][0], map_dict[cell][1], float("inf"), map_dict[cell][3]]
|
||||
elif actor == observer and map_dict[cell][3] == "-":
|
||||
local_walkable_cells[cell] = [map_dict[cell][0], map_dict[cell][1], map_dict[cell][2] + 100000, map_dict[cell][3]]
|
||||
else:
|
||||
local_walkable_cells[cell] = [map_dict[cell][0], map_dict[cell][1], map_dict[cell][2], map_dict[cell][3]]
|
||||
return local_walkable_cells
|
||||
|
||||
def calculate_next_cell(actor):
|
||||
|
||||
# making local mutable walkable cells dictionary
|
||||
walkable_cells_dict = dict()
|
||||
#walkable_cells_dict = get_local_walkable_cells(actor)
|
||||
for cell in get_walkable_cells(actor):
|
||||
if actor == observer and map_dict[cell][3] == "=":
|
||||
walkable_cells_dict[cell] = [map_dict[cell][0], map_dict[cell][1], map_dict[cell][2], map_dict[cell][3]]
|
||||
elif actor == observer and map_dict[cell][3] == "-":
|
||||
walkable_cells_dict[cell] = [map_dict[cell][0], map_dict[cell][1], 1000000 + map_dict[cell][2], map_dict[cell][3]]
|
||||
else:
|
||||
walkable_cells_dict[cell] = [map_dict[cell][0], map_dict[cell][1], map_dict[cell][2], map_dict[cell][3]]
|
||||
|
||||
|
||||
fs = []
|
||||
for cell_values in walkable_cells_dict.values():
|
||||
fs.append(cell_values[2]) # get_f(cell, accumulated_g)
|
||||
min_f = min(fs)
|
||||
|
||||
min_cells_by_f = []
|
||||
for cell in walkable_cells_dict.keys():
|
||||
if walkable_cells_dict[cell][2] == min_f: # get_f(cell, accumulated_g)
|
||||
min_cells_by_f.append(cell)
|
||||
|
||||
hs = []
|
||||
for cell in min_cells_by_f:
|
||||
hs.append(walkable_cells_dict[cell][0]) #get_h(cell)
|
||||
min_h = min(hs)
|
||||
|
||||
min_cells_by_h = []
|
||||
for cell in min_cells_by_f:
|
||||
if walkable_cells_dict[cell][0] == min_h: #get_h(cell)
|
||||
min_cells_by_h.append(cell)
|
||||
|
||||
next_cell = min_cells_by_h[0]
|
||||
return next_cell
|
||||
|
||||
def read_system():
|
||||
number_of_items = int(input())
|
||||
if number_of_items == 0:
|
||||
return False
|
||||
items = {}
|
||||
for _ in range(number_of_items):
|
||||
x, y, status = input().split(' ')
|
||||
items[(int(x), int(y))] = status
|
||||
return items
|
||||
|
||||
def regenerate_route():
|
||||
global green_cells, red_cells, black_cells, neo, observer
|
||||
observer = neo
|
||||
previous_cell = ()
|
||||
finish = False
|
||||
green_cell_found = False
|
||||
|
||||
|
||||
while not finish:
|
||||
map_dict[observer][1] += 5
|
||||
|
||||
# setting green cells
|
||||
for cell in get_walkable_cells(observer):
|
||||
if map_dict[cell][3] not in "kon-#=":
|
||||
set_status(cell, '+')
|
||||
|
||||
for cell in get_walkable_cells(observer):
|
||||
map_dict[cell][0] = get_h(cell)
|
||||
map_dict[cell][1] = get_g(cell)
|
||||
map_dict[cell][2] = get_f(cell)
|
||||
|
||||
# check if there is any green cell
|
||||
green_count = 0
|
||||
for cell in get_walkable_cells(observer):
|
||||
if map_dict[cell][3] == "+":
|
||||
green_cell_found = True
|
||||
green_count += 1
|
||||
set_status(observer, "-")
|
||||
if green_count == 0 and green_cell_found:
|
||||
print("return")
|
||||
print_cells_paremeters(get_walkable_cells(observer))
|
||||
#print_map()
|
||||
|
||||
regenerate_route()
|
||||
break
|
||||
|
||||
|
||||
next_cell = calculate_next_cell(observer)
|
||||
|
||||
|
||||
|
||||
#print_cells_paremeters(get_walkable_cells(observer))
|
||||
print_cells_paremeters(get_walkable_cells(observer))
|
||||
print_map()
|
||||
|
||||
previous_cell = observer
|
||||
observer = next_cell
|
||||
|
||||
|
||||
set_status(previous_cell, '-')
|
||||
|
||||
#accumulated_g += 1
|
||||
red_cells.append(next_cell)
|
||||
|
||||
|
||||
|
||||
time.sleep(0.1)
|
||||
if observer == keymaster:
|
||||
finish = True
|
||||
|
||||
|
||||
def do_step():
|
||||
global neo
|
||||
next_cell = calculate_next_cell(neo)
|
||||
neo = next_cell
|
||||
print(f"m {neo[0]} {neo[1]}")
|
||||
|
||||
perception_radius = 2 #input()
|
||||
keymaster = (6,4) #get_position_input()
|
||||
|
||||
initialize_weighted_map_dict()
|
||||
set_status((0,4),'=')
|
||||
set_status((1,3),'=')
|
||||
set_status((2,2),'=')
|
||||
set_status((3,1),'=')
|
||||
#set_status((4,0),'=') # TODO MAKE ERROR IF ALL PATHS ARE BLOCKED
|
||||
regenerate_route()
|
||||
|
||||
finish = False
|
||||
|
||||
while (finish == False):
|
||||
do_step()
|
||||
print_map()
|
||||
recieved_inputs = read_system()
|
||||
|
||||
for inpt in recieved_inputs.items():
|
||||
if inpt[1] == "P":
|
||||
set_status(inpt[0], "=")
|
||||
|
||||
'''#refreshing the path
|
||||
for item in map_dict.items():
|
||||
if item[1][3] not in "=":
|
||||
set_status(item[0],".")'''
|
||||
|
||||
regenerate_route()
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import sys
|
||||
import heapq
|
||||
|
||||
# Initialize cost, heuristic, map, visited nodes, and parent tracking arrays
|
||||
min_costs = [[10000]*9 for _ in range(9)] # Initialize minimum cost array with a high value (10000)
|
||||
hs = [[0]*9 for _ in range(9)] # Heuristic array for A* (Manhattan distance)
|
||||
astar_map = [['.']*9 for _ in range(9)] # Initial unexplored map with '.'
|
||||
visited_nodes = [[False]*9 for _ in range(9)] # Track visited nodes
|
||||
node_parents = [[None]*9 for _ in range(9)] # Track path parents for backtracking
|
||||
|
||||
# Input: perception radius and Keymaker position
|
||||
perception_radius = int(input()) # 1 or 2 for Neo’s perception variant
|
||||
input_list = input().split()
|
||||
goal_x, goal_y = int(input_list[0]), int(input_list[1]) # Keymaker’s coordinates
|
||||
|
||||
# Set up heuristic values (Manhattan distance) and initial costs for A*
|
||||
for i in range(9):
|
||||
for j in range(9):
|
||||
hs[j][i] = abs(j - goal_y) + abs(i - goal_x) # Calculate heuristic distance
|
||||
min_costs[j][i] = 10000 # Set initial high cost for all cells
|
||||
|
||||
min_costs[0][0] = 0 # Starting position (0,0) cost is zero
|
||||
|
||||
# Priority queue for A* with starting point at (0,0)
|
||||
priority_queue = []
|
||||
heapq.heappush(priority_queue, (min_costs[0][0] + hs[0][0], 0, 0)) # Push initial cell to queue
|
||||
|
||||
# Main A* loop
|
||||
while len(priority_queue) != 0:
|
||||
# Extract node with lowest f = g + h value
|
||||
temp, current_x, current_y = heapq.heappop(priority_queue)
|
||||
if visited_nodes[current_y][current_x]:
|
||||
continue
|
||||
visited_nodes[current_y][current_x] = True # Mark node as visited
|
||||
|
||||
# Backtrack to get the path to current node
|
||||
parent_node = node_parents[current_y][current_x]
|
||||
path_to_current = [(current_x, current_y)]
|
||||
while parent_node is not None:
|
||||
path_to_current.append(parent_node)
|
||||
parent_node = node_parents[parent_node[1]][parent_node[0]]
|
||||
|
||||
# Execute path, querying for perception data
|
||||
for i in reversed(range(len(path_to_current))):
|
||||
print(f"m {path_to_current[i][0]} {path_to_current[i][1]}")
|
||||
neighbor_count = int(input()) # Read the number of perceived items
|
||||
# Update map with perceived items
|
||||
for _ in range(neighbor_count):
|
||||
input_data = input().split()
|
||||
neighbor_x = int(input_data[0])
|
||||
neighbor_y = int(input_data[1])
|
||||
neighbor_char = input_data[2][0] # Character representing item
|
||||
astar_map[neighbor_y][neighbor_x] = neighbor_char # Update map cell
|
||||
|
||||
# Explore neighboring cells
|
||||
for dx, dy in [(1, 0), (0, 1), (-1, 0), (0, -1)]: # Move in four directions
|
||||
neighbor_x = current_x + dx
|
||||
neighbor_y = current_y + dy
|
||||
# Check boundaries and if cell is unexplored and safe
|
||||
if 0 <= neighbor_x < 9 and 0 <= neighbor_y < 9 and not visited_nodes[neighbor_y][neighbor_x] and astar_map[neighbor_y][neighbor_x] not in ('P', 'A', 'S'):
|
||||
# Update cost if a better path is found
|
||||
if min_costs[neighbor_y][neighbor_x] > min_costs[current_y][current_x] + 1:
|
||||
node_parents[neighbor_y][neighbor_x] = (current_x, current_y)
|
||||
min_costs[neighbor_y][neighbor_x] = min_costs[current_y][current_x] + 1
|
||||
# Add node to priority queue with updated f = g + h value
|
||||
heapq.heappush(priority_queue, (min_costs[neighbor_y][neighbor_x] + hs[neighbor_y][neighbor_x], neighbor_x, neighbor_y))
|
||||
|
||||
# Repeat path execution to keep querying
|
||||
for i in range(len(path_to_current)):
|
||||
print(f"m {path_to_current[i][0]} {path_to_current[i][1]}")
|
||||
neighbor_count = int(input()) # Re-read surroundings
|
||||
for _ in range(neighbor_count):
|
||||
input_data = input().split()
|
||||
neighbor_x = int(input_data[0])
|
||||
neighbor_y = int(input_data[1])
|
||||
neighbor_char = input_data[2][0]
|
||||
astar_map[neighbor_y][neighbor_x] = neighbor_char # Update map
|
||||
|
||||
# Check if the goal is reached and output the result
|
||||
if min_costs[goal_y][goal_x] != 10000:
|
||||
print(f"e {min_costs[goal_y][goal_x]}") # Output shortest path length
|
||||
else:
|
||||
print("e -1") # Output -1 if unsolvable.
|
||||
@@ -0,0 +1,172 @@
|
||||
import heapq
|
||||
import time
|
||||
|
||||
|
||||
|
||||
def get_percepted_cells(position:tuple):
|
||||
cells = []
|
||||
for x in range(position[0]- perception_radius, position[0] + perception_radius + 1):
|
||||
for y in range(position[1]- perception_radius, position[1] + perception_radius + 1):
|
||||
if (x,y) != position:
|
||||
cells.append((x,y))
|
||||
return cells
|
||||
|
||||
failed_tests = 0
|
||||
passed_tests = 0
|
||||
|
||||
total_time = 0
|
||||
average_time = 0
|
||||
|
||||
test_number = 0
|
||||
with open("20k_testset.txt", "r") as file:
|
||||
lines = file.readlines()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
line_number = 0
|
||||
while(test_number < 100):
|
||||
#time.sleep(.5)
|
||||
start_time = time.time()
|
||||
current_test_lines = []
|
||||
for local_line_number in range(14):
|
||||
current_line = lines[line_number]
|
||||
current_test_lines.append(current_line)
|
||||
line_number += 1
|
||||
|
||||
# Initialize cost, heuristic, map, visited nodes, and parent tracking arrays
|
||||
min_costs = [[10000]*9 for _ in range(9)] # Initialize minimum cost array with a high value (10000)
|
||||
hs = [[0]*9 for _ in range(9)] # Heuristic array for A* (Manhattan distance)
|
||||
astar_map = [['.']*9 for _ in range(9)] # Initial unexplored map with '.'
|
||||
visited_nodes = [[False]*9 for _ in range(9)] # Track visited nodes
|
||||
node_parents = [[None]*9 for _ in range(9)] # Track path parents for backtracking
|
||||
|
||||
# Input: perception radius and Keymaker position
|
||||
perception_radius = int(current_test_lines[1][0]) # 1 or 2 for Neo’s perception variant
|
||||
goal_x, goal_y = int(current_test_lines[2][1]), int(current_test_lines[2][4]) # Keymaker’s coordinates
|
||||
|
||||
# Set up heuristic values (Manhattan distance) and initial costs for A*
|
||||
for i in range(9):
|
||||
for j in range(9):
|
||||
hs[j][i] = abs(j - goal_y) + abs(i - goal_x) # Calculate heuristic distance
|
||||
min_costs[j][i] = 10000 # Set initial high cost for all cells
|
||||
|
||||
min_costs[0][0] = 0 # Starting position (0,0) cost is zero
|
||||
|
||||
# Priority queue for A* with starting point at (0,0)
|
||||
priority_queue = []
|
||||
heapq.heappush(priority_queue, (min_costs[0][0] + hs[0][0], 0, 0)) # Push initial cell to queue
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#for line in current_test_lines:
|
||||
#print(line[:-1])
|
||||
|
||||
test_map_matrix = current_test_lines[3:12]
|
||||
|
||||
#for line in test_map_matrix:
|
||||
#print(line[:-1])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Main A* loop
|
||||
while len(priority_queue) != 0:
|
||||
# Extract node with lowest f = g + h value
|
||||
temp, current_x, current_y = heapq.heappop(priority_queue)
|
||||
if visited_nodes[current_y][current_x]:
|
||||
continue
|
||||
visited_nodes[current_y][current_x] = True # Mark node as visited
|
||||
|
||||
# Backtrack to get the path to current node
|
||||
parent_node = node_parents[current_y][current_x]
|
||||
path_to_current = [(current_x, current_y)]
|
||||
while parent_node is not None:
|
||||
path_to_current.append(parent_node)
|
||||
parent_node = node_parents[parent_node[1]][parent_node[0]]
|
||||
|
||||
# Execute path, querying for perception data
|
||||
for i in reversed(range(len(path_to_current))):
|
||||
#print(f"m {path_to_current[i][0]} {path_to_current[i][1]}")
|
||||
for x in range(len(test_map_matrix)):
|
||||
for y in range(len(test_map_matrix)):
|
||||
if (x,y) in get_percepted_cells((current_x, current_y)) and test_map_matrix[x][y] != ".":
|
||||
astar_map[x][y] = test_map_matrix[x][y]
|
||||
|
||||
# Explore neighboring cells
|
||||
for dx, dy in [(1, 0), (0, 1), (-1, 0), (0, -1)]: # Move in four directions
|
||||
neighbor_x = current_x + dx
|
||||
neighbor_y = current_y + dy
|
||||
# Check boundaries and if cell is unexplored and safe
|
||||
if 0 <= neighbor_x < 9 and 0 <= neighbor_y < 9 and not visited_nodes[neighbor_y][neighbor_x] and astar_map[neighbor_y][neighbor_x] not in ('P', 'A', 'S'):
|
||||
# Update cost if a better path is found
|
||||
if min_costs[neighbor_y][neighbor_x] > min_costs[current_y][current_x] + 1:
|
||||
node_parents[neighbor_y][neighbor_x] = (current_x, current_y)
|
||||
min_costs[neighbor_y][neighbor_x] = min_costs[current_y][current_x] + 1
|
||||
# Add node to priority queue with updated f = g + h value
|
||||
heapq.heappush(priority_queue, (min_costs[neighbor_y][neighbor_x] + hs[neighbor_y][neighbor_x], neighbor_x, neighbor_y))
|
||||
|
||||
# Repeat path execution to keep querying
|
||||
for i in range(len(path_to_current)):
|
||||
#print(f"m {path_to_current[i][0]} {path_to_current[i][1]}")
|
||||
for x in range(len(test_map_matrix)):
|
||||
for y in range(len(test_map_matrix)):
|
||||
if (x,y) in get_percepted_cells((current_x, current_y)) and test_map_matrix[x][y] != ".":
|
||||
astar_map[x][y] = test_map_matrix[x][y]
|
||||
|
||||
# Check if the goal is reached and output the result
|
||||
if min_costs[goal_y][goal_x] != 10000:
|
||||
print(f"e {min_costs[goal_y][goal_x]}") # Output shortest path length
|
||||
#time.sleep(1)
|
||||
passed_tests += 1
|
||||
test_number += 1
|
||||
end_time = time.time()
|
||||
test_time = end_time - start_time
|
||||
total_time += test_time
|
||||
else:
|
||||
print("e -1") # Output -1 if unsolvable.
|
||||
#time.sleep(1)
|
||||
failed_tests += 1
|
||||
test_number += 1
|
||||
end_time = time.time()
|
||||
test_time = end_time - start_time
|
||||
total_time += 0 # we don't consider failed tests in statistics
|
||||
|
||||
average_time = total_time / passed_tests
|
||||
|
||||
print("-------A_STAR_RESULTS-------")
|
||||
print(f"passed tests: {passed_tests}")
|
||||
print(f"failed tests: {failed_tests}")
|
||||
print(f"total time: {total_time}")
|
||||
print(f"average time: {average_time}")
|
||||
'''
|
||||
FOR 100 tests
|
||||
-------A_STAR_RESULTS-------
|
||||
passed tests: 99
|
||||
failed tests: 1
|
||||
total time: 18.093406677246094
|
||||
average time: 0.1827616836085464
|
||||
|
||||
|
||||
FOR 1000 tests
|
||||
-------A_STAR_RESULTS-------
|
||||
passed tests: 995
|
||||
failed tests: 5
|
||||
total time: 184.33025455474854
|
||||
average time: 0.1852565372409533
|
||||
'''
|
||||
@@ -0,0 +1,77 @@
|
||||
# Initialize global variables for the map grid and minimum distances
|
||||
grid_map = []
|
||||
min_distances = []
|
||||
|
||||
|
||||
|
||||
def observe(x, y):
|
||||
# Sends a move command and receives information on perceived cells around position (x, y)
|
||||
print(f"m {x} {y}")
|
||||
num_items = int(input()) # Number of items perceived in the vicinity
|
||||
for temp in range(num_items):
|
||||
# Process each perceived item with coordinates and type
|
||||
item_info = input().split()
|
||||
item_x, item_y, item_type = item_info[0], item_info[1], item_info[2]
|
||||
item_x = int(item_x)
|
||||
item_y = int(item_y)
|
||||
item_type = item_type[0]
|
||||
# Update the grid map with the perceived item at the given position
|
||||
grid_map[item_y][item_x] = item_type
|
||||
|
||||
def find_path(x, y):
|
||||
# Explore surroundings from the current position (x, y)
|
||||
observe(x, y)
|
||||
|
||||
# Try moving right if within bounds, the cell is safe, and the new distance is shorter
|
||||
if x + 1 < 9 and grid_map[y][x + 1] not in ('P', 'A', 'S') and min_distances[y][x + 1] > min_distances[y][x] + 1:
|
||||
min_distances[y][x + 1] = min_distances[y][x] + 1
|
||||
find_path(x + 1, y) # Recursive call to explore the new position
|
||||
|
||||
observe(x, y) # Explore again after returning
|
||||
|
||||
# Try moving left with similar conditions
|
||||
if x - 1 >= 0 and grid_map[y][x - 1] not in ('P', 'A', 'S') and min_distances[y][x - 1] > min_distances[y][x] + 1:
|
||||
min_distances[y][x - 1] = min_distances[y][x] + 1
|
||||
find_path(x - 1, y)
|
||||
|
||||
observe(x, y) # Explore again after returning
|
||||
|
||||
# Try moving down
|
||||
if y + 1 < 9 and grid_map[y + 1][x] not in ('P', 'A', 'S') and min_distances[y + 1][x] > min_distances[y][x] + 1:
|
||||
min_distances[y + 1][x] = min_distances[y][x] + 1
|
||||
find_path(x, y + 1)
|
||||
|
||||
observe(x, y) # Explore again after returning
|
||||
|
||||
# Try moving up
|
||||
if y - 1 >= 0 and grid_map[y - 1][x] not in ('P', 'A', 'S') and min_distances[y - 1][x] > min_distances[y][x] + 1:
|
||||
min_distances[y - 1][x] = min_distances[y][x] + 1
|
||||
find_path(x, y - 1)
|
||||
|
||||
observe(x, y) # Final exploration after checking all directions.
|
||||
|
||||
|
||||
# Create a 9x9 grid map filled with '.'
|
||||
grid_map = [['.' for temp in range(9)] for temp in range(9)]
|
||||
# Create a minimum distance grid with initial values set to "infinity" (10000)
|
||||
min_distances = [[10000 for temp in range(9)] for temp in range(9)]
|
||||
|
||||
# Read perception variant
|
||||
variant = int(input())
|
||||
# Read Keymaker's position
|
||||
position_input = input().split()
|
||||
keymaker_x = int(position_input[0])
|
||||
keymaker_y = int(position_input[1])
|
||||
|
||||
# Set the starting position (0, 0) with a minimum distance of 0
|
||||
min_distances[0][0] = 0
|
||||
# Start the recursive pathfinding search from the starting position
|
||||
find_path(0, 0)
|
||||
|
||||
# Output the result based on the minimum distance to the Keymaker's position
|
||||
if min_distances[keymaker_y][keymaker_x] == 10000:
|
||||
print("e -1") # If no path is found, output -1
|
||||
else:
|
||||
print("e " + str(min_distances[keymaker_y][keymaker_x])) # Output the shortest path length
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
# Initialize global variables for the map grid and minimum distances
|
||||
import time
|
||||
|
||||
def get_percepted_cells(position:tuple):
|
||||
cells = []
|
||||
for x in range(position[0]- perception_radius, position[0] + perception_radius + 1):
|
||||
for y in range(position[1]- perception_radius, position[1] + perception_radius + 1):
|
||||
if (x,y) != position:
|
||||
cells.append((x,y))
|
||||
return cells
|
||||
|
||||
failed_tests = 0
|
||||
passed_tests = 0
|
||||
|
||||
total_time = 0
|
||||
average_time = 0
|
||||
|
||||
test_number = 0
|
||||
with open("20k_testset.txt", "r") as file:
|
||||
lines = file.readlines()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
line_number = 0
|
||||
while(test_number < 1000):
|
||||
#time.sleep(.5)
|
||||
start_time = time.time()
|
||||
current_test_lines = []
|
||||
for local_line_number in range(14):
|
||||
current_line = lines[line_number]
|
||||
current_test_lines.append(current_line)
|
||||
line_number += 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
grid_map = []
|
||||
min_distances = []
|
||||
|
||||
|
||||
def observe(x, y):
|
||||
# Sends a move command and receives information on perceived cells around position (x, y)
|
||||
#print(f"m {x} {y}")
|
||||
for x_temp in range(len(test_map_matrix)):
|
||||
for y_temp in range(len(test_map_matrix)):
|
||||
if (x_temp,y_temp) in get_percepted_cells((x, y)) and test_map_matrix[x_temp][y_temp] != ".":
|
||||
grid_map[x_temp][y_temp] = test_map_matrix[x_temp][y_temp]
|
||||
|
||||
def find_path(x, y):
|
||||
# Explore surroundings from the current position (x, y)
|
||||
observe(x, y)
|
||||
|
||||
# Try moving right if within bounds, the cell is safe, and the new distance is shorter
|
||||
if x + 1 < 9 and grid_map[y][x + 1] not in ('P', 'A', 'S') and min_distances[y][x + 1] > min_distances[y][x] + 1:
|
||||
min_distances[y][x + 1] = min_distances[y][x] + 1
|
||||
find_path(x + 1, y) # Recursive call to explore the new position
|
||||
|
||||
observe(x, y) # Explore again after returning
|
||||
|
||||
# Try moving left with similar conditions
|
||||
if x - 1 >= 0 and grid_map[y][x - 1] not in ('P', 'A', 'S') and min_distances[y][x - 1] > min_distances[y][x] + 1:
|
||||
min_distances[y][x - 1] = min_distances[y][x] + 1
|
||||
find_path(x - 1, y)
|
||||
|
||||
observe(x, y) # Explore again after returning
|
||||
|
||||
# Try moving down
|
||||
if y + 1 < 9 and grid_map[y + 1][x] not in ('P', 'A', 'S') and min_distances[y + 1][x] > min_distances[y][x] + 1:
|
||||
min_distances[y + 1][x] = min_distances[y][x] + 1
|
||||
find_path(x, y + 1)
|
||||
|
||||
observe(x, y) # Explore again after returning
|
||||
|
||||
# Try moving up
|
||||
if y - 1 >= 0 and grid_map[y - 1][x] not in ('P', 'A', 'S') and min_distances[y - 1][x] > min_distances[y][x] + 1:
|
||||
min_distances[y - 1][x] = min_distances[y][x] + 1
|
||||
find_path(x, y - 1)
|
||||
|
||||
observe(x, y) # Final exploration after checking all directions.
|
||||
|
||||
|
||||
|
||||
# Create a 9x9 grid map filled with '.'
|
||||
grid_map = [['.' for temp in range(9)] for temp in range(9)]
|
||||
# Create a minimum distance grid with initial values set to "infinity" (10000)
|
||||
min_distances = [[10000 for temp in range(9)] for temp in range(9)]
|
||||
|
||||
# Read perception variant
|
||||
perception_radius = int(current_test_lines[1][0])
|
||||
# Read Keymaker's position
|
||||
keymaker_x = int(current_test_lines[2][1])
|
||||
keymaker_y = int(current_test_lines[2][4])
|
||||
test_map_matrix = current_test_lines[3:12]
|
||||
# Set the starting position (0, 0) with a minimum distance of 0
|
||||
min_distances[0][0] = 0
|
||||
# Start the recursive pathfinding search from the starting position
|
||||
find_path(0, 0)
|
||||
|
||||
# Output the result based on the minimum distance to the Keymaker's position
|
||||
if min_distances[keymaker_y][keymaker_x] == 10000:
|
||||
print("e -1") # If no path is found, output -1
|
||||
time.sleep(1)
|
||||
failed_tests += 1
|
||||
test_number += 1
|
||||
end_time = time.time()
|
||||
test_time = end_time - start_time
|
||||
total_time += 0 # we don't consider failed tests in statistics
|
||||
|
||||
else:
|
||||
print("e " + str(min_distances[keymaker_y][keymaker_x])) # Output the shortest path length
|
||||
time.sleep(1)
|
||||
passed_tests += 1
|
||||
test_number += 1
|
||||
end_time = time.time()
|
||||
test_time = end_time - start_time
|
||||
total_time += test_time
|
||||
|
||||
average_time = total_time / passed_tests
|
||||
|
||||
print("-------BACKTRACKING_RESULTS-------")
|
||||
print(f"passed tests: {passed_tests}")
|
||||
print(f"failed tests: {failed_tests}")
|
||||
print(f"total time: {total_time}")
|
||||
print(f"average time: {average_time}")
|
||||
|
||||
'''
|
||||
FOR 100 tests
|
||||
-------BACKTRACKING_RESULTS-------
|
||||
passed tests: 99
|
||||
failed tests: 1
|
||||
total time: 156.93781638145447
|
||||
average time: 1.58523046849954
|
||||
'''
|
||||
Reference in New Issue
Block a user