Self-Avoiding Walker navigating through RGB space

The two components I decided to choose were to make a self-avoiding walker and have it navigate through an RGB space. The program is below:

The code for my program can be found on my GitHub here. EDIT: I really quickly added a reset function so you don’t need to constantly refresh the page to restart the walker.

Essentially, the program creates an invisible grid for the walker to travel on and then checks what adjacent points have been unvisited. It will then randomly choose one of the valid directions and travels there. The points are colored and are made so the RGB values are mapped based on the current coordinates of the walker. Red is mapped to x, and green is mapped to y. Blue is simply given a random value from 0-255 since the space is only two-dimensional. The program will continue until the walker gets stuck, meaning there are no unvisited nodes adjacent to it that can be visited. The code is a heavily modified version of the barebones walker we used in class.

Originally, it was going to be much closer to what the original walker code was like, but I opted to use the grid because I thought it would be much easier to track the coordinates that have been visited. Also, the original walker is small and hard to see, so I decided to use a more visually appealing and visible pathing. When I first tried to tackle the checking adjacent points problem, the code I had was using the original random 1-4 picker, and keeping the walker in a while loop if the chosen coordinate was within an array of coordinates to avoid. However, this was really inefficient, since the walker would have to iterate through an array of coordinates that go progressively larger over time every time it tried to move, and it made the program slow down if the program was able to go long enough.  After doing some research into other walker programs, I realized there was a much easier way to do the checking. This is how I came to develop the grid instead. Each coordinate in the array is given a value of false, which is then changed to true if the walker chooses that coordinate. You can then have a simple function that will return the boolean value of the coordinates adjacent to the walker.

//checks to make sure the point is unvisited and in bounds
function isValid(i, j) {
  if (i < 0 || i >= cols || j < 0 || j >= rows) {
    return false;
  }
  return !grid[i][j];
}

 

If there are visited nodes adjacent to the walker, it will not add it to the array of options it will randomly choose from to make its next move.

//all adjacent points on grid
let allOptions = [
  { dx: 1, dy: 0 },
  { dx: -1, dy: 0 },
  { dx: 0, dy: 1 },
  { dx: 0, dy: -1 },
];

...

let options = [];
    for (let option of allOptions) {
      let newX = this.x + option.dx;
      let newY = this.y + option.dy;
      if (isValid(newX, newY)) {
        options.push(option);
      }
    }
    //chose a random direction to move in
    if (options.length > 0) {
      let step = random(options);
...

    } else {
      //ends program if theres nowhere to go
      console.log(`I'm stuck!`);
      this.stuck = true;
    }

Honestly, there was a lot more I wanted to do with this program that I did not get to achieve. The main issue stemmed from the fact that during the development process of my program. I made a mistake debugging a loop, which caused the IDE to get stuck and crash the page. In a stroke of genius, I had completely forgotten to save the program I was writing at any point, meaning I had lost all the code I had done, and I was now back to square one. This severely demotivated me for a while and I did not try to tackle the program again until the end of the weekend.

Another aspect of this program I intended to develop was making the walker not get stuck. It annoyed me how quickly the walker usually got itself stuck. It made it hard to see the color changes at times when the walker was occupying about 10% of the grid. Had I given myself more time after my entire program ceased to exist I probably would’ve figured out how to make this work, but unfortunately, I was unable to do so.

Originally, I had also intended to make this program a 3D self-avoiding walker that would navigate through an RGB space, because it meant I could map the z coordinate to blue. I had found some programs that would allow me to do this, but I had a hard time understanding the code and was doing a lot of trial-and-error to really understand what each part of the program was doing and how I could translate it into code of my own. I just decided to go with 2D instead because it was easier to understand, code, and debug. I think I want to try to tackle this again at some point in the future because the walker looked really nice and it would be a good opportunity to work with processing in three dimensions rather than two.

 

EDIT 9/4: After completing the two-dimensional program, I went back to attempt the three-dimensional walk again, and I managed to do so. The link to it can be found here.

The program is functionally similar to the two-dimensional program, there were extra parts that had to be added in order to make the program work in three dimensions. Also, I added some buttons that could be interacted with so that there are some options for the user to play around with. The main difference is in how the program renders the 3D path, where there is an array storing each coordinate point the walker has visited, and renders lines between each point. This means the program has to iterate through the entire array every time to render it, which does lag the program when the path gets very large. There is also a function that tries to center the camera around the path and will shift when it reaches a new min/max to account for this. You can also use the mouse to move the camera, lmb to rotate, rmb to pan, and scroll to zoom.

 

Leave a Reply

Your email address will not be published. Required fields are marked *