Skip to content

Commit

Permalink
Add crossover spawning of new boppies
Browse files Browse the repository at this point in the history
  • Loading branch information
LiquidFun committed Feb 17, 2022
1 parent 32fa5e4 commit f402f88
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 26 deletions.
17 changes: 11 additions & 6 deletions Controllers/GameController/GameController.gd
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ func handle_boppie(boppie):
func _on_SpawnNewBoppie(at, dna):
add_boppie(at, boppie_configurations[0].scene, dna)

func add_boppie(at: Vector2, scene: PackedScene, dna=null):
func add_boppie(at: Vector2, scene: PackedScene, dna=null, dna2=null):
var instance = scene.instance()
if instance is Boppie:
if dna != null:
instance.set_dna(dna, 1)
instance.set_dna(dna, 1, dna2)
handle_boppie(instance)
instance.rotation = Globals.rng.randf() * 2 * PI
add_child(instance)
Expand All @@ -134,10 +134,15 @@ func add_boppie(at: Vector2, scene: PackedScene, dna=null):

func add_random_boppies(count: int, config: BoppieConfiguration):
for _i in range(count):
var old_dna = null
if config.fittest.size() == keep_n_fittest_boppies and Globals.rng.randf() > config.new_dna_chance:
old_dna = config.fittest[Globals.rng.randi() % keep_n_fittest_boppies][1]
add_boppie(random_world_coordinate(), config.scene, old_dna)
var dna1 = null
var dna2 = null
if config.fittest.size() >= 10 and Globals.rng.randf() > config.new_dna_chance:
var fittest_len = len(config.fittest)
var dna1_index = Globals.rng.randi() % fittest_len
var dna2_index = (dna1_index + (fittest_len - 1)) % fittest_len
dna1 = config.fittest[dna1_index][1]
dna2 = config.fittest[dna2_index][1]
add_boppie(random_world_coordinate(), config.scene, dna1, dna2)


func add_food(at: Vector2):
Expand Down
2 changes: 0 additions & 2 deletions Entities/Boppie/Boppie.gd
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ func initialize_dna():
func set_dna(new_dna: Dictionary, mutation_factor=0, crossover_dna=null):
new_dna = new_dna.duplicate(true)
for property in new_dna:
print(property)
var resolved_subproperty = self
var subproperties = property.split(".")
var last = subproperties[-1]
Expand All @@ -192,7 +191,6 @@ func set_dna(new_dna: Dictionary, mutation_factor=0, crossover_dna=null):
resolved_subproperty.crossover(property, crossover_dna[property])
if mutation_factor > 0:
resolved_subproperty.mutate(last, new_dna["offspring_mutability"] * mutation_factor)
print()
initialize_dna()

func mutate(property: String, mutability: float):
Expand Down
43 changes: 28 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,10 @@ Quickstart: after starting a simulation: press `9` to simulate quickly. After a
* Open Godot and import the `project.godot` file
* Now press on the play button to run it

## Ideas for features
## Ideas for future features

### Simulation

* Implement NEAT (Neuroevolution of Augmenting Topologies), such that the neural networks of the boppies change with each generation
* Innovation number (tracking of changes between species)
* Different parallel simulations where the best are merged into 1
* Merging of neural networks
* Add obstacles
* Add more senses for the boppies, such as:
* Instead of rays try neural network inputs with information for angle+distance
Expand All @@ -80,36 +76,53 @@ Quickstart: after starting a simulation: press `9` to simulate quickly. After a
* Add sexual reproduction, as in the real world merging DNA from two individuals has greatly benefited survival of the fittest
* Add loading/saving of simulations
* Add areas of high ground productivity (where more food spawns)
* Add (for example), a river in the middle of the map, which separates the species on the left/right of it.
* Encode how many creatures are reproduced in the DNA of the creature
* Make boppies leave flesh after death
* Change meat-eating from boolean to a float, where it essentially becomes meat-tolerance or meat effectiveness (a factor of how much energy can be gained from meat). However high meat-tolerance means low
* Add/extend boppie color as part of DNA
* Extend boppie color as part of DNA
* Ideas:
* HSL (where H is part of DNA, S shows energy, L = .5 or meat-tolerance )
* RGB (where R, G is part of DNA, B shows meat-tolerance)
* Add reinforcement learning
* Save which neurons most contributed to a reward in the last seconds (eating)/penalty (taking damage), increase the weights of those connections
* Drop in boppies from fitness list
* Show genetic tree for entire simulation
* Different parallel simulations where the best are merged into one

### UI/UX
* Add menu so that simulation could be configured
* Show additional senses (dangersense) near boppie
* Show genetic tree for entire simulation
* Improve graph by drawing lines instead of pixels
* Add more graphs
* Fittest creature each second
* Species stacked bar-plot
* Select different profiles for displaying neural network (weights or activations)
* Full screen on neural network, which shows actual weights
* Improve display of recurrent connections
* Check DNA importing, such that no object references are mentioned in the DNA
* Use textures on the ground (fertile vs infertile land)
* Disable spike rotation and blood in performance mode


## Changelog

### v0.2.0 (not yet released)
### v0.2.0 (2022-02-17)

* UI/UX Improvements
* Random seed is shown
* Can now drag boppies from fittest list into world
* Camera can now be moved by dragging the mouse
* DNA/Neural network as tabs, as they did not fit in a single column
* Neural networks now show what each input/output neuron means
* Neural networks can have any structure (not necessarily fully connected)
* Added an innovation number for each change in the neural network, as described in NEAT
* Added rotating traps with spikes and blood marks after death
* Added these senses for boppies:
* Danger sense (for detecting traps and kloppies)
* Camera can now be moved by dragging the mouse
* Random seed is shown
* Neural networks now show what each input/output neuron means
* DNA/Neural network as tabs, as they did not fit in a single column
* Added boppie color as part of DNA
* Can now drag boppies from fittest list into world
* Implemented NEAT (Neuroevolution of Augmenting Topologies), such that the neural networks of the boppies change with each generation
* Added an innovation number for each connection in the neural network, as described in NEAT
* Crossover of creature DNA and neural networks


### v0.1.0 (2021-10-19)

Expand Down
5 changes: 2 additions & 3 deletions UI/GameUI/Neurons.gd
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,8 @@ func _draw():
var left_pos = lookup_index_to_pos[connection[1][i]]
var weight = connection[1][i+1]
var dendron = weight * values[connection[1][i]]
var color = neuron_weight_gradient.interpolate((weight + 1) / 2.0)
# var color = Color.white
draw_line(left_pos, right_pos, color, abs(weight * 3))
var color = neuron_weight_gradient.interpolate((dendron + 1) / 2.0)
draw_line(left_pos, right_pos, color, abs(dendron * 3))

# Draw neurons
for index in lookup_index_to_pos:
Expand Down

0 comments on commit f402f88

Please sign in to comment.