Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Simulated Organisms Project
- # Created by Jack Cummins and Ethan Wrightson on Tuesday, 17th October 2017
- # An attempt to create a simulation of lifelike organisms which will evolve over time.
- # http://www.101computing.net/creating-sprites-using-pygame/
- # Definitions:
- # SO: Simulated Organism, or the list that contains all the simulated organisms
- # starter: One of the original SOs that is created at the start of the simulation (contrast with daughter)
- # daughter: An SO that has been born of another SO's mitosis
- # DEBUG LINE: A line that has been added in for the purpose of debugging. Delete the lines when finished debugging
- import random
- import time
- class Organism:
- # This class defines the behavior of organism objects
- # Properties of organism objects
- energy = 0 # How much energy the SO has, how hungry it is
- immunity = 0 # How strong the SO is at fighting disease
- health = 0 # How healthy the SO is.
- thirstSatisfied = 0 # How much water the SO has to function
- speed = 0 # How quickly the SO can get to food
- fertility = 0 # How soon the SO will reproduce (assuming it survives long enough)
- digestionPercentage = 0 # How good the SO is at getting energy from food and thirstSatisfied from water
- timeAlive = 0 # How long the organism has been alive for
- chanceOfSexualRepoduction = 0 # The chance the organism has of being able to reproduce sexually
- xPosition = 0 # The position of the So in the x axis (0 being the very left)
- yPosition = 0 # The position of the SO in the y axis (0 being the very bottom)
- chanceOfJoiningUp = 0 # The chance that the SO will be able to join up with another to double the speed
- # Initialiser function
- def __init__(self, type, SO):
- # Function run automatically when a new SO is created
- print('A new ' + type + ' SO has been created.')
- # Functions of organism objects
- def die(self, reason, num, SO, numOfDeadSOs):
- # Function called when an SO dies
- print('Die function called')
- print(len(SO)) # Debug Line
- # Print statement
- if reason is 'mitosis':
- print('An SO has performed mitosis')
- else:
- print('An SO is dying for reason: ' + reason)
- # Kill the SO
- del SO[num]
- print('Killed SO')
- numOfDeadSOs += 1
- print('About to return from die')
- print(len(SO)) # Debug Line
- return [SO, numOfDeadSOs]
- def eat(self, SO, foodCellNum, foodCells):
- # Function called when an SO should consume food to increase energy
- print('Eat function called')
- # Give the SO the energy of the food cell, and then delete the food cell
- self.energy += foodCells[foodCellNum]
- del foodCells[foodCellNum]
- return [SO, foodCells]
- def drink(self, waterDropletNum, waterDroplets):
- # Function called when an SO should consume water to increase thirstSatisfied
- print('Eat function called')
- # Give the SO the thirstSatisfied of the water droplet, and then delete the water droplet
- self.energy += waterDroplets(waterDropletNum)
- del waterDroplets[waterDropletNum]
- def mitosis(self, SO, numOfDeadSOs, parentNum):
- # Start the process of turning one sucessful parent cell into two dauchter cells
- print('Mitosis function called')
- print(len(SO)) # Debug Line
- for i in range(0, 2): # For loop so that one block of code creates two daughters
- SO.append(Organism('daughter', SO)) # Creates the daughter
- a = len(SO) - 1 # SO[a] will be used to refer to the newly created daughter
- # Give the daughter its parameters
- SO[a].timeAlive = 0
- SO[a].health = 1000
- SO[a].energy = 1000
- SO[a].thirstSatisfied = 1000
- SO[a].immunity = self.immunity + random.randint(-10, 10)
- SO[a].speed = self.speed + random.uniform(-1, 1)
- SO[a].fertility = self.fertility + random.randint(-10, 10)
- if SO[a].fertility < 500: # Limit the minimum fertility time to 500. No hyper-reproduction
- SO[a].fertility = 500
- SO[a].digestionPercentage = self.digestionPercentage + random.randint(-1, 2)
- if SO[a].immunity > 100:
- SO[a].immunity = 100
- if self.chanceOfSexualRepoduction == 1000:
- SO[a].chanceOfSexualReproduction = 1000
- else:
- SO[a].chanceOfSexualReproduction = self.chanceOfSexualRepoduction + random.randint(-10, 10)
- SO[a].xPosition = self.xPosition + random.randint(-10, 10)
- SO[a].yPosition = self.yPosition = random. randint(-10, 10)
- if SO[i].chanceOfJoiningUp == 1000:
- SO[a].chanceOfJoiningUp = 1000
- else:
- SO[a].chanceOfJoiningUp = self.chanceOfJoiningUp + random.randint(-10, 10)
- b = self.die('mitosis', parentNum, SO, numOfDeadSOs) # Eliminates the parent SO
- SO = b[0]
- numOfDeadSOs = b[1]
- return [SO, numOfDeadSOs]
- def sexualReproduction(self):
- # The function called when two parent SOs create a daughter SO with lots of variation
- print("Filler code. Delete when other code is added")
- def joinUp(self):
- # The function called when two SOs can join up to increase speed and probability of survival
- print('Filler code. Delete when other code is added.')
- def move(self, SO):
- # The function called for each SO every second which decides how it should move
- target = self.findWhereShouldMove()
- return SO
- def findWhereShouldMove(self):
- # The function called each cycle in order to figure out how it should move that cycle
- print('Filler code. Delete when other code is added.')
- class MultiCellSO:
- # A multi-cellular organism. Hopefully the SOs can evolve into these over time
- #Properties of MultiCellSO objects
- cellSpeeds = []
- cellImmunities = []
- cellHealths = []
- # Initialiser function
- def __init__(self):
- print('Filler code. Delete when other code is added.')
- class Disease:
- # This class defines the behaviour of disease objects
- # Properties of disease objects
- effect = 0 # How effective the disease is at wiping out SOs
- timePresent = 0 # How long the disease should keep wiping out weak SOs
- timeHasBeenPresent = 0 # Similar to timeAlive for SOs, measures how long a disease has been present
- # Initialiser function
- def __init__(self, type):
- print('A new disease has been initialised.')
- # Give the disease its parameters
- if type == 'chance':
- self.effect = random.randint(0, 1000)
- self.timePresent = random.randint(0, 1000)
- class FoodCell:
- # This class defines the behaviour of food cells that the SOs can get energy from
- # Properties of food cells
- containedEnergy = 0 # How much energy the food cell contains, that the SOs can harvest
- xPosition = 0 # The position of the food cell in the x axis (0 being the very left)
- yPosition = 0 # The position of the food cell in the y axis (0 being the very bottom)
- # Initialiser function
- def __init__(self):
- print('A new food cell has spawned\n')
- self.containedEnergy = random.randint(20, 500)
- self.xPosition = random.randint(0, 1000)
- self.yPosition = random.randint(0, 1000)
- class WaterDroplet:
- # This class defines the behaviour of water droplets that the SOs can get thirstSatisfied from
- # Properties of water droplets
- containedWater = 0 # The amount of water that the droplet contains, the maximum thirstSatisfied obtainable
- xPosition = 0 # The position of the water droplet in the x axis (0 being the very left)
- yPosition = 0 # The position of the water droplet in the y axis (0 being the very bottom)
- # Initialiser function
- def __init__(self):
- print('A new water droplet has spawned\n')
- self.containedEnergy = random.randint(20, 500)
- self.xPosition = random.randint(0, 1000)
- self.yPosition = random.randint(0, 1000)
- def simCycle(SO, multiCellSOs, diseases, foodCells, waterDroplets, numOfDeadSOs):
- # The function that will actually run the simulation
- print('SimCycle function has been called')
- a = True
- simTime = 0 # The time that the simulation has been active
- # This is the loop that will take all action and essentially govern the simulation
- while a is True:
- print('SimCycle loop called')
- simTime += 1
- # Print current sim data - before graphics added, user can see what's going on old style
- print('\n')
- print('Simulation has been running for: ' + str(simTime) + ' simulated seconds')
- print('The total number of living SOs is: ' + str(len(SO)))
- print(str(numOfDeadSOs) + ' have died since sim began')
- print('The number of food cells currently existing is: ' + str(len(foodCells)))
- print('The number of water droplets currently existing is: ' + str(len(waterDroplets)))
- print('\n')
- # Update the timeAlive for all SOs
- i = 0
- b = len(SO)
- while i < b:
- SO[i].timeAlive += 1
- # If the SO has reached its fertility time and has enough energy, let it do mitosis.
- if SO[i].timeAlive == SO[i].fertility and SO[i].energy >= 100:
- e = SO[i].mitosis(SO, numOfDeadSOs, i)
- SO = e[0]; numOfDeadSOs = e[1]
- i += 1
- # Decide if a new food cell should be initialised
- chance = random.randint(0, 20)
- if chance is 20:
- foodCells.append(FoodCell())
- # Decide if a new water droplet should be initialised
- chance = random.randint(0, 20)
- if chance is 20:
- waterDroplets.append(WaterDroplet())
- # Decide if a new disease should be initialised
- chance = random.randint(0, 10000)
- if chance == 1000:
- diseases.append(Disease())
- # Decide if the SO can eat / drink
- i = 0
- while i < b:
- d = 0
- while d < len(foodCells):
- if SO[i].xPosition == foodCells[d].xPosition and SO[i].yPosition == foodCells[d].yPosition:
- c = SO[i].eat(d, foodCells)
- SO = c[0]; foodCells = c[1]
- d += 1
- d = 0
- while d < len(waterDroplets):
- if SO[i].xPosition == waterDroplets[d].xPostion and SO[i].yPosition == waterDroplets[d].yPosition:
- # Do the drinking and then delete the water droplet
- c = SO[i].drink(d, waterDroplets)
- SO = c[0]; waterDroplets = c[1]
- d += 1
- i += 1
- # Reloop the simCycle
- time.sleep(0)
- a = True
- def main():
- # This code is run when the program starts.
- print("Program starting - main function has been called")
- # Create the empty lists that will soon be full of objects.
- SO = []
- multiCellSOs = []
- diseases = []
- foodCells = []
- waterDroplets = []
- # Create other variables that will be used in the simulation
- numOfDeadSOs = 0
- # Create the starter SOs that will populate the early simulation
- numOfStarters = 20 # The number of starter cells that will be created
- for i in range(0, numOfStarters): # Will create as many SO as wanted upon startup
- SO.append(Organism('starter', SO)) # Creates the new SO
- # Gives the SO its parameters
- SO[i].energy = 1000
- SO[i].immunity = random.randint(0, 1000)
- SO[i].health = 1000
- SO[i].thirstSatisfied = 1000
- SO[i].speed = random.uniform(0, 5)
- SO[i].fertility = random.randint(1000, 3000)
- SO[i].digestionPercentage = random.randint(0, 100)
- SO[i].timeAlive = 0
- SO[i].chanceOfSexualRepoduction = random.randint(0, 1000)
- SO[i].xPosition = random.randint(0, 1000)
- SO[i].yPosition = random.randint(0, 1000)
- SO[i].chanceOfJoiningUp = random.randint(0, 1000)
- print("The number of SOs spawned is: " + str(len(SO)))
- print("Main function finished. Calling simCycle")
- # Start the cycle that will run the simulation and allow changes to be made.
- simCycle(SO, multiCellSOs, diseases, foodCells, waterDroplets, numOfDeadSOs)
- # Initiate the program on startup
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement