/prey

Primary LanguageC#

Predator v Prey

Predator (blue) versus prey (yellow) simulator. This is inspired by AI Battles.

game2

The AI are driven by a neural networks that choose the direction and speed of movement. In the initial configuration the predators (blue) hunt and attack the prey (yellow). A series of experiments were run to guage the fitness of these networks (compared with a random movement AI). The results show that the average lifetime of a predator is 40-70% longer than moving randomly.

Basic Rules

The basic rules for the simulatio are that predators must eat prey to survive, and prey try to survive as long as they can.

game3

Predators

  • Movement consume energy, standing still consumes energy
  • Must consume prey in order to gain energy and reproduce
  • Once energy is depleted, they will die
  • Touching a prey is lethal
  • Eating when not fully digested their previous meal will gain energy, but not contribute to their next reproduction
  • The field of vision is narrow and long

Prey

  • Movement consumes energy, standing still replenishes energy
  • Reproductio happens as long as they stay alive long enough
  • Once energy is depleted, they cannot move
  • The field of vision is wide and short

Optional rules include allowing prey to fight back and kill predators, requiring N hits to deal a lethal hit, etc.

Mechanics

The AI are governed by a set of meters that are adjusted for every update. An update is designed to happen 10 times a second. Predators and prey have specific costs/update for each of these meters.

  • Energy - needed to move/survive
  • Digestion - (predator) when still digesting, eating more prey does not lower the reproduction meter
  • Reproduction
    • (predator) adjusts when digesting prey
    • (prey) adjusted per update
  • Attack - a cool down between each attack

Each AI also has a Health meter, which is only adjusted if attacked by an AI of the opposite type.

The field of view is generated by extending rays out in front of the AI and returning the objects that are the closest.

game1

Movement and speed are determined by two neural networks. These neural networks are trained by actions that the AI take. At first, the actions are largely random, but as the AI survives the actions are reinforced by actions that yield longer life. New AI have a chance to inhert traits from their parents or the best surviving AI.

Experiments

Experiments are run to track if neural network trained AI can have extended average lifetimes to random AI. The termination conditions for the experiments are either of the populations are extinct, or a maximum lifetime is reached (maximum number of updates).

The minimum / maximum lifetimes: (without being killed)

  • Predator - 200 thru 1000 (even further if consuming prey)
  • Prey - maxium lifetime (per the basic rules, prey will stay still once energy is depleted)

Small experiment

The small experiments have a limit of ~1,000 AI. This is a great experiment to visualize how the modes evolve and interact.

Configuration:

  • Width - 6,400
  • Height - 6,400
  • Predator (initial/max) - 50/170
  • Prey (initial/max) - 300/800
  • Combat - variable (peaceful or aggressive)
  • Random - variable
  • Iterations - 10
  • Max Lifetime - 5,000
./simulationcli -width 6400 -height 6400 -initialpred 50 -initialprey 300 -maxpred 170 -maxprey 800 -combat $0 -random $1 -it 10 -maxl 5000
Predator (peaceful) v Prey (peaceful)

This configuration is useful for a baseline, it will help determine local minimums for the predators as they require combat (eating) to survive. The average lifetime of predator (neural) was 70% higher than predator (random). The average lifetime for predators (neural) were 586-589 updates, where as predator (random) was 333-334 updates.

data Predator (neural) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
067308006720104210
169808006961006060
267508006722005890
368908006883006160
468008006804005600
571008007085006180
667108006696006260
771208007107006090
867608006768106110
970308007029006060
Predator (random) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
035908003590003340
136208003601003380
235508003522103340
336508003643103350
436408003644113340
535408003535003310
637008003700003350
735508003551103320
836008003592003350
936508003633003350
Predator (neural) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
067608006680004290
167408006741006140
270108006902006200
369908006923006130
470008006844006110
570008006945006090
668908006726006040
768708006867006010
869108006888005880
97060800696910604
Predator (random) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
035908013520003300
138708003721103340
236708003592003350
336108003523003340
436808003544003360
537108003635103330
636308003576003330
738108003720003350
835308003511003320
936908003562003350
Predator (aggressive) v Prey (peaceful)

This is the default configuration, the predators hunt the prey. The predator lifetime saw a 40% increase when using the predator (neural) over predator (random). The average lifetime of predator (neural) was 670-818 updates, where as predator (random) was 514-559 updates.

data Predator (neural) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
050001708002490532882396238
1500017080019121144953651560
24086080016741233635841610
34221080016891433357855519
44597080016811739568842826
5500017079917881838999469302
65000166800200425430611486383
739050800141426370513774431
842350800161427321114860585
9500016680115518406815535339
Predator (random) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
050001707972020525429545251
15001157800230210264812518243
2500116979020381432126512247
3500016679923052339399511270
45000169800201332340911512259
55000170794160839346919516269
65000170797163847336523494283
75000169800190454314525545260
85001168799178664293226492285
95000169799176272361027499273
Predator (neural) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
050021698002278143861675414
150001708001688431167630321
2500017080023148354111726353
350031708002645944811943542
4500417080123371344450769436
5500116979927881842674919519
6500217080031361940116904528
75005167800310121451710922522
85008168800283423439415958526
95002168799262526409318740336
Predator (random) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
050071698002371326796546270
1500517079722181030769534273
2500116980022791130165545269
3500117080021681827127562263
45002169797192723312713577259
55000170800176526309020557272
65004170801199627264424579265
7500216979722142829040549274
8500616779820963125745566264
950001707992074732298583256
Predator (peaceful) v Prey (aggressive)

This configuration has a double negative for predators, they are not able to reproduce (as they cannot eat) and prey are agressive. There was a significant drop (2x) in average lifetimes for predators compared with the baseline.

data Predator (neural) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
048608004860102110
146108004611001380
264908006482002090
367608006763002350
451208005124101920
569808006985003170
664208006426001990
765208006527001820
843908004388001460
966608006669001930
Predator (random) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
034708003460001710
135108003501101840
235808003582002310
334208013423001820
436208003614001860
534708003475001800
634708003466001770
734208003427001550
834008003408001890
933608003359001660
Predator (neural) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
038008003760001610
131008013081121430
261208006042001770
341308004063121440
452108005194131740
539508003945001700
669208006916221720
760708006020131650
852308005141001820
954008005392001510
Predator (random) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
034108003370121500
134908003441001830
235308003482001810
332708003223001720
435208003454001620
532208003205001440
634908003396101760
735408003497001850
833608003318001650
933508003319001770
Predator (aggresive) v Prey (aggressive)

This is the purge mode, everyone is attacking everyone. The prey seem to have the advantage as they have the numbers and significantly reduce (5x) the length of the game, espeically once the prey (neural) model is trained.

data Predator (neural) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
0454308008092419902981618
150011080010551640371315445
23621080012891727371336416
39130800486188652172169
4649080064803313193105
5717080071615174260102
672608007262408524088
772908007293345725481
877008007700326824898
97020800702147010227104
Predator (random) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
04448080056011412702841102
15000488009123239603344615
25000148007943838016324562
35000178008225646568348816
450001008008006047571322665
58470800510616943204202
6177208004226514284197202
75190800436664820198118
8681080042767594120990
9829080041607223176232
Predator (neural) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
05000298005494497702031577
1720080048056691193188
2713080147565962205183
3847080143076534200149
4730080043885726231162
5661080044894707221137
6538080046804358195135
7780080046527040235183
818370802436318161211495
9866080040645913233181
Predator (random) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
01019080045718691216155
120390800508618952222395
2875080047276974231184
312210800420811145214252
4168008005261214630233219
5930080040108700221166
6635080043215981228147
717780800467215583220363
8526080047143945224136
912380800508010466245233

Large experiment

The large experiments have a limit of ~16,000 AI, an increase of 16x over the small experiment.

Configuration:

  • Width - 16,000
  • Height - 16,000
  • Predator (initial/max) - 800/800
  • Prey (initial/max) - 4800/13000
  • Combat - variable (peaceful or aggressive)
  • Random - variable
  • Iterations - 5
  • Max Lifetime - 10,000
./simulationcli -width 16000 -height 16000 -initialpred 800 -initialprey 4800 -maxpred 800 -maxprey 13000 -combat $0 -random $1 -it 10 -maxl 10000 
Predator (aggressive) v Prey (peaceful)

This larger configuration provides more space, more predators, and more prey. Predator lifetime saw a 75% increase when using the predator (neural) over predator (random). The average lifetime of predator (neural) was 1183 updates, where as predator (random) was 674 updates. In addition, prey (neural) lifetime was 55% longer than prey (random).

data Predator (neural) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
010000800119228127157460854323
1100008001299798982934521187531
2100008001299789563966431188479
3100008001299888814993941283644
4100008001300097055981061405612
Predator (random) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
0100008001299964145542811719327
11000080013000394818468821667341
21000080012997563829574032656335
31000080013000396642528037652328
41000079812991420455505345680333
Predator (aggresive) v Prey (aggressive)

This configuration continues to be a struggle for predators, as prey are aggressive and attack back. Predator (neural) and predator (random) were within 8%, with random trending better. Prey (neural) average lifetime was nearly 4x higher than prey (random).

data Predator (neural) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
086090130007120797711991327
14280130004281333210377
24050130003882372010077
310000104130007863999412082408
47330130007064720013583
Predator (random) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
0108401300052209540162145
11335013000554113201161172
24201013000470341612158391
399601299959249453162153
486901300057557894162139

Long running

This experiment was to see if over the long term who wins: predators or prey. When predator (neural) and prey (nerual) are active, it was a toss up with prey winning more often. When predator (random) and prey (random) are active, the predators win. If you visualize the difference between predator (neural) and predator (random), predator (random) holds even distribution across the board (eg. playing zone defense). Whereas predator (neural) sweeps the prey away and follows the respan around the board. The later approach can cause mass extinction if there are no predators in the zone where prey are spawning.

Configuration:

  • Width - 6,400
  • Height - 6,400
  • Predator (initial/max) - 50/170
  • Prey (initial/max) - 300/800
  • Combat - Predator
  • Random - variable
  • Iterations - 5
  • Max Lifetime - 100,000
simulationcli.exe -width 6400 -height 6400 -initialpred 50 -initialprey 300 -maxpred 170 -maxprey 800 -combat 1 -random 0 -it 5 -maxl 100000 
Predator (aggressive) v Prey (peaceful)
data Predator (neural) v Prey (neural)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
052413167020849541541466321
140462080037715316975457821062
232140800148455257246790616
3267371560252868871147486461
4548008001609734887488411169
Predator (random) v Prey (random)
IterationLifetimeAlivePredatorsAlivePreyBestPredatorLifetimeBestPredatorGenerationBestPreyLifetimeBestPreyGenertationAvgPredatorLifetimeAvgPreyLifetime
05227116802134158426557475315
14390716302287283408669480317
22682316502236304387084470311
331292169017873234139148473322
421914166019613644727161483308

Next steps

There is a lot more tuning possible in this experiment.
A few areas of focus:

  • nerf prey attacks (as they currently are like a hord of unstoppable zobmies and overwhelm the predators)
  • further tuning of AI meters
  • allow for longer sight by predators
  • perform a tuning experiment to find the cross over points of where predators dominate, prey dominate, and a balance

Trying

This project is build able with Visual Studio 2022 or later. Below are the steps to reproduce these experiments.

Visual representation (Windows only)

simulation.exe

Cross platform and on the command line.

./simulationcli.exe

This is all the available options for trying out the simulation from the command line.

./simulationcli.exe -help
./simulationcli
  -(help)             : this help
  -(w)idth            : the 2d width of the environment (default: 6400)
  -(hei)ght           : the 2d height of the enviorment (default: 6400)
  -(initialPred)ators : the initial number of predators at start (default: 50)
  -(maxPred)ators     : the max number of predators (default: 170)
  -(initialPrey)      : the initial number of prey at start (default: 300)
  -(maxPrey)          : the max numbre of prey (default: 800)
  -(c)ombat           : allowed combat (0: none, 1:Predators, 2:Prey, 3:Predators+Prey) (default: 1)
  -(r)andom           : random movement (0: none, 1:Predators, 2:Prey, 3:Predators+Prey) (default: 0)
  -(it)erations       : number of training runs (a run stops when either Predators or Prey are extinct) (default: 10)
  -(maxl)ifetime      : maximum number of updates per iteration (default: 5000

Initialization

git submodule init
git submodule update