# Converting coding challenge 'Self-avoiding walk backtracing' from p5.js to Processing (Java)

**URL:** https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047
**Category:** Coding Questions
**Created:** [February 8, 2022, 7:34pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047 "2022-02-08T19:34:23Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![psamead](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@psamead](https://discourse.processing.org/u/psamead)
#### Post date: [February 8, 2022, 7:34pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/1 "2022-02-08T19:34:23Z")

</div>

Hi my friends,  
I am trying to learn coding challenge Self-avoiding walk backtracing from [Denial’s video](https://www.youtube.com/watch?v=m6-cm6GZ1iw) 26:40 ; And converting the P5.js code to processing(java) code. But my code seems it is struggling on getting the array right and null pointer. Can anyone help me to figure out the problem?

```auto
Step[] allOptions = 
{
  new Step(1, 0), new Step(-1, 0), new Step(0, 1), new Step(0, -1)
};

Spot spot;

ArrayList<Spot> path = new ArrayList<Spot>();

Spot[][] grid;
int spacing = 20;
int cols, rows;

boolean isValid(int i, int j)
{
  if(i < 0 || i >= cols || j < 0 || j >= rows)
  {
    return false;
  }
  return !grid[i][j].visited;
}

void setup()
{
  size(400, 400);
  cols = floor(width / spacing)+1;
  rows = floor(height / spacing)+1;
  background(0);
  
  grid = new Spot[cols][rows];
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      grid[i][j] = new Spot(i, j);
    }
  }
  spot = grid[0][0];
  path.add(spot);
  spot.visited = true;
}

void draw()
{

  spot = spot.nextSpot();
  if(spot == null)
  {
    ArrayList<Spot> stuck = new ArrayList<Spot>();
    for(int i = path.size()-1; i >= 0; i--)
    {
      path.remove(i);
    }
    
    for(Spot sp: path)
    {
      stuck.add(sp);
    }
    stuck.clear();
    
    for(int i = path.size()-1; i >= 0; i--)
    {
      spot = path.get(i);
    }
  }
  else
  {
    path.add(spot);
    spot.visited = true;
  }
  
  if(path.size() == cols*rows)
  {
    println("Solved!");
    noLoop();
  }
  
  stroke(250, 0, 160);
  strokeWeight(spacing*0.25);
  noFill();
  beginShape();
  for(int i = 0; i < path.size(); i++)
  {
    vertex(path.get(i).x, path.get(i).y);
  }
  endShape();
  
  stroke(250, 160, 0);
  strokeWeight(spacing * 0.5);
  point(spot.x, spot.y);

}

class Spot
{
  int x, y;
  int i, j;
  boolean visited;
  Step[] options;
  
  
  Spot(int _i, int _j)
  {
    i = _i;
    j = _j;
    x = i * spacing;
    y = j * spacing;
    options = new Step[allOptions.length];
    for(int i = 0; i < options.length; i++)
    {
      options[i] = allOptions[i];
    }
    visited = false;
  }

  void Clear()
  {
    visited = false;
    for(int i = 0; i < options.length; i++)
    {
      options[i] = allOptions[i];
    }
  }
  
   Spot nextSpot()
  {
    ArrayList<Step> validOptions = new ArrayList<Step>(); 
    for(Step option: options)
    {
      int newX = i + option.dx;
      int newY = j + option.dy;
      if(isValid(newX, newY) && !option.tried)
      {
        validOptions.add(option);
      }
      println("newX: "+newX, "newY: "+newY);
    }
    println("valid options.size: " + validOptions.size());
    if(validOptions.size() > 0)
    {
      int index = int(random(validOptions.size()-1));
      Step step = validOptions.get(index);
      step.tried = true;
      return grid[i+step.dx][j+step.dy];
    }
    return null;
  }
}

class Step
{
  int dx, dy;
  boolean tried;
  
  Step(int x, int y)
  {
    dx = x;
    dy = y; 
    tried = false;
  }
}

```

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [February 8, 2022, 7:59pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/2 "2022-02-08T19:59:25Z")

</div>

> **[website/CodingChallenges/CC\_162\_self\_avoiding\_walk/backtracking at main ·...](https://github.com/CodingTrain/website/tree/main/CodingChallenges/CC_162_self_avoiding_walk/backtracking)**
>
> main/CodingChallenges/CC\_162\_self\_avoiding\_walk/backtracking

> **[p5.js Web Editor](https://editor.p5js.org/codingtrain/sketches/dRWS3A9nq)**
>
> A web editor for p5.js, a JavaScript library with the goal of making coding accessible to artists, designers, educators, and beginners.

---

<div class="post-metadata">

### Author: ![psamead](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@psamead](https://discourse.processing.org/u/psamead)
#### Post date: [February 8, 2022, 8:05pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/3 "2022-02-08T20:05:48Z")

</div>

Hi @GoToLoop ,  
Thanks for the reply!  
I have read the p5js version, but I can not figure out to convert it to processing code. I definately make some mistakes, but I can not figure them out. I wonder if someone can help to change it to processing java.

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [February 9, 2022, 5:23am UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/4 "2022-02-09T05:23:57Z")

</div>

> [@psamead](#):
>
> I definitely made some mistakes, but I cannot figure them out.

In the original p5js version _validOptions_ is a function which returns an array w/ 4 instances of Step:

> <https://github.com/CodingTrain/website-archive/blob/main/CodingChallenges/CC_162_self_avoiding_walk/backtracking/spot.js#L21-L23>

But in your converted Java Mode version it is just an array not a function:

> [@psamead](#):
>
> ```auto
> Step[] allOptions = {
> new Step(1, 0), new Step(-1, 0), new Step(0, 1), new Step(0, -1)
> };
> 
> ```

Also your attempt of emulating method Array::[**pop()**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop):

> <https://github.com/CodingTrain/website-archive/blob/main/CodingChallenges/CC_162_self_avoiding_walk/backtracking/sketch.js#L56-L61>

Using Java’s List::[**remove()**](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/List.html#remove(int)) mixing w/ loops doesn’t seem to be working.

BtW, I’ve ended up making my own conversion attempt and posted it online:

https://OpenProcessing.org/sketch/1475556/embed/

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [February 9, 2022, 11:02am UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/5 "2022-02-09T11:02:32Z")

</div>

Another version, this time named “Self Avoiding Walk II”, which implements a more aggressive backtracking based on the _age_ of each Spot inside container _path_, so it has a better chance to unstuck itself:

https://OpenProcessing.org/sketch/1475931/embed/"index.html": - ```

```auto

```

---

<div class="post-metadata">

### Author: ![psamead](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@psamead](https://discourse.processing.org/u/psamead)
#### Post date: [February 9, 2022, 7:19pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/6 "2022-02-09T19:19:55Z")

</div>

Hi @GoToLoop ,  
Thanks for your replay and help.  
Your code is absolutely so much help and it is incrediable. And the openprocessing web editor is brilliant and it can declare static method with in, my current process IDE can not, except adding .java files.  
I don’t know much about javascript and am quite newbie, so as you point out my code drops some important idea of the original code on the conversion.  
With your advice and help, I figure out my problem

> [@GoToLoop](#):
>
> In the original p5js version _validOptions_ is a function which returns an array w/ 4 instances of Step:
> 
> [website-archive/CodingChallenges/CC\_162\_self\_avoiding\_walk/backtracking/spot.js at main · CodingTrain/website-archive · GitHub](https://github.com/CodingTrain/website/blob/main/CodingChallenges/CC_162_self_avoiding_walk/backtracking/spot.js#L21-L23)
> 
> But in your converted Java Mode version it is just an array not a function:
> 
> > [@psamead](#):
> >
> > ````auto
> > > Step[] allOptions = {
> > new Step(1, 0), new Step(-1, 0), new Step(0, 1), new Step(0, -1)
> > };
> > > ```
> > 
> > ````

And I borrowed your code

```auto
 static final Step[] allDirections() {
    return new Step[] {
      new Step(1, 0), new Step(-1, 0), new Step(0, 1), new Step(0, -1)
    };
  }

```

My one is finally working, but it seems it will be stuck at some point quite long 😂 it definately has other problems 😂

```auto
// Self Avoiding Walk (Basic)
// The Coding Train / Daniel Shiffman
// https://thecodingtrain.com/CodingChallenges/162-self-avoiding-walk.html
// https://www.youtube.com/watch?v=m6-cm6GZ1iw

// Basic: https://editor.p5js.org/codingtrain/sketches/2_4gyDD_9
// With Backtracking: https://editor.p5js.org/codingtrain/sketches/dRWS3A9nq
// 3D: https://editor.p5js.org/codingtrain/sketches/D0ONOlCDT
// With Bezier: https://editor.p5js.org/codingtrain/sketches/KFbX0NWgh
// With Recursion: https://editor.p5js.org/codingtrain/sketches/UPxBk1YiB
// Random Walk with Alpha: https://editor.p5js.org/codingtrain/sketches/IEw2RkDnJ

Spot[][] grid;
int spacing = 40;
ArrayList<Spot> path = new ArrayList<Spot>();
int cols, rows;
Spot spot;

boolean isValid(int i, int j)
{
  if(i < 0 || i >= cols || j < 0 || j >= rows)
  {
    return false;
  }
  else
  {
    return !grid[i][j].visited;
  }
}

void setup()
{
  size(400, 400);
  cols = floor(width / spacing)+1;
  rows = floor(height / spacing)+1;
  background(0);
  //frameRate(1);
  
  grid = new Spot[cols][rows];
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      grid[i][j] = new Spot(i, j);
    }
  }
  spot = grid[0][0];
  path.add(spot);
  spot.visited = true;
}

void draw()
{
  background(0);
  
  for(int i = 0; i < 5000; i++)
  {
    spot = spot.nextSpot();
    if(spot == null)
    {
      int len = path.size();
      path.remove(len-1).Clear();
      println("N_Path size: " + path.size());
      
      spot = path.get(len-2);
    }
    else
    {
      path.add(spot);
      spot.visited = true;
      println("Path size: "+path.size());
    }
    
    if(path.size() == cols*rows)
    {
      println("Solved!");
      noLoop();
      break;
    }
  }
  
  stroke(250, 0, 160);
  strokeWeight(spacing*0.25);
  noFill();
  beginShape();
  for(Spot sp: path)
  {
    vertex(sp.x, sp.y);
  }
  endShape();
  
  stroke(250, 160, 0);
  strokeWeight(spacing * 0.5);
  point(spot.x, spot.y);
}

Step[] allOptions()
{
  return new Step[] {new Step(1,0), new Step(0,1), new Step(0,1), new Step(0,-1)};
}

class Spot
{
  int x, y;
  int i, j;
  boolean visited;
  Step[] options = new Step[4];
  
  
  Spot(int _i, int _j)
  {
    i = _i;
    j = _j;
    x = i * spacing;
    y = j * spacing;
    options = allOptions();
    printArray(options);
    visited = false;
  }

  void Clear()
  {
    for(Step sp: options)
    {
      sp.tried = false;
    }
    visited = false;
  }
  
   Spot nextSpot()
  {
    ArrayList<Step> validOptions = new ArrayList<Step>(); 
    for(Step option: options)
    {
      int newX = i + option.dx;
      int newY = j + option.dy;
      if(isValid(newX, newY) && !option.tried)
      {
        validOptions.add(option);
        //println("validoptions.size: " + validOptions.size());
      }
      println("newX: "+newX, "newY: "+newY);
    }
    println("validoptions.size: " + validOptions.size());
    if(validOptions.size() > 0)
    {
      int index = int(random(validOptions.size()-1));
      Step step = validOptions.get(index);
      println("index: " + index);
      println("valid options.size: " + validOptions.size());
      step.tried = true;
      return grid[i+step.dx][j+step.dy];
    }
    else
    {
      println("F_validoptions.size: " + validOptions.size());
      return null;
    }
  }
}

class Step
{
  int dx, dy;
  boolean tried;
  
  Step(int x, int y)
  {
    dx = x;
    dy = y; 
    tried = false;
  }
}

```

---

<div class="post-metadata">

### Author: ![psamead](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@psamead](https://discourse.processing.org/u/psamead)
#### Post date: [February 9, 2022, 7:26pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/7 "2022-02-09T19:26:02Z")

</div>

```auto
 path.add(spot = grid[rows >> 1][cols >> 1]);

```

> rows \>\> 1

> cols \>\> 1

btw what does this kind of expression mean?

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [February 9, 2022, 7:34pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/8 "2022-02-09T19:34:30Z")

</div>

> [@psamead](#):
>
> BtW, what does this kind of expression mean?

The bitwise right shift operator moves all bits of a value ‘x’ times:

> **[\>\> (right shift) / Reference](https://processing.org/reference/rightshift.html)**
>
> Shifts bits to the right. The number to the left of the operator is shifted the number of places specified by the number to the right. Each shift to the right halves the number, therefore each right s…

Each right shifting halves the value; so `>> 1` is equivalent to `/ 2`, `>> 2` is `/ 4`, and so on.

The advantage of using the operator `>>` in place of `/` is that the former guarantees the result is always a whole number (truncated division) when the code is transpiled to run on the web from Java ([Processing library](https://processing.org/reference/)) to JS ([Pjs library](https://gotoloop.github.io/processing-js.github.io/reference/)).

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [February 9, 2022, 7:58pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/9 "2022-02-09T19:58:21Z")

</div>

> [@psamead](#):
>
> And the [OpenProcessing.org](http://OpenProcessing.org) web editor is brilliant and it can declare `static` methods within; my current Processing IDE cannot, except by adding _.java_ files.

I’ve coded everything in Processing IDE (PDE) version 3.5.4.

So if you click the download icon from my online sketch and transfer those files to the offline PDE it should just run.

Inside “.pde” files all classes we create are nested.

In order to have `static` methods inside a nested class its class has to be declared `static` as well.

On the other hand, top-level classes inside “.java” files are naturally `static` already.

---

<div class="post-metadata">

### Author: ![psamead](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@psamead](https://discourse.processing.org/u/psamead)
#### Post date: [February 10, 2022, 5:25pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/10 "2022-02-10T17:25:06Z")

</div>

Thanks for the reference link, much appreciated

---

<div class="post-metadata">

### Author: ![psamead](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@psamead](https://discourse.processing.org/u/psamead)
#### Post date: [February 10, 2022, 5:32pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/11 "2022-02-10T17:32:28Z")

</div>

sorry my mistake, I should say mix use of the static and non-static in the same class 😂 thanks for this

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [February 10, 2022, 8:16pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/12 "2022-02-10T20:16:35Z")

</div>

I got a question.

I understand that the backtracking algorithm is recursive.

In Java processing a recursive function wouldn’t update the screen throughout. How come it is updated here?

Is it that you can update the screen throughout in p5 or is it just not really recursive?

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [February 10, 2022, 9:03pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/13 "2022-02-10T21:03:52Z")

</div>

> [@Chrisir](#):
>
> I understand that the backtracking algorithm is recursive.

The approach taken by Daniel Shiffman in his Coding Challenge #162 YouTube video isn’t recursive.

In my 1st version of it (“Self Avoiding Walk I”), the main algorithm happens here:

```auto
void getNextSpot() {
  spot = spot.nextSpot(grid);

  if (spot != null) {
    path.add(spot);
    spot.visited = true;
  } else {
    final int len = path.size();
    path.remove(len - 1).clear();
    spot = path.get(len - 2);
  }

  if (path.size() == matrix) {
    println("Solved!");
    finished = true;
  }
}

```

As you can see, function **getNextSpot()** never calls itself as we woulda expected from a recursive 1.

The way it works is like a stack, pushing & popping from the container’s tail index:

- Method Spot::**nextSpot()** attempts to find a valid non-_visited_ Spot from within array _grid[][]_.
- If successful, that found Spot is **add()** to _path_’s tail; and its Spot::_visited_ state becomes `true`.
- Otherwise, the previous Spot is **remove()** from _path_’s tail and its state is reset by calling method Spot::**clear()**; and then variable _spot_ is updated to point to the now current Spot tail:

```java
  Spot clear() {
    for (final Step step : options) step.tried = false;
    visited = false;
    return this;
  }

```

> [@Chrisir](#):
>
> Is it that you can update the screen throughout in p5…

I believe callback **draw()** needs to finish before p5js sketch’s canvas is updated.

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [February 21, 2022, 4:02pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/14 "2022-02-21T16:02:44Z")

</div>

Thank you so much for this good explanation!

😉

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [February 22, 2022, 1:48pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/15 "2022-02-22T13:48:48Z")

</div>

Decided to convert my sketch to Python Mode too: 🐍

## “Self\_Avoiding\_Walk\_II.pyde”:

```auto
"""
 * 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”:

```auto
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”:

```auto
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”:

```auto
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

```

---

<div class="post-metadata">

### Author: ![psamead](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@psamead](https://discourse.processing.org/u/psamead)
#### Post date: [February 22, 2022, 4:28pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/16 "2022-02-22T16:28:36Z")

</div>

This is brilliant !!!

---

<div class="post-metadata">

### Author: ![psamead](https://avatars.discourse-cdn.com/v4/letter/p/2bfe46/32.png) [@psamead](https://discourse.processing.org/u/psamead)
#### Post date: [March 3, 2022, 5:25pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/17 "2022-03-03T17:25:16Z")

</div>

Hi @GoToLoop

I wonder if this one

> removals += removed? 1 : -removals;

is equivalent

> if (removed) { removals += 1;}  
> else { removals -= 1; }

---

<div class="post-metadata">

### Author: ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)
#### Post date: [March 3, 2022, 5:28pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/18 "2022-03-03T17:28:58Z")

</div>

> [@psamead](#):
>
> removed? 1 : -removals;

you can test it yourself.

My guess

```auto
if (removed) { 
   removals += 1;
}
else { 
  removals += -removals; // which is 0 I guess
 }

```

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [March 10, 2022, 12:57am UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/19 "2022-03-10T00:57:21Z")

</div>

- I’m back w/ another “Self Avoiding Walk II” conversion.
- This time I’m using the [CoffeeScript](https://coffeescript.org/) language which directly transpiles to JavaScript.
- Processing 2 used to have a [CoffeeScript Mode](https://github.com/fjenett/coffeescript-mode-processing) a long time ago and I’ve ended up learning it.
- When I later decided to learn [Python Mode](https://py.processing.org/reference/) to help folks here I’ve relied on my previous [CoffeeScript](https://coffeescript.org/) knowledge b/c they have similar syntax.
- The old [CoffeeScript Mode](https://github.com/fjenett/coffeescript-mode-processing) relied on the [Pjs](https://gotoloop.github.io/processing-js.github.io/reference/) library in order to run its transpiled sketch on the web.
- Which by the way is the same lib that transpiles a [Java Mode](https://processing.org/reference/) sketch to JS.
- But I also wanted to use [p5js](https://p5js.org/reference/) & even [q5js](https://q5xjs.netlify.app/) to run my latest conversion.
- So why not make the new [CoffeeScript](https://coffeescript.org/) sketch compatible w/ all those 3 libraries?
- That’s exactly what I did! Each time the sketch is refreshed it randomly picks 1 of the 3 libs:

https://glitch.com/embed/#!/self-avoiding-walk-ii-coffeescript?path=app/sketch.coffee&previewSize=0&sidebarCollapsed=true

[Click here](https://api.glitch.com/project/download/?projectId=f19e91c7-6e32-4fed-9e54-6d2cff00e48b&authorization=05ff34d2-6010-454a-9fd0-143b25304ae9) to download the full app project.  
Also go to link below to view it fullscreen:

- [https://Self-Avoiding-Walk-II-CoffeeScript.Glitch.me](https://Self-Avoiding-Walk-II-CoffeeScript.Glitch.me)

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [March 23, 2022, 5:54pm UTC](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047/20 "2022-03-23T17:54:06Z")

</div>

Well I couldn’t stop! I’ve found out a new language, RapydScript:

> **[GitHub - atsepkov/RapydScript: Python-inspired, decluttered JavaScript](https://github.com/atsepkov/RapydScript)**
>
> Python-inspired, decluttered JavaScript. Contribute to atsepkov/RapydScript development by creating an account on GitHub.

In the same vein as [CoffeeScript](https://CoffeeScript.org) is inspired by [Ruby](https://en.wikipedia.org/wiki/Ruby_(programming_language)), RapydScript is inspired by [Python](https://en.wikipedia.org/wiki/Python_(programming_language)).

It’s the same “Self Avoiding Walk II” CoffeeScript multi-flavor sketch, but now converted to RapydScript:

https://glitch.com/embed/#!/self-avoiding-walk-ii-rapydscript?path=app/sketch.pyj&previewSize=0&sidebarCollapsed=true

You can [click here](https://api.glitch.com/project/download/?projectId=2c9564d4-7f1d-48c1-84e3-4d97bdf582f5&authorization=05ff34d2-6010-454a-9fd0-143b25304ae9) to download the full sketch so you can edit & run it somewhere else.  
And go to link below to view it fullscreen:

- [https://Self-Avoiding-Walk-II-RapydScript.Glitch.me/](https://Self-Avoiding-Walk-II-RapydScript.Glitch.me/)

[Next page](https://discourse.processing.org/t/converting-coding-challenge-self-avoiding-walk-backtracing-from-p5-js-to-processing-java/35047.md?page=2)
