Advertisement
JCandEW

SimulatedOrganisms

Oct 19th, 2017
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.56 KB | None | 0 0
  1. # Simulated Organisms Project
  2. # Created by Jack Cummins and Ethan Wrightson on Tuesday, 17th October 2017
  3. # An attempt to create a simulation of lifelike organisms which will evolve over time.
  4.  
  5. # http://www.101computing.net/creating-sprites-using-pygame/
  6.  
  7. # Definitions:
  8.  
  9. # SO: Simulated Organism, or the list that contains all the simulated organisms
  10. # starter: One of the original SOs that is created at the start of the simulation (contrast with daughter)
  11. # daughter: An SO that has been born of another SO's mitosis
  12. # DEBUG LINE: A line that has been added in for the purpose of debugging. Delete the lines when finished debugging
  13.  
  14. import random
  15. import time
  16.  
  17.  
  18. class Organism:
  19.     # This class defines the behavior of organism objects
  20.  
  21.     # Properties of organism objects
  22.  
  23.     energy = 0  # How much energy the SO has, how hungry it is
  24.     immunity = 0  # How strong the SO is at fighting disease
  25.     health = 0  # How healthy the SO is.
  26.     thirstSatisfied = 0  # How much water the SO has to function
  27.     speed = 0  # How quickly the SO can get to food
  28.     fertility = 0  # How soon the SO will reproduce (assuming it survives long enough)
  29.     digestionPercentage = 0  # How good the SO is at getting energy from food and thirstSatisfied from water
  30.     timeAlive = 0  # How long the organism has been alive for
  31.     chanceOfSexualRepoduction = 0  # The chance the organism has of being able to reproduce sexually
  32.     xPosition = 0  # The position of the So in the x axis (0 being the very left)
  33.     yPosition = 0  # The position of the SO in the y axis (0 being the very bottom)
  34.     chanceOfJoiningUp = 0  # The chance that the SO will be able to join up with another to double the speed
  35.  
  36.     # Initialiser function
  37.     def __init__(self, type, SO):
  38.         # Function run automatically when a new SO is created
  39.         print('A new ' + type + ' SO has been created.')
  40.  
  41.     # Functions of organism objects
  42.  
  43.     def die(self, reason, num, SO, numOfDeadSOs):
  44.         # Function called when an SO dies
  45.  
  46.         print('Die function called')
  47.         print(len(SO)) # Debug Line
  48.  
  49.         # Print statement
  50.         if reason is 'mitosis':
  51.             print('An SO has performed mitosis')
  52.         else:
  53.             print('An SO is dying for reason: ' + reason)
  54.  
  55.         # Kill the SO
  56.         del SO[num]
  57.         print('Killed SO')
  58.         numOfDeadSOs += 1
  59.  
  60.         print('About to return from die')
  61.         print(len(SO)) # Debug Line
  62.         return [SO, numOfDeadSOs]
  63.  
  64.  
  65.     def eat(self, SO, foodCellNum, foodCells):
  66.         # Function called when an SO should consume food to increase energy
  67.  
  68.         print('Eat function called')
  69.  
  70.         # Give the SO the energy of the food cell, and then delete the food cell
  71.         self.energy += foodCells[foodCellNum]
  72.         del foodCells[foodCellNum]
  73.  
  74.         return [SO, foodCells]
  75.  
  76.     def drink(self, waterDropletNum, waterDroplets):
  77.         # Function called when an SO should consume water to increase thirstSatisfied
  78.  
  79.         print('Eat function called')
  80.  
  81.         # Give the SO the thirstSatisfied of the water droplet, and then delete the water droplet
  82.         self.energy += waterDroplets(waterDropletNum)
  83.         del waterDroplets[waterDropletNum]
  84.  
  85.     def mitosis(self, SO, numOfDeadSOs, parentNum):
  86.         # Start the process of turning one sucessful parent cell into two dauchter cells
  87.  
  88.         print('Mitosis function called')
  89.         print(len(SO)) # Debug Line
  90.  
  91.         for i in range(0, 2):  # For loop so that one block of code creates two daughters
  92.  
  93.             SO.append(Organism('daughter', SO))  # Creates the daughter
  94.             a = len(SO) - 1  # SO[a] will be used to refer to the newly created daughter
  95.  
  96.             # Give the daughter its parameters
  97.             SO[a].timeAlive = 0
  98.             SO[a].health = 1000
  99.             SO[a].energy = 1000
  100.             SO[a].thirstSatisfied = 1000
  101.             SO[a].immunity = self.immunity + random.randint(-10, 10)
  102.             SO[a].speed = self.speed + random.uniform(-1, 1)
  103.             SO[a].fertility = self.fertility + random.randint(-10, 10)
  104.             if SO[a].fertility < 500: # Limit the minimum fertility time to 500. No hyper-reproduction
  105.                 SO[a].fertility = 500
  106.             SO[a].digestionPercentage = self.digestionPercentage + random.randint(-1, 2)
  107.             if SO[a].immunity > 100:
  108.                 SO[a].immunity = 100
  109.             if self.chanceOfSexualRepoduction == 1000:
  110.                 SO[a].chanceOfSexualReproduction = 1000
  111.             else:
  112.                 SO[a].chanceOfSexualReproduction = self.chanceOfSexualRepoduction + random.randint(-10, 10)
  113.             SO[a].xPosition = self.xPosition + random.randint(-10, 10)
  114.             SO[a].yPosition = self.yPosition = random. randint(-10, 10)
  115.             if SO[i].chanceOfJoiningUp == 1000:
  116.                 SO[a].chanceOfJoiningUp = 1000
  117.             else:
  118.                 SO[a].chanceOfJoiningUp = self.chanceOfJoiningUp + random.randint(-10, 10)
  119.  
  120.         b = self.die('mitosis', parentNum, SO, numOfDeadSOs)  # Eliminates the parent SO
  121.  
  122.         SO = b[0]
  123.         numOfDeadSOs = b[1]
  124.  
  125.         return [SO, numOfDeadSOs]
  126.  
  127.     def sexualReproduction(self):
  128.         # The function called when two parent SOs create a daughter SO with lots of variation
  129.         print("Filler code. Delete when other code is added")
  130.  
  131.     def joinUp(self):
  132.         # The function called when two SOs can join up to increase speed and probability of survival
  133.         print('Filler code. Delete when other code is added.')
  134.  
  135.     def move(self, SO):
  136.         # The function called for each SO every second which decides how it should move
  137.         target = self.findWhereShouldMove()
  138.  
  139.         return SO
  140.  
  141.     def findWhereShouldMove(self):
  142.         # The function called each cycle in order to figure out how it should move that cycle
  143.         print('Filler code. Delete when other code is added.')
  144.  
  145.  
  146. class MultiCellSO:
  147.     # A multi-cellular organism. Hopefully the SOs can evolve into these over time
  148.  
  149.     #Properties of MultiCellSO objects
  150.  
  151.     cellSpeeds = []
  152.     cellImmunities = []
  153.     cellHealths = []
  154.  
  155.     # Initialiser function
  156.     def __init__(self):
  157.         print('Filler code. Delete when other code is added.')
  158.  
  159.  
  160. class Disease:
  161.     # This class defines the behaviour of disease objects
  162.  
  163.     # Properties of disease objects
  164.    
  165.     effect = 0  # How effective the disease is at wiping out SOs
  166.     timePresent = 0  # How long the disease should keep wiping out weak SOs
  167.     timeHasBeenPresent = 0 # Similar to timeAlive for SOs, measures how long a disease has been present
  168.  
  169.     # Initialiser function
  170.     def __init__(self, type):
  171.         print('A new disease has been initialised.')
  172.  
  173.         # Give the disease its parameters
  174.         if type == 'chance':
  175.             self.effect = random.randint(0, 1000)
  176.             self.timePresent = random.randint(0, 1000)
  177.  
  178.  
  179. class FoodCell:
  180.     # This class defines the behaviour of food cells that the SOs can get energy from
  181.  
  182.     # Properties of food cells
  183.     containedEnergy = 0 # How much energy the food cell contains, that the SOs can harvest
  184.     xPosition = 0  # The position of the food cell in the x axis (0 being the very left)
  185.     yPosition = 0  # The position of the food cell in the y axis (0 being the very bottom)
  186.  
  187.     # Initialiser function
  188.     def __init__(self):
  189.         print('A new food cell has spawned\n')
  190.         self.containedEnergy = random.randint(20, 500)
  191.         self.xPosition = random.randint(0, 1000)
  192.         self.yPosition = random.randint(0, 1000)
  193.  
  194.  
  195. class WaterDroplet:
  196.     # This class defines the behaviour of water droplets that the SOs can get thirstSatisfied from
  197.  
  198.     # Properties of water droplets
  199.     containedWater = 0  # The amount of water that the droplet contains, the maximum thirstSatisfied obtainable
  200.     xPosition = 0  # The position of the water droplet in the x axis (0 being the very left)
  201.     yPosition = 0  # The position of the water droplet in the y axis (0 being the very bottom)
  202.  
  203.     # Initialiser function
  204.     def __init__(self):
  205.         print('A new water droplet has spawned\n')
  206.         self.containedEnergy = random.randint(20, 500)
  207.         self.xPosition = random.randint(0, 1000)
  208.         self.yPosition = random.randint(0, 1000)
  209.  
  210. def simCycle(SO, multiCellSOs, diseases, foodCells, waterDroplets, numOfDeadSOs):
  211.     # The function that will actually run the simulation
  212.  
  213.     print('SimCycle function has been called')
  214.  
  215.     a = True
  216.     simTime = 0 # The time that the simulation has been active
  217.  
  218.     # This is the loop that will take all action and essentially govern the simulation
  219.     while a is True:
  220.  
  221.         print('SimCycle loop called')
  222.  
  223.         simTime += 1
  224.  
  225.         # Print current sim data - before graphics added, user can see what's going on old style
  226.         print('\n')
  227.         print('Simulation has been running for: ' + str(simTime) + ' simulated seconds')
  228.         print('The total number of living SOs is: ' + str(len(SO)))
  229.         print(str(numOfDeadSOs) + ' have died since sim began')
  230.         print('The number of food cells currently existing is: ' + str(len(foodCells)))
  231.         print('The number of water droplets currently existing is: ' + str(len(waterDroplets)))
  232.         print('\n')
  233.  
  234.         # Update the timeAlive for all SOs
  235.         i = 0
  236.         b = len(SO)
  237.  
  238.         while i < b:
  239.             SO[i].timeAlive += 1
  240.  
  241.             # If the SO has reached its fertility time and has enough energy, let it do mitosis.
  242.             if SO[i].timeAlive == SO[i].fertility and SO[i].energy >= 100:
  243.                 e = SO[i].mitosis(SO, numOfDeadSOs, i)
  244.                 SO = e[0]; numOfDeadSOs = e[1]
  245.  
  246.             i += 1
  247.  
  248.         # Decide if a new food cell should be initialised
  249.         chance = random.randint(0, 20)
  250.         if chance is 20:
  251.             foodCells.append(FoodCell())
  252.  
  253.         # Decide if a new water droplet should be initialised
  254.         chance = random.randint(0, 20)
  255.         if chance is 20:
  256.             waterDroplets.append(WaterDroplet())
  257.  
  258.         # Decide if a new disease should be initialised
  259.         chance = random.randint(0, 10000)
  260.         if chance == 1000:
  261.             diseases.append(Disease())
  262.  
  263.         # Decide if the SO can eat / drink
  264.         i = 0
  265.         while i < b:
  266.             d = 0
  267.             while d < len(foodCells):
  268.                 if SO[i].xPosition == foodCells[d].xPosition and SO[i].yPosition == foodCells[d].yPosition:
  269.                     c = SO[i].eat(d, foodCells)
  270.                     SO = c[0]; foodCells = c[1]
  271.  
  272.                 d += 1
  273.  
  274.             d = 0
  275.             while d < len(waterDroplets):
  276.                 if SO[i].xPosition == waterDroplets[d].xPostion and SO[i].yPosition == waterDroplets[d].yPosition:
  277.                     # Do the drinking and then delete the water droplet
  278.                     c = SO[i].drink(d, waterDroplets)
  279.                     SO = c[0]; waterDroplets = c[1]
  280.  
  281.                 d += 1
  282.  
  283.             i += 1
  284.  
  285.         # Reloop the simCycle
  286.         time.sleep(0)
  287.         a = True
  288.  
  289. def main():
  290.     # This code is run when the program starts.
  291.  
  292.  
  293.     print("Program starting - main function has been called")
  294.  
  295.     # Create the empty lists that will soon be full of objects.
  296.     SO = []
  297.     multiCellSOs = []
  298.     diseases = []
  299.     foodCells = []
  300.     waterDroplets = []
  301.  
  302.     # Create other variables that will be used in the simulation
  303.  
  304.     numOfDeadSOs = 0
  305.  
  306.     # Create the starter SOs that will populate the early simulation
  307.  
  308.     numOfStarters = 20  # The number of starter cells that will be created
  309.  
  310.     for i in range(0, numOfStarters):  # Will create as many SO as wanted upon startup
  311.  
  312.         SO.append(Organism('starter', SO))  # Creates the new SO
  313.  
  314.         # Gives the SO its parameters
  315.         SO[i].energy = 1000
  316.         SO[i].immunity = random.randint(0, 1000)
  317.         SO[i].health = 1000
  318.         SO[i].thirstSatisfied = 1000
  319.         SO[i].speed = random.uniform(0, 5)
  320.         SO[i].fertility = random.randint(1000, 3000)
  321.         SO[i].digestionPercentage = random.randint(0, 100)
  322.         SO[i].timeAlive = 0
  323.         SO[i].chanceOfSexualRepoduction = random.randint(0, 1000)
  324.         SO[i].xPosition = random.randint(0, 1000)
  325.         SO[i].yPosition = random.randint(0, 1000)
  326.         SO[i].chanceOfJoiningUp = random.randint(0, 1000)
  327.  
  328.     print("The number of SOs spawned is: " + str(len(SO)))
  329.     print("Main function finished. Calling simCycle")
  330.  
  331.     # Start the cycle that will run the simulation and allow changes to be made.
  332.     simCycle(SO, multiCellSOs, diseases, foodCells, waterDroplets, numOfDeadSOs)
  333.  
  334. # Initiate the program on startup
  335. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement