Environment Simulator

This was the project that I did for my Spring 2012 High Performance Computing class. Since a simulation with potentially millions of organisms being simultaneously updated requires a lot of powerful parallel processing, it was an ideal project to experiment with for learning programming with MPI on a computer cluster.


Here is a screenshot of the running simulation:

Click the image to see it in full size.


Source code for this project is available here on GitHub!


What exactly does it do?
This program simulates three types of organisms: plants, herbivores, and predators. Plants spawn in the environment, but the number that spawn at each time interval depend on the number that already exist. The more there already are, the faster they reproduce. Herbivores eat plants, and reproduce if they are well-fed. Of course, if they don't eat for a while, they will starve and die. Also, if they eat too many plants, or if the plants go extinct, the herbivores will also starve! Predators work similarly, except that they eat the herbivores. Predators are at the top of the food chain.

How does it work?
When the program is run, the head node of the cluster initializes the other worker nodes. It sends each of them a message with the predetermined number of organisms they will work with. Currently, three worker nodes handle the position updates and reproductions of each of the three different organism types. Then, two other worker nodes handle the collision calculations between herbivores and plants, and herbivores and predators. They return the collision data to the other three worker nodes, which then send the position of all living organisms to the head node. The head node draws the organisms on the screen with OpenGL.

What are the future plans for this project?
There is still a lot to do. These are just a few potential ideas:
• Modify how the organisms move: make them "smarter" by having their movement controlled by decisions based on their need to feed or avoid predators.
• Add sexual reproduction for certain organisms instead of having them all reproduce only based on food level.
• Re-design some parts of the MPI code that would allow for an abstract number of organism types (species), and allow for a more dynamically expanding population size.
• Add more nodes to the cluster, and organize the distribution of work in a way so that some nodes can take on any arbitrary job, rather than be limited to a specific task.
• Implement genomes in the organisms, where reproduction will pass down genes, and allow natural selection to act on the system. Genes would allow each organism's behavior to be encoded which would determine how they avoid predators and how they feed.
• Add customizable organism types and ability to specify behavior.
• Add walls and walled-off areas, and other objects (such as mountains) that organisms cannot pass through that would provide more variety in the environment.
• Add environmental conditions, such as weather, that would explose some strenghts and weaknesses of organisms, especially plants, and allow for the observation of adaptation.

Why do the project?
On one hand, it's an excellent learning experience. It is also a potentially interesting and powerful tool that could simulate biological ecosystems, and the interaction between evolving organism populations. One of my personal goals with this project is to be able to simulate how different events, such as natural disasters, human interference, or disease outbreaks, can affect a stable ecosystem of millions of organisms. It is a nice mix of computer science and biology, and I am very excited to keep working on this project.



Here is some sample code of the OpenGL display function which displays each organism:

void display_func(){
	// clear and ready for display
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	
	// set size of each rendered point!
	glPointSize(4.0);
	
	// DISPLAY ORGANISMS!
	glBegin(GL_POINTS); // start creating POINT vertices
	
		// display plants:
		glColor3f(0.0, 1.0, 0.0); // green
		int i;
		for(i = 0; i<plant_loc_count; i++){
			glVertex2f(plant_locs[i*2], plant_locs[i*2+1]);
		}
		
		// display herbivores
		glColor3f(0.0, 0.0, 1.0); // blue
		for(i = 0; i<herbivore_loc_count; i++){
			glVertex2f(herbivore_locs[i*2], herbivore_locs[i*2+1]);
		}
		
		// display predators
		glColor3f(1.0, 0.0, 0.0); // red
		for(i = 0; i<predator_loc_count; i++){
			glVertex2f(predator_locs[i*2], predator_locs[i*2+1]);
		}
		
	glEnd(); // finish making vertices

	// display the updated buffer
	glutSwapBuffers();
}

This code is run on the head node to display the simulation on the screen in real time.




Back to Top