Long time ago I wrote a small program. It simulated a simple world with creatures and food. Creatures had "energy" which was lost when they moved, when energy was low, they "looked for food close by" to feed. When energy was high, they "looked for a suitable partner close by" to reproduce. When they reached food, they gained energy, when they reached a "suitable partner" they turned in 3 creatures with combined energy equally distributed among them.
To "look for", at each iteration, the creature randomly picked a test-target. If it had no current-target, the test-target was turned into its new current-target. If it had a current-target which was more distant than the test-target, then the test-target was copied to the current-target for the creature.
Creatures had a "threshold". When its energy was above the threshold, it entered "reproduction mode"; when its energy was below the threshold, it entered feed mode. A "suitable partner" was any other creature which was also in "reproduction mode". When they "reproduced" the new creature threshold was an average of the threshold of its parents plus a small random number.
It also had three settings: number of new generated creatures per unit of time, number of new food packs per unit of time and number of iterations per unit of time.
It had a very "real behavior". After a few minutes running, I usually set the "number of new generated creatures per unit of time" to 0 and watched creatures look for food and reproduction. Set a small number of food packs and watched famine, set it high and saw creatures thrive...
But, whenever it was the time to close the program, I had a small feeling. I didn't like stopping it. It was like killing an entire fishbowl.