Coding Assignment – Week 1

Random Walker through RGB Space

My approach for this assignment was very simple. I decided to simply create the random walker like we did earlier in class and give it a 50% chance of moving towards the mouse pointer, at the times where it was not moving towards the pointer, I assigned it a random movement through the RGB space. 

While my code was mostly based on the random Walker we had already worked on in class, the section with the movement within the RGB space was something I explored and was glad I was able to accomplish. 

Below is a snippet of that section: 

else {
      // Random walker changing color in RGB
      let choice = floor(random(3)); // 0 for R, 1 for G, 2 for B

      //changing color components with =in respective range
      if (choice === 0) {
        this.r = (this.r + random(-5, 5)) % 255;
      } else if (choice === 1) {
        this.g = (this.g + random(-5, 5)) % 255;
      } else {
        this.b = (this.b + random(-5, 5)) % 255;
      }

As shown above this was part of my if statement that determined the movement of the Walker. If the Walker did not move towards the mouse, that is, the randomly generated value was less than the probability, then the color of the random Walker would change. In this case I decided to make the change specific to every color component. I created assigned a random number from 0-3 to the variable choice and from there I created nested if statements that were responsible from changing the RGB color components accordingly. I created a range for change between (-5, 5) to ensure that the respective components do not change drastically allowing for a smooth look in the color transformations. 

Challenges: 

The main challenge I faced was in terms of having the Walker move at first. I had all the elements of the code according the example we did in class but it turned out that I was failing to update the value of the coordinates of the direction which would result in my Walker staying still on the page. Once I added the lines that incremented the value of the coordinates I eliminated the issue in hand. I also added the p5js embedded ‘normalize’ function to the direction vector this way I was able to scale the vectors length to 1 while preserving its direction. This prevented a scattered display of the walker but rather a uniform continuous line. 

Reflection and Ideas:

When working on this assignment I was unsure of whether or not I was meeting the exact guidelines of creating a random walker with dynamic probabilities, while also having it walk through the RGB space, however I attempted to work on it to the best of my abilities. For the future I would want to experiment with ways that could combine both prompts together rather than having them in an if statement. This was not something I was able to accomplish as I have not yet grappled the concept of moving through RGB or HSB spaces, but I believe it is certainly possible to accomplish both prompts simultaneously and I plan on hopefully returning to update this code using a different approach. 

Below is the editor link for reference:

https://editor.p5js.org/dhabialhosani/sketches/08pvhUyNH

Reading Response – Week 1

In “The Computational Beauty of nature” Gary Flake explores the various methods used to understand the universe and the inherent attributes that are always present in nature. Flake highlights the importance of considering different approaches to study the same topic as each approach can result in a different outcome. Flake’s example of studying ants using reductionism highlights how such an approach can strip away the intricate beauty of their colony systems. On the other hand, studying humans as groups takes away the individualistic essence of each person. This concept underscores the realization that many aspects of life remain imperfectly understood due to the universe’s intricate complexity.


This concept has made me realize how mimicking nature in programs can be done in many different ways depending on the task required. For instance, mimicking an ant colony system might require a holistic approach to capture its intricate beauty, while emulating individual human behaviors may necessitate a more nuanced focus. It is hard to understand how we should interpret each of these subjects because of the complexity of the universe knowing that some systems are parallel while others adapt and evolve due to their environment. So many things could be studied and mimicked using different approaches which could result in different outcomes.

Reading Response 1 – Ayush

As someone studying computer science, I find the concept of reductionism very intriguing. It’s similar to how we pursue the understanding of first principles in computing – breaking down complex problems into their fundamental components. This text demonstrates how various scientific disciplines, from biology to physics, follow a similar approach, dissecting the universe into smaller, more manageable parts. However, it also reminds us that, much like in computer science, merely understanding these building blocks isn’t enough. We must delve into the interactions and emergent properties that arise when these components come together, mirroring the complexity we often encounter in computational systems.

The part about fractals and chaos in this text reminded me of my past experiences. It’s like when I work with technologies that don’t always give the same results for the same inputs. A tiny change can make a big difference, just like chaos theory shows. Also, when the text talks about complex systems that learn and adapt, it’s a lot like what we do in machine learning and artificial intelligence. We teach computer programs to get better at tasks over time. So, this text reminds me that we should not just learn the basics; we should also explore how different parts work together, kind of like how scientists study the universe, from big bang to the multiverse.

Xiaozao Reading Reflection – Week#1

I really like the reading passage. It tells us about how different disciplines interact with each other and have shared underlying logic. The author mentioned two opposite theories, the reductionism and the holism. He said that these two theories won’t agree with each other because reductionism is about how we break down things in parts, and smaller parts, right to the quantum level, while holism is studying how simple things can form together into a more complex system. But from my perspective, these theories are not only contradictory but also complementary. When looking at something, we always look at it from “eye level”, which means we observe its appearance and try to get information about what it is naturally. Then we apply reductionism and break down its concepts. After that, we apply holism and analyze how it behaves in a larger context or environment. Finally we go back to the middle stage and will be able to get a clearer idea of not only “what it is”, but also “why it does this”. This is how we get to know every individual in the universe, and how we develop an interdisciplinary perspective.

There are many examples in life that prove the ideas of the author. For example, the clusters of galaxies in the field of astronomy are quite similar to neural networks in the field of neural science. And actually, the structure and logic of computers are inspired by the two. Many manmade things are bionic, meaning that they all got inspiration from the micro and macro world in nature. When we break them down, we will see similar basic patterns; and when we look from the macroscopic perspective, we will find they have similar behaviors under that respective context. As the author has mentioned, the invention of the computer brings all the subjects together and promotes communication between them. This is right because the computer simulators found out the similarity of structure and interaction type among them. Therefore, what we are doing in this class is very important to not only the application of computer programming, but also the discovery of nature theories.

Coding assignment – week 1

So for this week’s assignment I worked on 2 separate p5.js sketches. The first sketch is a progression on some of the generative code I created in class (sketch linked below).

https://editor.p5js.org/as13805/sketches/4bYDgmVvu

In the above sketch I built off of the randomness concepts we learnt in class to govern the movement of the walker’s in accordance to Perlin noise. In doing so, it provided smooth transitions between each new step the walker took. I also used the x and y coordinate values of the walker to control the dimensions of the walker (ellipse) and using the Perlin noise values of variable v to control the shade of the walker.

————————————————————

My second work (main assignment) is my attempt at creating a walker than follows Levy flight.

To my understanding, Levy Flight is a random walk where most often the walker takes many small steps in a small area but sometimes takes a much larger step of varying distance. Similar to how some animals forage for food, where they sniff continuously around one area and then suddenly move a long distance away to sniff a different area. They repeat this until satiated. Below are images of the phenomena from Wikipedia that I used to try to recreate.

In my p5.js sketch I also controlled the color of the walker using the randomness of the walker.

Below is the link to my p5.js sketch and the corresponding code.

https://editor.p5js.org/as13805/sketches/PVIa9w0zN

let chance = random(100);
  if (chance<2){
    direction.mult(random(25,100));
  }else{
    direction.setMag(4);
    stroke(this.pos.x,map(this.pos.y,0,600,0,255),chance);
  }

The code snippet above controls the randomness of the walker its erratic jumps. I believe this is the main part of my code.

Challenges:

I wanted to make a bigger spectacle using the perlin noise in this code but I did not know how to add it in time. Hopefully, if I start working on my next project earlier, I can take bigger creative decisions to make the code standout out more.

Inspiration:

I learnt a lot from this youtube video

Reading Response Week 1 – Omar ElGamal

For this reading, it covers some things that I am generally interested in like the emergence of properties in complex systems, and parallels between evolution and other seemingly unrelated processes. I liked the author’s use of examples to illustrate his point, like the simple concept of a deer evading prey to explain more complex phenomena of natural selection, and in general, I found that thinking of evolution in computational terms (describing it as a parallel system that has “fault tolerance” and reproduction being described as iteration and recursion) provides a helpful analogy.

From an IM & coding perspective, I think it’s an attractive idea that nature’s patterns are recurring, repeating, and simple, and definitely agree with this in some ways. Testing this idea by trying to mimic or simulate different natural phenomena using a set of small & simple rules sounds really fun and I believe the book as a whole can be very helpful in this regard. I’ve dreamt a lot of trying to make my own version of cellular automata and incorporating an evolutionary network but still keeping it relatively simple, just to see how far I can push it in terms of interesting emergent behaviors that might manifest.

On a slightly more unrelated point, the adaptation section piqued my interest the most, especially the bit about learning, evolution, and cultural adaptation being the same process on different time scales. I’ve watched a couple of lectures from developmental biologist Michael Levin (A really interesting one is Intelligence Beyond the Brain on Youtube), and in it, he proposes this idea that intelligence is more or less the same across different physical scales and that all intelligence is collective intelligence (since everything is made of parts). He talks about the similarities between types of intelligences that we often think of as vastly different or even completely overlook. Like how cells came together as separate individual intelligent agents and gave rise to multicellular intelligence able to solve more complex problems (emergence), and then how these multicellular intelligences can be organs (that can themselves be considered intelligent) that come together to make organisms that are able to solve & work towards more even complex goals (although at the most basic level, they seem to me more or less the same goals of reproduction, food prosperity, etc.. just on larger scales). Sometimes I like to theorise that any group of intelligent agents is eventually bound to come together and give rise to something more complex, and I think that humans are just going through their evolutional journey of figuring out how to connect, communicate and work together seamlessly (almost like cells do), to give rise to an agent that’s on a different plane of intelligence, capable of much more than we are able to imagine. I think we would need a real technological revolution in communication, but sometimes I feel like it’s almost inevitable. In the lecture I mentioned earlier Michael Levin points out how cells don’t know that they are part of a human they’re just doing their thing, and I think that even if they had some sort of awareness that they are part of a system or working within a larger group, the problems and aspects of human life are simply incomprehensible to a single cell because they exist on a different scale. So, maybe we already are part of an intelligent agent and we just don’t know it, an agent that exists in a realm beyond our comprehension or understanding.

Reading Response – Week #1

The author says, “Reductionism fails when we try to use it in the opposite direction.” I do not completely agree with this statement. From what I understand, reductionism is breaking down a complex system into smaller parts, until it cannot be broken down further, and studying the system at this core level. This gives us a lot of information on how the individual elements of a system work, but this is not the final step. The ultimate goal is to understand the system itself. That can only happen if, after reductionism, we let ourselves use the knowledge of these individual simpler units to build back up the full system and study it as a whole – how are these individual agents interacting with each other and what does that tell us about the system? This is a bottom-up approach, i.e., understanding reductionism in reverse.

In fact, the author himself touches upon this and contradicts himself when he quotes Bertand Russel in the beginning, “The point of philosophy is to start with something so simple as to not seem worth stating, and to end with something so paradoxical that no one will believe it.” This is nothing but reverse reductionism. This is what we often do in math too. We start with an obvious (trivial) statement that no one will seem to contradict, and then build something upward from there, leading to a complex proof or a result that may be counterintuitive or ‘mind-boggling’ as the mathematicians say. Since most of the sciences depend on math, they follow a similar pattern of experimentalism and theorization. And what does science aim to do? Science studies and tries to explain the daily observations and occurrences in nature. So, doesn’t this tell us something about nature as well? Yes, it does. And it is that nature itself governs by the law of reverse reductionism. Nature defines how the individual elements behave and then puts them together, letting them run free reign – agents interacting as they wish – and thus creating complex systems.

Hence, if we wish to understand the complex systems in nature, we must employ the strategy of reverse reductionism after reductionism. Understanding reductionism in the reverse direction does not fail us, but rather it is an essential next step.

Assignment 1 – Ayush

 

My inspiration for this project comes from this video by Veritasium.

Pathfinding have a ubiquitous presence in the real world. Their applications range from everyday navigation tools like Google Maps and logistics optimization for companies like Amazon. They are also used in guiding the movements of autonomous vehicles.

Through this project I wanted to experiment with more than just a random walk. I wanted to see if we can put some brain into our walker, so it doesn’t just go towards random directions, but makes some decision in order to find the destination.

Here’s the p5.js sketch:

https://editor.p5js.org/ap6178/sketches/Wi7864pjq

 

The walker performs multiple succeeding walks, from one cell to the other. But then it realizes that the direction it’s taking is not the correct one. When this happens, it tries a new path. Each of these paths have some metrics that tell the walker whether it’s going towards the correct direction or not.

To put brain into the walker, I have used the A* search algorithm. It basically takes two things into consideration in order to be able to make decisions:

  • The cost it took for the walker to get to the current point.
  • An estimate of how far the walker thinks it is from the destination.

This estimate is called the heuristic function in A* search algorithm. The total estimated cost is given by the following equation:

f(n) = g(n) + h(n)

At any node n, the estimated cost of the path is calculated i.e. f(n)
f(n) requires two other costs: the cost to reach node n i.e. g(n) and the estimated cost to reach the goal node i.e. h(n)

h(n) in this equation is called the heuristic function. There are many heuristic functions we can use, but in this project, I decided to use the Manhattan distance heuristic since we’re dealing with cells on the grid. The Manhattan distance is the sum of horizontal and vertical cell distances to the goal node.

This idea of calculating heuristic for each step makes the walker intelligent.

 

Code

Each node has the following properties as described by the Node class.

class Node {
  constructor(i, j) {
    this.i = i;
    this.j = j;
    this.f = 0;
    this.g = 0;
    this.h = 0;
    this.wall = random(1) < 0.30; // there's a 30% chance of being a wall
    this.previous = undefined;
  }

  show(col) {
    fill(col);
    if (this.wall) {
      fill(59, 25, 25);
    }
    rect(this.i * cellSize, this.j * cellSize, cellSize, cellSize);
  }

  getNeighbors() {
    const neighbors = [];
    const i = this.i;
    const j = this.j;

    if (i < cols - 1) {
      neighbors.push(grid[i + 1][j]);
    }
    if (i > 0) {
      neighbors.push(grid[i - 1][j]);
    }
    if (j < rows - 1) {
      neighbors.push(grid[i][j + 1]);
    }
    if (j > 0) {
      neighbors.push(grid[i][j - 1]);
    }

    return neighbors;
  }
}

The main brain of the walker lies on this heuristic measure. It calculates the Manhattan distance between two nodes nodeA and nodeB required for our estimation function.

function heuristic(nodeA, nodeB) {
  // Manhattan distance (sum of horizontal and vertical distances)
  const dx = abs(nodeA.i - nodeB.i);
  const dy = abs(nodeA.j - nodeB.j);
  return dx + dy;
}

With the help of this heuristic, the function values: f, g, and h are then updated and required actions are taken.

// check neighbors and update their f, g, h values
const neighbors = current.getNeighbors();
for (let neighbor of neighbors) {
  if (!visited.includes(neighbor) && !neighbor.wall) {
    const g = current.g + 1;
    let newPath = false;
        
    if (unexplored.includes(neighbor)) {
      if (g < neighbor.g) {
        neighbor.g = g;
        newPath = true;
      }
    } else {
      neighbor.g = g;
      unexplored.push(neighbor);
      newPath = true;
    }
        
    // update values if path is new
    if (newPath) {
      neighbor.h = heuristic(neighbor, endNode);
      neighbor.f = neighbor.g + neighbor.h;
      neighbor.previous = current;
    }
  }

Future Improvements

An improvement to this project would be to be able to connect the path with lines and show a more artistic version of how the walker is choosing new paths. I would also want to add some kind of animation when it reverts back a few steps to continue to a new path.

Xiaozao Week1 Coding Assignment

This week, I tried on two different kinds of random walkers, which are the self-avoiding walker and the chance-control walker.

Self-avoiding Snake

Video: https://drive.google.com/file/d/1Y0-no7La1HUOdGIHNaVAoFkQJxFrM-Tg/view?usp=drive_link


P5js sketch: https://editor.p5js.org/Xiaozao/sketches/st5NS1k5R


(I’m sorry, something went wrong with my wordpress editor and I really don’t know how to insert the p5 sketch in this new editor. I will try to figure it out asap!!)


This project is inspired by the classic game “Snake”. Since the self-avoiding random walker moves either vertically or horizontally on a grid, why can’t I make a snake game by controlling the length of the path of this random walker, and placing some “apples” on the grid, so that whenever the snake touches an apple, it will eat it and grow in length? And the special property of the self-avoiding walker, which is that it will either find another path or terminate walking when it meets its own body, is very suitable for making a snake game.


I started with coding a self-avoiding random walker. I learned it from the coding train: https://youtu.be/m6-cm6GZ1iw?si=cbg0Dx-YE7jZplUc.

Basically, I first create a grid of size (rows, cols) and initialize the value of each pixel in the grid to be True, meaning that it’s empty and available to be occupied. And then, I create an array, which consists of every node of the snake’s body, and I change the status of the pixels that have been occupied by the snake’s body, meaning that they can no longer be stepping into when I’m considering the next step. After that, I begin to check the 4 neighbours of my current position (up, down, left and right), and if they are still empty and not occupied, I put them into my “available options” array. Finally, I choose a random direction from the available options, and go to the next step. This is how the self-avoiding walker works.

And then, I began to program the snake game. There are two main considerations of this game. Firstly, different from the original random walker, which draws every single node that I’ve been to, now I want to control the length of my snake. This can lower the chance of terminating the game too fast because a long body occupies a lot of space so there will be fewer choices in every step. To do this, I have to keep track of every node of the snake’s body, and pop the tail out if it’s too long. I made an array of nodes, and used the function splice() to pop out the older parts of the snake body.

The second important part is the apple-eating mechanism. Whenever I click the mouse, an apple will be placed at the same place and can be eaten by the snake. The snake’s length will plus by one every time it eats an apple. I made a class for the Apple objects, and came up with a formula that calculates the position to place the apples so that they will always be in the center of the pixels, so that they can be easily eaten by the snake.

Lastly, I placed a “keyboard” in the grid. The value of mouseY will control the frequency rate of the sound being played so it creates a really funny sound effect! (By the way, I recorded the sound on my own~)

Chance-control random walker

This is another experiment that comes from a mistake. Please look at the explanation below:

I mistakenly wrote the code when I was trying to create a uniform random distribution. Instead of generating a single random number and checking its value using if/else statement, I generated a brand new random number in each “else if” statement”. But it accidentally created a non-uniform random distribution which the chance of executing the second “else if” block is somehow dependent on the chance of executing the first “if” block, and so on. I then tried to pass the chance values for the four statements as parameters and map the hue of the random walker with the chance values. And the result turned out to be interesting!

Here is the code: https://editor.p5js.org/Xiaozao/sketches/vyNmsjMgc

There’s so much more to explore about this chance-controlling random walker!