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

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

And I borrowed your code

 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 :joy: it definately has other problems :joy:

// 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;
  }
}