Add maze.py with functions to plant and solve mazes
This commit is contained in:
95
maze.py
Normal file
95
maze.py
Normal file
@@ -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()
|
||||
Reference in New Issue
Block a user