Merge pull request #129 from MaxRobinsonTheGreat/develop

Develop
This commit is contained in:
Max Robinson
2022-04-16 18:52:07 -05:00
committed by GitHub
8 changed files with 82 additions and 73 deletions

48
package-lock.json generated
View File

@@ -222,9 +222,9 @@
"dev": true "dev": true
}, },
"ansi-regex": { "ansi-regex": {
"version": "4.1.0", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
"dev": true "dev": true
}, },
"ansi-styles": { "ansi-styles": {
@@ -1089,24 +1089,24 @@
} }
}, },
"elliptic": { "elliptic": {
"version": "6.5.3", "version": "6.5.4",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"bn.js": "^4.4.0", "bn.js": "^4.11.9",
"brorand": "^1.0.1", "brorand": "^1.1.0",
"hash.js": "^1.0.0", "hash.js": "^1.0.0",
"hmac-drbg": "^1.0.0", "hmac-drbg": "^1.0.1",
"inherits": "^2.0.1", "inherits": "^2.0.4",
"minimalistic-assert": "^1.0.0", "minimalistic-assert": "^1.0.1",
"minimalistic-crypto-utils": "^1.0.0" "minimalistic-crypto-utils": "^1.0.1"
}, },
"dependencies": { "dependencies": {
"bn.js": { "bn.js": {
"version": "4.11.9", "version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
"dev": true "dev": true
} }
} }
@@ -1706,9 +1706,9 @@
"dev": true "dev": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true "dev": true
}, },
"interpret": { "interpret": {
@@ -2934,9 +2934,9 @@
} }
}, },
"ssri": { "ssri": {
"version": "6.0.1", "version": "6.0.2",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz",
"integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"figgy-pudding": "^3.5.1" "figgy-pudding": "^3.5.1"
@@ -3569,9 +3569,9 @@
"dev": true "dev": true
}, },
"y18n": { "y18n": {
"version": "4.0.0", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"dev": true "dev": true
}, },
"yallist": { "yallist": {

View File

@@ -204,7 +204,6 @@ class ControlPanel {
if (!env.reset(true, false)) return; if (!env.reset(true, false)) return;
let center = env.grid_map.getCenter(); let center = env.grid_map.getCenter();
let org = this.editor_controller.env.getCopyOfOrg(); let org = this.editor_controller.env.getCopyOfOrg();
this.env_controller.add_new_species = true;
this.env_controller.dropOrganism(org, center[0], center[1]) this.env_controller.dropOrganism(org, center[0], center[1])
}); });
$('#save-env').click( () => { $('#save-env').click( () => {
@@ -464,8 +463,6 @@ class ControlPanel {
if (mode == Modes.Clone) { if (mode == Modes.Clone) {
this.env_controller.org_to_clone = this.engine.organism_editor.getCopyOfOrg(); this.env_controller.org_to_clone = this.engine.organism_editor.getCopyOfOrg();
this.env_controller.add_new_species = this.editor_controller.new_species;
this.editor_controller.new_species = false;
} }
} }

View File

@@ -3,6 +3,7 @@ const Modes = require("./ControlModes");
const CellStates = require("../Organism/Cell/CellStates"); const CellStates = require("../Organism/Cell/CellStates");
const Directions = require("../Organism/Directions"); const Directions = require("../Organism/Directions");
const Hyperparams = require("../Hyperparameters"); const Hyperparams = require("../Hyperparameters");
const Species = require("../Stats/Species");
class EditorController extends CanvasController{ class EditorController extends CanvasController{
constructor(env, canvas) { constructor(env, canvas) {
@@ -10,7 +11,6 @@ class EditorController extends CanvasController{
this.mode = Modes.None; this.mode = Modes.None;
this.edit_cell_type = null; this.edit_cell_type = null;
this.highlight_org = false; this.highlight_org = false;
this.new_species = false;
this.defineCellTypeSelection(); this.defineCellTypeSelection();
this.defineEditorDetails(); this.defineEditorDetails();
this.defineSaveLoad(); this.defineSaveLoad();
@@ -46,7 +46,6 @@ class EditorController extends CanvasController{
else if (this.right_click) else if (this.right_click)
this.env.removeCellFromOrg(this.mouse_c, this.mouse_r); this.env.removeCellFromOrg(this.mouse_c, this.mouse_r);
this.new_species = true;
this.setBrainPanelVisibility(); this.setBrainPanelVisibility();
this.setMoveRangeVisibility(); this.setMoveRangeVisibility();
this.updateDetails(); this.updateDetails();
@@ -134,6 +133,9 @@ class EditorController extends CanvasController{
this.refreshDetailsPanel(); this.refreshDetailsPanel();
this.env.organism.updateGrid(); this.env.organism.updateGrid();
this.env.renderFull(); this.env.renderFull();
this.env.organism.species = new Species(this.env.organism.anatomy, null, 0);
if (org.species_name)
this.env.organism.species.name = org.species_name;
if (this.mode === Modes.Clone) if (this.mode === Modes.Clone)
$('#drop-org').click(); $('#drop-org').click();
// have to clear the value so change() will be triggered if the same file is uploaded again // have to clear the value so change() will be triggered if the same file is uploaded again

View File

@@ -12,7 +12,6 @@ class EnvironmentController extends CanvasController{
super(env, canvas); super(env, canvas);
this.mode = Modes.FoodDrop; this.mode = Modes.FoodDrop;
this.org_to_clone = null; this.org_to_clone = null;
this.add_new_species = false;
this.defineZoomControls(); this.defineZoomControls();
this.scale = 1; this.scale = 1;
} }
@@ -171,15 +170,15 @@ class EnvironmentController extends CanvasController{
var new_org = new Organism(col, row, this.env, organism); var new_org = new Organism(col, row, this.env, organism);
if (new_org.isClear(col, row)) { if (new_org.isClear(col, row)) {
if (this.add_new_species){ let new_species = !FossilRecord.speciesIsExtant(new_org.species.name);
if (new_org.species.extinct) {
FossilRecord.resurrect(new_org.species);
}
else if (new_species) {
FossilRecord.addSpeciesObj(new_org.species); FossilRecord.addSpeciesObj(new_org.species);
new_org.species.start_tick = this.env.total_ticks; new_org.species.start_tick = this.env.total_ticks;
this.add_new_species = false;
new_org.species.population = 0; new_org.species.population = 0;
} }
else if (this.org_to_clone.species.extinct){
FossilRecord.resurrect(this.org_to_clone.species);
}
this.env.addOrganism(new_org); this.env.addOrganism(new_org);
new_org.species.addPop(); new_org.species.addPop();

View File

@@ -72,7 +72,6 @@ class OrganismEditor extends Environment{
this.organism = new Organism(center[0], center[1], this, orig_org); this.organism = new Organism(center[0], center[1], this, orig_org);
this.organism.updateGrid(); this.organism.updateGrid();
this.controller.updateDetails(); this.controller.updateDetails();
this.controller.new_species = false;
} }
getCopyOfOrg() { getCopyOfOrg() {
@@ -109,7 +108,6 @@ class OrganismEditor extends Environment{
newOrganism.species = new Species(newOrganism.anatomy, null, 0); newOrganism.species = new Species(newOrganism.anatomy, null, 0);
var col = Math.floor(size + (Math.random() * (env.grid_map.cols-(size*2)) ) ); var col = Math.floor(size + (Math.random() * (env.grid_map.cols-(size*2)) ) );
var row = Math.floor(size + (Math.random() * (env.grid_map.rows-(size*2)) ) ); var row = Math.floor(size + (Math.random() * (env.grid_map.rows-(size*2)) ) );
env.controller.add_new_species = true;
env.controller.dropOrganism(newOrganism, col, row); env.controller.dropOrganism(newOrganism, col, row);
} }
} }

View File

@@ -36,10 +36,10 @@ class WorldEnvironment extends Environment{
to_remove.push(i); to_remove.push(i);
} }
} }
this.removeOrganisms(to_remove);
if (Hyperparams.foodDropProb > 0) { if (Hyperparams.foodDropProb > 0) {
this.generateFood(); this.generateFood();
} }
this.removeOrganisms(to_remove);
this.total_ticks ++; this.total_ticks ++;
if (this.total_ticks % this.data_update_rate == 0) { if (this.total_ticks % this.data_update_rate == 0) {
FossilRecord.updateData(); FossilRecord.updateData();
@@ -123,6 +123,16 @@ class WorldEnvironment extends Environment{
this.organisms = []; this.organisms = [];
} }
clearDeadOrganisms() {
let to_remove = [];
for (let i in this.organisms) {
let org = this.organisms[i];
if (!org.living)
to_remove.push(i);
}
this.removeOrganisms(to_remove);
}
generateFood() { generateFood() {
var num_food = Math.max(Math.floor(this.grid_map.cols*this.grid_map.rows*Hyperparams.foodDropProb/50000), 1) var num_food = Math.max(Math.floor(this.grid_map.cols*this.grid_map.rows*Hyperparams.foodDropProb/50000), 1)
var prob = Hyperparams.foodDropProb; var prob = Hyperparams.foodDropProb;
@@ -168,6 +178,7 @@ class WorldEnvironment extends Environment{
} }
serialize() { serialize() {
this.clearDeadOrganisms();
let env = SerializeHelper.copyNonObjects(this); let env = SerializeHelper.copyNonObjects(this);
env.grid = this.grid_map.serialize(); env.grid = this.grid_map.serialize();
env.organisms = []; env.organisms = [];
@@ -198,7 +209,7 @@ class WorldEnvironment extends Environment{
org.loadRaw(orgRaw); org.loadRaw(orgRaw);
this.addOrganism(org); this.addOrganism(org);
let s = species[orgRaw.species_name]; let s = species[orgRaw.species_name];
if (!s){ // ideally, every organisms species should exists, but there is a bug somewhere if (!s){ // ideally, every organisms species should exists, but there is a bug that misses some species sometimes
s = new Species(org.anatomy, null, env.total_ticks); s = new Species(org.anatomy, null, env.total_ticks);
species[orgRaw.species_name] = s; species[orgRaw.species_name] = s;
} }

View File

@@ -4,8 +4,8 @@ const Species = require("./Species");
const FossilRecord = { const FossilRecord = {
init: function(){ init: function(){
this.extant_species = []; this.extant_species = {};
this.extinct_species = []; this.extinct_species = {};
// if an organism has fewer than this cumulative pop, discard them on extinction // if an organism has fewer than this cumulative pop, discard them on extinction
this.min_discard = 10; this.min_discard = 10;
@@ -20,45 +20,44 @@ const FossilRecord = {
addSpecies: function(org, ancestor) { addSpecies: function(org, ancestor) {
var new_species = new Species(org.anatomy, ancestor, this.env.total_ticks); var new_species = new Species(org.anatomy, ancestor, this.env.total_ticks);
this.extant_species.push(new_species); this.extant_species[new_species.name] = new_species;
org.species = new_species; org.species = new_species;
return new_species; return new_species;
}, },
addSpeciesObj: function(species) { addSpeciesObj: function(species) {
this.extant_species.push(species); if (this.extant_species[species.name]) {
console.warn('Tried to add already existing species. Add failed.');
return;
}
this.extant_species[species.name] = species;
return species; return species;
}, },
numExtantSpecies() {return Object.values(this.extant_species).length},
numExtinctSpecies() {return Object.values(this.extinct_species).length},
speciesIsExtant(species_name) {return !!this.extant_species[species_name]},
fossilize: function(species) { fossilize: function(species) {
species.end_tick = this.env.total_ticks; if (!this.extant_species[species.name]) {
for (i in this.extant_species) { console.warn('Tried to fossilize non existing species.');
var s = this.extant_species[i]; return false;
if (s == species) {
this.extant_species.splice(i, 1);
species.ancestor = undefined; // garbage collect dead species
// if (species.ancestor)
// species.ancestor.ancestor = undefined;
if (species.cumulative_pop < this.min_pop) {
return false;
}
// disabled for now, causes memory problems on long runs
// this.extinct_species.push(s);
return true;
}
} }
species.end_tick = this.env.total_ticks;
species.ancestor = undefined; // garbage collect ancestors
delete this.extant_species[species.name];
if (species.cumulative_pop >= this.min_discard) {
// TODO: store as extinct species
return true;
}
return false;
}, },
resurrect: function(species) { resurrect: function(species) {
if (species.extinct) { if (species.extinct) {
for (i in this.extinct_species) { species.extinct = false;
var s = this.extinct_species[i]; this.extant_species[species.name] = species;
if (s == species) { delete this.extinct_species[species.name];
this.extinct_species.splice(i, 1);
this.extant_species.push(species);
species.extinct = false;
}
}
} }
}, },
@@ -77,7 +76,7 @@ const FossilRecord = {
var tick = this.env.total_ticks; var tick = this.env.total_ticks;
this.tick_record.push(tick); this.tick_record.push(tick);
this.pop_counts.push(this.env.organisms.length); this.pop_counts.push(this.env.organisms.length);
this.species_counts.push(this.extant_species.length); this.species_counts.push(this.numExtantSpecies());
this.av_mut_rates.push(this.env.averageMutability()); this.av_mut_rates.push(this.env.averageMutability());
this.calcCellCountAverages(); this.calcCellCountAverages();
while (this.tick_record.length > this.record_size_limit) { while (this.tick_record.length > this.record_size_limit) {
@@ -97,8 +96,8 @@ const FossilRecord = {
cell_counts[c.name] = 0; cell_counts[c.name] = 0;
} }
var first=true; var first=true;
for (let s of this.extant_species) { for (let s of Object.values(this.extant_species)) {
if (s.cumulative_pop < this.min_discard && !first){ if (!first && this.numExtantSpecies() > 10 && s.cumulative_pop < this.min_discard){
continue; continue;
} }
for (let name in s.cell_counts) { for (let name in s.cell_counts) {
@@ -107,8 +106,11 @@ const FossilRecord = {
total_org += s.population; total_org += s.population;
first=false; first=false;
} }
if (total_org == 0) if (total_org == 0) {
return cell_counts; this.av_cells.push(0);
this.av_cell_counts.push(cell_counts);
return;
}
var total_cells = 0; var total_cells = 0;
for (let c in cell_counts) { for (let c in cell_counts) {
@@ -137,7 +139,7 @@ const FossilRecord = {
av_cell_counts:this.av_cell_counts, av_cell_counts:this.av_cell_counts,
}; };
let species = {}; let species = {};
for (let s of this.extant_species) { for (let s of Object.values(this.extant_species)) {
species[s.name] = SerializeHelper.copyNonObjects(s); species[s.name] = SerializeHelper.copyNonObjects(s);
delete species[s.name].name; // the name will be used as the key, so remove it from the value delete species[s.name].name; // the name will be used as the key, so remove it from the value
} }

View File

@@ -50,7 +50,7 @@ class StatsPanel {
updateDetails() { updateDetails() {
var org_count = this.env.organisms.length; var org_count = this.env.organisms.length;
$('#org-count').text("Total Population: " + org_count); $('#org-count').text("Total Population: " + org_count);
$('#species-count').text("Number of Species: " + FossilRecord.extant_species.length); $('#species-count').text("Number of Species: " + FossilRecord.numExtantSpecies());
$('#largest-org').text("Largest Organism Ever: " + this.env.largest_cell_count + " cells"); $('#largest-org').text("Largest Organism Ever: " + this.env.largest_cell_count + " cells");
$('#avg-mut').text("Average Mutation Rate: " + Math.round(this.env.averageMutability() * 100) / 100); $('#avg-mut').text("Average Mutation Rate: " + Math.round(this.env.averageMutability() * 100) / 100);