For this assignment, keep track and record the progress of your project by using Git.
You will have to submit the output of the git log –showing at least 3 commits– along with a comment that explains your decision about when to commit your files.
Artificial Life is a field of computer science that uses the power of computers to gain understanding about the fundamental processes of living systems. Research in Artificial Life (or A-Life) often uses highly complex object-oriented software programs to model properties of a living organism. However, the necessary elements for an artificial life simulation are actually fairly easy.
In this assignment, you will be using your skills in object-oriented programming to make an artificial life simulation of cooperation between bacteria. Bacteria actually cooperate in lots of interesting ways. Because they are so small, however, it is difficult for biologists to figure out exactly what each individual is doing. Instead, we have a good understanding of the large-scale patterns seen in bacterial colonies. This topic is therefore great for a computer simulation, because you can test out hypotheses about what individual organisms are doing and compare your large-scale results to what we already know is happening in biological systems.
Implementing Artificial Life
Fundamentally, an artificial life simulation can consist of only two primary classes:
The Population class is how you represent your virtual petri dish. It keeps track of how long the experiment has been running and what sort of environment your digital bacteria are attempting to live in. It also has methods for collecting statistical information about your experiment. The Population class will hold a list of all of your organisms and at every “time point” or tick it will loop over those organisms and allow them to perform one action, represented by an update method.
The Organism class is how you represent a single individual organism. This project is one where object-oriented programming is a powerful paradigm, because you will have hundreds of instances of Organisms, all with different values for their variables. The Organism class holds methods for determining what each instance is going to do at any given time (in our project, cooperate or not) and instructions for reproduction if that instance has gotten enough resources. Each organism has an “energy level” that measures how much energy that organism has currently. When the organism has enough energy, it is able to reproduce, which uses up all the energy it had saved. You will give each organism one new energy at each update.
Cooperation
You are going to use your artificial life simulation to study the dynamics of cooperation between bacteria of the same species. Your Organism classes will track the likelihood that it cooperates with other organisms, its cooperation probability. When an organism has a chance to act, i.e. when its update method is called. You will use that cooperation probability number to determine if the organism cooperates with its neighbors. In this project, the cooperation probability will be between 1 (100%) or 0 (0%). If the organism’s probability is 1, it will cooperate with organisms around it; if it is 0, it does not cooperate; and if it is somewhere between it cooperates with that probability.
When an organism cooperates, it loses one of its energy units and in exchange it gives eight other organisms an energy unit. (You will randomly select which other organisms to give energy to.)
Note: Create a package for your classes, called "simulator"
The Organism Class
This class will represent individual bacterium in your population. It should have the following constructor and methods:
Note that no Organism objects themselves actually exist as they are an abstract concept in this program; you should only create instances of sub-classes of the Organism class described below.
The getType, reproduce, getCooperationProbability, and cooperates methods must be overridden by the subclasses. We should enforce this rule by making those abstract methods.
Organism Sub-Classes
We will use inheritance to differentiate the behavior of the different organisms in our system. In your program, implement the following sub-classes of Organism:
The Population Class
Your class should have the following constructor and methods:
Note that when implementing update() that you should respect encapsulation of data between the population and organism class. Furthermore, you should also be aware of ConcurrentModificationExceptions in your code. Such an exception occurs whenever you add or remove from a list that you are currently iterating over with an iterator. You will need to be careful with how you design your iteration pattern in update to avoid this problem.
The ALifeSim Class
Finally, write a driver (main) class ALifeSim that creates a simulation with parameters provided from the command-line and runs that simulation for a particular number of iterations. Your ALifeSim class should contain a main method that accepts command-line arguments of the following form:
java ALifeSim <#/iterations> <#/cooperators> <#/defectors> <#/partial cooperators>
Your ALifeSim simulates the given population for the given number of iterations of the simulation. It then reports the final counts of organisms and mean cooperation probability for the population in the following format:
After <#/iterations> ticks:
Cooperators = <final #/cooperators>
Defectors = <final #/defectors>
Partial = <final #/partial cooperators>
Mean Cooperation Probability = <mean cooperation probability>
You will use your program to perform a number of experiments with artificial life and write a short essay on the results.
You should use the following settings:
For each experiment you should write a short paragraph reporting:
Finally, you should write a concluding paragraph that summarizes the results you found. What insights can you make regarding what lets cooperators succeed in this simulation versus go extinct?
All together, this report should be at least a page in length. You may want to test other population sizes and starting proportions to get a better idea of what dynamics are happening.
You will have to submit the output of the git log –showing at least 3 commits– along with a comment that explain your decision about when to commit your project/files, and the source files.
You MUST include an Academic Honesty Statement in your Program (the file with the main method). If you do not, your submission will be assessed a 10% penalty. Code that does not compile or have corrupted files will received a zero (0). This is the last assignment, so there is no opportunity to resubmit your work.
You will submit this assignment via Gradescope. You must upload the source files, the assignment report, the git log, and the compressed file containing all the aforementioned files. The compressed file must be a tar.gz file (see Lab 1 for instructions on how to create this file from your directory). Files that are in a .zip format will lose one point. Others types of compressed files will not be graded.
This assignment is worth up to 25 points based on the following:
Good practices
Meet Requirement specification
Apply object-oriented design principles to the creation of Java programs
Handling errors
The original version of this assignment was written by Anya Vostinar and is available at: https://github.com/anyaevostinar/alife-assignment
For your assignment to be considered for extra points, the Artificial Life Simulator must work without errors, as detailed in the assignment requirements. You can create a different tester for the extra section.
The following may or not be helpful.
To render text in an animated way, we can use a loop but in each iteration of the loop, delay execution by causing the program to sleep. To do this, we’ll use the sleep(
milliseconds)
function of the Thread class:
public static void printStaggered() throws InterruptedException {
while(true) {
System.out.println("Hello World!");
Thread.sleep(2000);
} // while
} // printStaggered
This snippet of code constantly prints Hello World to the console but in two second intervals. The argument to Thread.sleep
is the amount of time the program should wait in milliseconds. Note that Thread.sleep
throws the checked exception InterruptedException
. We use a throws
clause here to avoid handling the exception explicitly.
You can use the information above and what you learned about Graphics and DrawingPanel in the Drawing and the Java GUI Lab to create a visual representation of the Artificial Life Simulator.
This section is worth 5 extra points. (No partial points will be given).