diff --git a/maze.py b/maze.py new file mode 100644 index 0000000..c1225c1 --- /dev/null +++ b/maze.py @@ -0,0 +1,95 @@ +import utils +from __builtins__ import * + +# Plant a full maze. +# +# Parameters: +# dimensions (tuple): The dimensions of the maze. If not set, default to the maximum size. +def place(dimensions=None): + if dimensions == None: + dimensions = get_world_size() + + plant(Entities.Bush) + substance = dimensions * 2**(num_unlocked(Unlocks.Mazes) - 1) + use_item(Items.Weird_Substance, substance) + +def solve(dimensions=None): + if dimensions == None: + dimensions = get_world_size() + + grid_size = get_world_size() + + directions = [North, East, South, West] + left_of = {North: West, West: South, South: East, East: North} + right_of = {North: East, East: South, South: West, West: North} + back_of = {North: South, South: North, East: West, West: East} + + def next_pos(x, y, direction): + if direction == North: + return x, (y + 1) % grid_size + if direction == South: + return x, (y - 1) % grid_size + if direction == East: + return (x + 1) % grid_size, y + return (x - 1) % grid_size, y + + def direction_between(x, y, nx, ny): + if (x + 1) % grid_size == nx and y == ny: + return East + if (x - 1) % grid_size == nx and y == ny: + return West + if x == nx and (y + 1) % grid_size == ny: + return North + return South + + visited = [] + x = get_pos_x() + y = get_pos_y() + visited.append([x, y]) + + def is_visited(vx, vy): + for i in range(len(visited)): + if visited[i][0] == vx and visited[i][1] == vy: + return True + return False + + stack = [[x, y, 0]] + + while len(stack) > 0: + current = stack[-1] + x = current[0] + y = current[1] + next_dir_index = current[2] + + if get_entity_type() == Entities.Treasure and can_harvest(): + harvest() + return + + moved = False + while next_dir_index < len(directions): + direction = directions[next_dir_index] + stack[-1][2] = next_dir_index + 1 + if can_move(direction): + next_xy = next_pos(x, y, direction) + nx = next_xy[0] + ny = next_xy[1] + if not is_visited(nx, ny): + move(direction) + visited.append([nx, ny]) + stack.append([nx, ny, 0]) + moved = True + break + next_dir_index = stack[-1][2] + + if moved: + continue + + if len(stack) == 1: + return + + prev = stack[-2] + prev_x = prev[0] + prev_y = prev[1] + back_dir = direction_between(x, y, prev_x, prev_y) + move(back_dir) + stack.pop()