Decided to convert my sketch to Python Mode too: ![]()
“Self_Avoiding_Walk_II.pyde”:
"""
* Self Avoiding Walk II [with Backtracking]
* Coding Challenge #162
* by The Coding Train / Daniel Shiffman
*
* https://TheCodingTrain.com/CodingChallenges/162-self-avoiding-walk.html
*
* Python Mode conversion by GoToLoop (2022/Feb/22) (v1.0.5)
*
* https://Discourse.Processing.org/t/
* converting-coding-challenge-self-avoiding-walk-backtracing-
* from-p5-js-to-processing-java/35047/15
*
* OpenProcessing.org/sketch/1475931
"""
from functions import *
removals = 0
def setup():
size(650, 500)
noFill()
createGrid()
states[BG] = randomColor()
def draw():
if states[FINISHED]: return
states[REMOVED] and removeTailSpotIfTooOld()
states[REMOVED] or getNextSpot()
global removals
removals += states[REMOVED] and 1 or -removals
removals == Spot.MAX_STRAIGHT_REMOVALS and resetAllSpotsAgesFromPath()
drawGridPath()
drawTrailPoint()
def mousePressed():
if mouseButton == LEFT:
states[PAUSED] ^= True
noLoop() if states[PAUSED] else loop()
elif mouseButton == RIGHT: states[BG] = randomColor()
elif mouseButton == CENTER: createGrid()
else: saveFrame()
def randomColor(): return int(random(Spot.ALL_COLORS))
“functions.py”:
from spot import Spot
REMOVED, PAUSED, FINISHED, BG = 'removed', 'paused', 'finished', 'bg'
states = { REMOVED: False, PAUSED: False, FINISHED: False, BG: 0 }
path = []
def createGrid():
rows = height // Spot.SPACING
cols = width // Spot.SPACING
global grid, spot, path, matrix
matrix = rows * cols
states[FINISHED] = states[REMOVED] = False
grid = tuple(tuple(Spot(r, c) for c in range(cols)) for r in range(rows))
spot = grid[rows >> 1][cols >> 1]
spot.visited = True
path *= 0
path.append(spot)
def resetAllSpotsAgesFromPath():
for spot in path: spot.age = frameCount
def removeTailSpotIfTooOld():
states[REMOVED] = frameCount - spot.age >= Spot.AGE_THRESHOLD
if states[REMOVED]: removeTailSpotFromPath(); rejuvenateAllSpotsFromPath()
def removeTailSpotFromPath():
states[REMOVED] = len(path) >= 2
states[REMOVED] and path.pop().clear()
global spot
spot = path[-1]
def rejuvenateAllSpotsFromPath():
size = len(path) - 1
if not size: return
for i in range(size + 1):
path[i].age += round(map(i, 0, size, 1, Spot.AGE_INCREASE))
def getNextSpot(DONE = 'Solved!'):
global spot
spot = spot.nextSpot(grid)
if spot:
path.append(spot)
spot.visited = True
states[REMOVED] = False
else: removeTailSpotFromPath();
if len(path) == matrix:
print DONE
states[FINISHED] = True
def drawGridPath():
background(states[BG])
translate(Spot.HALF_SPACE, Spot.HALF_SPACE)
strokeWeight(Spot.QUARTER_SPACE)
stroke(Spot.PATH_STROKE)
with beginShape():
for spot in path: vertex(spot.x, spot.y)
def drawTrailPoint():
strokeWeight(Spot.HALF_SPACE)
stroke(Spot.TRAIL_STROKE)
point(spot.x, spot.y)
“spot.py”:
from step import Step
class Spot:
AGE_THRESHOLD = 200
AGE_INCREASE = 5
MAX_STRAIGHT_REMOVALS = 200
SPACING = 10
HALF_SPACE = SPACING * .5
QUARTER_SPACE = SPACING * .25
PATH_STROKE = -1
TRAIL_STROKE = 0xffFFA000
ALL_COLORS = (0xff << 0o30) - (1 << 0o40)
def __init__(s, row, col):
s.x = col * s.SPACING
s.y = row * s.SPACING
s.c = col
s.r = row
s.visited = False
s.age = frameCount
s.options = Step.allDirections()
def clear(s):
for step in s.options: step.tried = False
s.visited = False
s.age = frameCount
return s
def nextSpot(s, grid, dirs = []):
rr = len(grid)
cc = len(grid[0])
valid = Step.isValid2
dirs *= 0
for step in s.options:
r = s.r + step.y
c = s.c + step.x
not step.tried and valid(grid, r, c, rr, cc) and dirs.append(step)
size = len(dirs)
if not size: return
step = dirs[int(random(size))]
step.tried = True
return grid[s.r + step.y][s.c + step.x]
“step.py”:
class Step:
def __init__(s, x, y):
s.x = x
s.y = y
s.tried = False
@staticmethod
def allDirections():
return Step(1, 0), Step(-1, 0), Step(0, 1), Step(0, -1)
@staticmethod
def isValid(grid, r, c):
return\
0 <= r < len(grid) and\
0 <= c < len(grid[r]) and\
not grid[r][c].visited
@staticmethod
def isValid2(grid, r, c, rows, cols):
return 0 <= r < rows and 0 <= c < cols and not grid[r][c].visited