Each Organism represents an organism (or colony thereof) in the simulation. Organisms do most of the activity in the simulation. On every generation step, each organism reads one codon of their genome and either changes its mode, or performs the appropriate action. Depending on the organism’s current mode, this action can be gathering, moving, or making a protein.
When an organism is in gather mode, every time it reads a chemical codon, it will gather that resource. The amount of that chemical that it gathers is computed by:
C*G*F
Where C is the amount of that chemical present in the environment, G is the global gather_proportion, and F is the entry for that chemical in the organism’s function vector (Function Vectors).
Gathering is the default mode for an organism, and it will reset to this mode after completing a set of move or protein actions.
When an organism is in movement mode, each read of a chemical codon will cause the organism to move towards that chemical. This is known as a movement action. Each movement action is made up of move_speed movement steps. For a movement step, the organism looks at each of the adjacent grid squares (up, down, left, right) and it’s own and moves to the one with the largest concentration of the specified chemical. If it finds a local maximum of that chemical, it will stay there.
While in movement mode, an organism can make up to max_moves movement actions before it is automatically reset to gather mode. This is largely to prevent movement point mutations from changing a large chunk of a genome into useless moves. If the organism encounters another mode codon before it runs out of moves, it will switch to that mode, resetting the move counter.
Note
Organisms can share the same location; there are no collisions in the world of Biological Complexity.
When an organism is in protein mode, each chemical codon that it reads will cause the organism to attempt to add that chemical to its current protein. In order to do this, it must have 1 unit of the chemical in question. If it lacks the resources, the current protein is aborted and all the spent resources are refunded. If the environment is resource poor, of if gather_proportion is set low, it will take a long time before organisms acquire enough resources to begin protein construction.
The organism will keep adding to the protein until it changes modes, or until the protein reaches max_protein_length at which point the organism will reset to gather mode. In either case, the protein is completed and–providing that it is at least min_protein_length long–it will be added to the organism’s stock of proteins, potentially binding to other proteins, and modifying the organism’s function vector.
Each organism calculates its own fitness based on its genome length and the amount of chemicals that it has acquired over the course of a generation. For a detailed discussion of fitness and reproduction, see Fitness and Reproduction
An organism’s ability to gather chemicals is determined by its function vector. The function vector has one entry for each chemical in the environment. The entry multiplies the amount of that chemical that it can gather. An organism’s initial function vector will consist of 1’s for all chemicals that can be gathered without proteins, and 0’s everywhere else.
When an organism produces a protein, that protein’s function vector is added to the organisms. This happens for each copy of that protein that is produced. Thus, an organism with 10 copies of a protein that adds 2 to the entry for chemical 0 will be 20 times more effective at gathering chemical 0 than its neighbors without that protein. When two complexes (possibly proteins) bind, the reactant’s vectors are subtracted from the organism’s vector based on how much bound, and the product’s vector is added based on the amount created.
Pykaryote Organisms
Organism(environment, row=None, column=None, genome=<???>, chemicals=None, fit_scale=1.0, id=-1, ancestry=[], data=None, on_movement=None)
This class represents an organism in the simulation. It has a location, a genome, etc.
The self.complexes data structure is a bit complicated and deserves explanation.
complexes has an entry for each complex that the organism has. The entries are tuples with the following elements.
the complex
the current amount of the complex possessed by the organism
Args:
- environment: The environment in which this organism lives,
- used as a reference
- row (int): The row location in the environment. if None it will be
- chosen randomly
- column (int): The column location in the environment. if None it
- will be chosen randomly
genome (int or list): The genome of the organism, if a list, the genome will stay that way if an int, a genome of that length will be generated
chemical (list): The starting amount of chemicals owned by the organism. If None, the organism owns 0.0 of all chemicals
fit_scale (float): The fitness scaling factor. See the documentation for further details.
id (int): The id # for this organism w/in the generation.
ancestry (list): the list of ancestor id #’s
data (list): a list of control values for the organism, used only for reconstructing an organism.
ancestry: list
returns a copy of the organism with possible mutations, chemicals are not kept location may be kept based on global variables
builds: ‘int’
cell: numpy.ndarray
Computes the unscaled fitness benefit of a vector of chemicals.
This is used to calculate an organisms fitness.
chemicals: numpy.ndarray
column: ‘int’
complexes: dict
environment: object
failed_builds: ‘int’
fit_scale: ‘float’
The fitness function of the organism.
Each chemical contributes a set amount to the fitness. The chemicals provide diminishing returns.
Args:
genome_cost: if set to False, the genome fitness cost will not be subtracted from the organism.
function: numpy.ndarray
gathers: ‘int’
genome: numpy.ndarray
id: ‘int’
len: ‘int’
mode: ‘int’
move_count: ‘int’
moves: ‘int’
pos: ‘int’
Reads and executes codons from the genome.
This is the applications inner most loop, and accounts for most of the program runtime. If you’re looking to optimize, start here.
row: ‘int’
Copies a section of other’s genome into its own genome
Creates a default function vector. Capable of harvesting n0 complexes, but nothing else.