// geneCruft.c // K. J. Rock // October 31, 2024 Energy genes: ->EN in all organisms 7 b metabolism 2^7 = 128 3 b absorption 2^3 = 8 9 b satiety 2^9 = 512 3 b maturity 2^3 = 8 10 b senescence 2^10 = 1024 Plant genes: ->PL 6 bits pollination probability 2^6 = 64 6 bits poison probability => to camouflage% 6 bits poison strength 6 bits spine probability 6 bits spine length => to scent strength 2 bits free Herbivore genes: ->HB 5 bits probability of running when carnivore sensed 5 bits probability of hiding 5 bits percent camouflage effectiveness 5 bits ability to eat spiny plants 5 bits ability to withstand poison (should affect energy absorbed by strength of poison) 5 bits escape range leap? 2 bits speed 2^2 = 4 Carnivore genes: ->CN 6 bits attack probability when herbivore sensed 2 bits attack range 2^2 4 is more accurate 0 to 3 6 bits sleep probability affected by energy level hungry or sated? 6 bits hide probability 2^6 64 bit value/64 = % value 6 bits percent camouflage effectiveness 3 bits pursuit max 2^3 8 steps is about right 2 bits speed speed gene It would scale the dir[] vector 1 free Five senses { sight, hearing, smell, taste, touch } Sensor genes: ->SN in herbivores and carnivores 8 bits sight camouflage effectiveness would be tested here 8 bits hearing hear predator or prey 8 bits smell 32-24 = 8 smell poison or prey 4 bits taste taste poison, touch spines 4 bits touch 2^4 = 16 pursue vibration of ground?? or hide if sensed Direction genes: ->DR in herbivores and carnivores 4 bits East probability 4 bits West probability 4 bits North probability 4 bits South probability 4 bits Northeast probability 4 bits Southeast probability 4 bits Northwest probability 4 bits Southwest probability (PL+i)->EN for energy genes { metabolism, absorption, satiety, maturity, senescence } (PL+i)->PL for plant genes { pollination%, poison%, poison strength, spine%, spine length } (HL+i)->HB for herbivore genes { run%, hide%, camo%, eat spine%, eat poison% } (CL+i)->CN for carnivore genes { attack%, attack range, sleep%, hide%, camo%, pursuit time } (HL+i)->SN for sensor genes { touch range, hearing range, seeing range, smelling range } (CL+i)->DR for direction genes { E, W, N, S, NE, SE, NW, SW } // Genetic information for each gene in each chromosome Direction genes: ->DR direction probability chromosome // * indicates gene is implemented dirProb[8] = (float) (DR & 15); DR::G8 move SW SE * dirProb[7] = (float) ((DR & (15 << 4)) >> 4); DR::G7 move NW S * dirProb[6] = (float) ((DR & (15 << 8)) >> 8); DR::G6 move SE SW * dirProb[5] = (float) ((DR & (15 << 12)) >> 12); DR::G5 move NE W * dirProb[4] = (float) ((DR & (15 << 16)) >> 16); DR::G4 move S NW * dirProb[3] = (float) ((DR & (15 << 20)) >> 20); DR::G3 move N N * dirProb[2] = (float) ((DR & (15 << 24)) >> 24); DR::G2 move W NE * dirProb[1] = (float) ((DR & (15 << 28)) >> 28); DR::G1 move E E * metab = (float) (EN & 127) + 1.0; EN::G5 1 - 128 * absorb = (float) (((EN & (7 << 7)) >> 7) + 1.0) / 16.0; EN::G4 6.25 - 50.0% * satiety = (float) (((EN & (511 << 10)) >> 10) + 1.0 ; EN::G3 1 - 512 * maturity = (int) (((EN & (7 << 19) >> 19)) + 1; EN::G2 1 - 8 * senescence = (int) (((EN & (1023 << 22) >> 22)) + 1; EN::G1 1 - 1024 days * pollen = (float) ((PL+i)->PL & 63) / 63; PL::G5 pollination probability poison = (float) (((PL+i)->PL & (63 << 6)) >> 6) / 63; PL::G4 poison prob camouflage * strength = (float) (((PL+i)->PL & (63 << 12)) >> 12) / 63; PL::G3 poison strength * spine = (float) (((PL+i)->PL & (63 << 18)) >> 18) / 63; PL::G2 spine probability * length = (float) (((PL+i)->PL & (63 << 24)) >> 24) / 63; PL::G1 spine length Scent strength see = (float) ((HL+i)->SN & 255) / 255.0; SN::G5 sight ability * hear = (float) (((CL+i)->SN & (255 << 8)) >> 8) / 255.0; SN::G4 hearing ability smell = (float) (((HL+i)->SN & (255 << 16)) >> 16) / 255.0; SN::G3 scent capability taste = (float) (((HL+i)->SN & (15 << 24)) >> 24) / 15.0; SN::G2 taste sense touch = (float) (((HL+i)->SN & (15 << 28)) >> 28) / 15.0; SN::G1 touch sensitivity run = (float) ((HL+i)->HB & 31) / 31.0; HB::G7 run probability hide = (float) (((HL+i)->HB & (31 << 5)) >> 5) / 31.0; HB::G6 hide probability camo = (float) (((HL+i)->HB & (31 << 10)) >> 10) / 31.0; HB::G5 camouflage effectiveness * eat = (float) (((HL+i)->HB & (31 << 15)) >> 15) / 31.0; HB::G4 ability to eat spines * withstand = (float) (((HL+i)->HB & (31 << 15)) >> 15)/31.0; HB::G3 withstand poison * escape = (int) ((HL+i)->HB & (31 << 25)) >> 25; HB::G2 escape range speed = (int) ((HL+i)->HB & (3 << 30)) >> 30; HB::G1 speed gene 2 b?? * attack = (float) ((CL+i)->CN & 63) / 63.0; CN::G7 attack probability range = (float) (((CL+i)->CN & (3 << 6)) >> 6) / 3.0; CN::G6 attack range sleep = (float) (((CL+i)->CN & (63 << 8)) >> 8) / 63.0; CN::G5 sleep probability hide = (float) (((CL+i)->CN & (63 << 14)) >> 14) / 63.0; CN::G4 hide probability camo = (float) (((CL+i)->CN & (63 << 20)) >> 20) / 63.0; CN::G3 camouflage effectiveness time = (int) ((CL+i)->CN & (7 << 26)) >> 26; CN::G2 maximum pursuit time speed = (int) ((CL+i)->CN & (3 << 29)) >> 29; CN::G1 speed gene 2 b?? * Then H->SN::See > P->PL::Camo eat() and H->SN::Smell > P->PL::Scent eat() if P->PL::Pollen and P->EN::Age fit criteria reproduce() Plant can breed from age 3 to age 5 if I am not mistaken or at age == 4 and 5 to be more accurate then senescence This means it can pollinate twice and it can be pollinated twice Or we could extend the range downward If age == 3 then reproduce() if pollen/2 > xx at age == 4 reproduce() if pollen > xx at age == 5 reproduce() 32 bits ->EN Metabolism gene - How much energy do I use each day? Absorb gene - How much energy can I gain per plant (or herb)? Satiety gene - When am I full? Maturity gene - When am I old enough to reproduce? Senescence gene - How long can I live (if not eaten)? Separate speed from eat radius moveCarnivore(), moveHerbivore() should use speed not eat(). It should have its own gene: eat radius Make both CN::Speed and HB::Speed larger 4 bits instead of just two HB::{ camo, eat spine, withstand poison, move speed } useful and expressed CN::{ speed, ?? } useful. Now rework both HB and CN with more useable genes. What do we need? Eat radius is good. Move speed can be 4 bits for HB and 5 bits for CN with modifiers of course. Herbivore run/hide choice implies the ability to run so maybe a high gear speed gene? And run/hide is a continuum not a toggle switch so HB::run at 90% would trigger running HB::run below a certain threshhold would trigger hiding. HB::run would trigger moveHerbivore() to use HB::High speed gene Then a limit on how many cycles to hold the frightened state CN::attack/rest is also a continuum CN::chase would be a high speed gear for chasing CN::pursuit time would be number of cycles for chase CN::attack would also trigger a higher metabolic rate, same for Herbivores Thus CN::metab and HB::metab for the higher rates. Is this metabolic process separate from metabolism()?? CN::camouflage is still valid. If HB->SN::see < CN::camo then HB gets eaten. Do we need Boolean flags for keying higher metabolic rates in metabolism() or do we extract the energy from the running organisms directly? I say we modify metabolism() to notice the change. Because it also sums the energy used by all of the organisms throughout this cycle. Why keep track of that in two places which would require a global variable? We could check HB::run/hide and CN::attack/rest against each other in metabolism() Just as we are checking genes inside other functions. Or extract the normal metabolic() energy rate and extract more in moveHerb() moveCarn() at the higher metabolic rate. moveHerbivore() & moveCarnivore() need to access the SN genes of each of them That will fulfill the SN::taste, SN::touch, SN::smell, SN::see can be implemented. SN::hear - not yet. Implement a move/do not move continuum with your sensing For example: while you are moving you search for a cell which is NOT occupied by a similar organism. Along the way you can collect information about each cell you visit along the way. Sense the presence of a herbivore, plant, or carnivore. Rethink PL HB and CN chromosomes. There is too much overlap Poison strength and probability? Spine length and probability? Both of these seem redundant. Hide and camo in both HB and CN are also redundant. Pick one Then you will have room for traits you can express. Reevaluate attack probability and range, sleep, hide, camo, max pursuit time in CN Herbivore genes also need pruning and editing and additions Plants can have a scent Or they could be camouflaged in some way So two SN genes: smell, touch vs two PL genes scent, camo Herbivores can have a scent so HB::scent vs carnivore SN::smell How do we compare run and chase? HB::CN Attack vs defend?? CN::HB Check how many times you make a oice in eat() or reproduce() moveCarnivore(), moveHerbivore(), and eat() use loops to find a different location in the ecosystem. In so doing it can 'sense' P, H, and C populations nearby. How can we use this information efficiently? if( (E +Y*SZ +X)->H) (CL+i)->Hsense[ k ]++; Where k is direction vector array index. Sense along rings of 8 points at the Cardinal directions E,NE,N etc. Sum P,H,C in dir[i] put into sense[8]; Each Herbivore and each carnivore can have another attribute:sense[] Carnivores only need one sense[] array which totals H found along the way Herbivores need two because they are seeking plants while avoiding carnivores So H->Psense[] and H->Csense[] ?? or similar How about a sensing function which scans both herbivore and carnivore lists then senses outward to a certain limiting ring value. Some amalgam of sight, sound, and smell. For now let us stick to sense, not which one, just the ability to sense. if( (E +Y*SZ +X)->P Where A holds the current location (E +Y*SZ +X)->H These references need to be with (E +Y*SZ +X)->C respect to that point along dir[i] Think about a genetic marker chromosome, GM. It can contain 31 bits of information. It is passed on in one chunk from the mother to her offspring. There is NO crossover with a matching paternal GM chromosome. We could use it to mark specific populations of organisms generated by the user and implemented as a second sample pool inside useSamples(). Since the chromosome is monolithic we can trace whether the user created viable organism samples or not. Run a count on GM of a certain type. Remember to initialize GM to be all zeros so any difference triggers a flag. We could mark the various sample pools with different GM settings. Then determine how they compete for resources with one another. A^2 - (A-2)^2 = the perimeter, if A is an odd number greater than 1 3 - 1 = 8 1::1 25 - 9 = 16 1::2 49 - 25 = 24 1::3 81 - 49 = 32 1::4 Sensor search compression ratio ??? if( SN::G1->smell > PL::G4->poison ) do not eat if( SN::G1->taste > PL::G4->poison ) if( SN::G4->touch > PL::G2->spine ) do not eat if( HB::G3->withstand > PL::G3->strength ) eat() but EN::G4->absorb * 0.4 or more if( EN::G2->maturity && EN::G1->senescence > PL::G5->pollen ) mate if( SN::G2->see > HB::G5->camo ) eat if( SN::G3->hear > HB::G6->hide ) eat Camouflage is susceptible to better vision. Poison is sensed by better smell and/or taste. Carnivores could be sensed by better sight, hearing, or smell Herbivores could be sensed through the same mechanisms. Carnivores need to sense herbivores: camo, sight, smell, vibration - touch or hearing if( fRan() < PL::G5->pollen ) spread your seed Link this trait to the age of the plant. Older plants, nearing senescence, increase the probability of pollenation. If PL::G5->pollen = 75% (0.75) then any chance less than 0.75 allows pollenation. Senescence: at 5 cycles PL::G5->pollen = 100%?? 95% at 4 cycles or EN::G1->senescence - 1 PL::G5->pollen * 0.5 at 3 cycles or EN::G1->senescence - 2 PL::G5->pollen * 0.25 How do I combine spine probability with spine length to get a reasonable metric for comparison with the ability to eat spiny plants? Ability to eat poisoned plants EP ranges from none to all or 0.0 to 1.0 probability It competes with poison probability (concentration) PP combined with poison strength PS. PP ranges from 0.0 to 1.0 PS from 0.0 to 1.0 Now, how do I combine PP and PS??? PP * PS gives 0.0 to 1.0 if PP=0.5 * PS=0.8 = 0.4 0.9 * 0.9 = 0.81 if( EP > PP * PS ) eat(); Equality goes to the plant if( PS > 95 && EP < 50 ) ->alive = false; H->energy to E(x,y)->nutrient 6 bits poison probability 2^6 = 64 6 bits poison strength - eat() herbivore module 6 bits spine probability 6 bits spine length 5 bits ability to eat spiny plants HB::G4 2^5 = 32 5 bits ability to withstand poison (should affect energy absorbed by strength of poison) 32 bits EN Rebuild the Energy Chromosome. Metabolism gene - how much energy do I use each day 2^7 = 128 Absorb gene - how much energy can I gain per plant (or herb) 2^3 = 8 or %? Satiety gene - when am I full? 2^9 = 512 Maturity gene - old enough to reproduce? 2^3 = 8 Senescence gene - how long can I live (if not eaten) 2^10 = 1024 ### Energy use notes metab = (float) (EN & 127) + 1.0; EN::G5 1.0 - 128.0 absorb = (float) ((EN & (7 << 7)) >> 7) + 1.0) / 16.0; EN::G4 6.25 - 50.0% satiety = (float) ((EN & (511 << 10)) >> 10) + 1.0; EN::G3 1.0 - 512.0 satiety = (float) ((EN & (15 << 10)) >> 10) + 0.1; 0.1 - 15.1 max satiety = (float) ((EN & (15 << 10)) >> 10) + 14.0; 14.0 - 29.0 max maturity = (int) ((EN & (7 << 19)) >> 19) + 1; EN::G2 1 - 8 days senescence = (int) ((EN & (1023 << 22)) >> 22) + 1; EN::G1 1 - 1024 days senescence = (int) ((EN & (31 << 22)) >> 22) + 8; 8 - 39 days P->energy += E(x,y)->nutrient * absorb 1 cell possible absorb = (float) ((((PL+i)->EN & (7 << 7)) >> 7) + 1.0) / 18.0; 5.5 to 44.4% max H->energy += P(x,y)->energy * absorb * 8 * 12 rings 96 cells possible speed = (int) (((HL+i)->HB & (15 << 28)) >> 28) + 12; 30 out of 96 chances absorb = (float) ((((HL+i)->EN & (7 << 7)) >> 7) + 1.0) / 13.0; 7.7 to 61.5% max C->energy += H(x,y)->energy * absorb * 8 * 12 rings 96 cells possible speed = (int) (((CL+i)->CN & (15 << 28)) >> 28) + 12; 12*8 = 96 for 40 out of 96 absorb = (float) ((((CL+i)->EN & (7 << 7)) >> 7) + 1.0) / 18.0; 5.5 to 44.4% max // TODO update this Plant energy init 50 PFA ## metabolism 6.1 - 13.1 EN::G5 eat satiety 20.1 - 83.1 EN::G3 absorb 1/16 - 8/18 EN::G4 reproduction maturity 0 - 3 EN::G2 energy 5.6 PFA ## die 3 - 10 EN::G1 Herbivore energy init 100 metabolism 2.2 - 9.2 EN::G5 eat speed 0 - 15 ???? HB::G1 satiety 20.1 - 275.1 EN::G3 absorb 0.1 - 0.8 EN::G4 reproduction maturity 2 - 9 EN::G2 energy 25.0 PFA ## die 19 - 50 EN::G1 Carnivore energy init 700 PFA ## metabolism 5.4 - 36.3 EN::G5 eat speed 0 - 15??? CN::G1 satiety 20.1 - 275.1 EN::G3 absorb 1/9 - 8/9 (0.89) EN::G4 reproduction maturity 2 - 9 EN::G2 energy 63.1 PFA ## die 25 - 56 EN::G1 #endif see = (float) ((CL+i)->SN & 255) / 255.0; SN::G5 sight range hear = (float) (((CL+i)->SN & (255 << 8)) >> 8) / 255.0; SN::G4 hearing ability smell = (float) (((HL+i)->SN & (255 << 16)) >> 16) / 255.0; SN::G3 scent capability taste = (float) (((HL+i)->SN & (15 << 24)) >> 24) / 15.0; SN::G2 taste sense touch = (float) (((HL+i)->SN & (15 << 28)) >> 28) / 15.0; SN::G1 touch sensitivity Hard wire plant senescence at 5 cycles Then set its maturity at 3 or 4 cycles. Thus each could create two or three offspring. They can get eaten at any age from 1 to 5 cycles. pollen = (float) ((PL+i)->PL & 63) / 63; PL::G5 pollination probability