Added rotations, health, damage
This commit is contained in:
10
README.md
10
README.md
@@ -1,10 +1,18 @@
|
|||||||
# EvolutionSimulatorV2
|
# EvolutionSimulatorV2
|
||||||
Version 2 of the evolution simulator
|
Version 2 of the evolution simulator
|
||||||
|
|
||||||
Requirements:
|
Requirements to Play:
|
||||||
|
- browser (preferably chrome)
|
||||||
|
|
||||||
|
Requirements to edit and build:
|
||||||
- npm
|
- npm
|
||||||
- webpack
|
- webpack
|
||||||
|
|
||||||
|
## Playing
|
||||||
|
Included in this repo is an already built version of the game. You can play it simply by opening `index.html` in your browser.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
If you want to change the source code use any of the following commands:
|
||||||
To build minified: `npm run build`
|
To build minified: `npm run build`
|
||||||
To build in dev mode: `npm run build-dev`
|
To build in dev mode: `npm run build-dev`
|
||||||
To build in dev/watch mode: `npm run build-watch`
|
To build in dev/watch mode: `npm run build-watch`
|
||||||
|
|||||||
256
dist/bundle.js
vendored
256
dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
21
dist/css/style.css
vendored
21
dist/css/style.css
vendored
@@ -2,6 +2,8 @@ body{
|
|||||||
background: black;
|
background: black;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
@@ -15,15 +17,18 @@ canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.env {
|
.env {
|
||||||
height: 80vh;
|
position: absolute;
|
||||||
position: static;
|
top: 0;
|
||||||
|
bottom: 300px; /* must correspond to control-panel height*/
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-panel {
|
.control-panel {
|
||||||
height: 20vh;
|
height: 300px;
|
||||||
width: 100vw;
|
width: 100%;
|
||||||
|
bottom: 0;
|
||||||
|
position: absolute;
|
||||||
background-color: gray;
|
background-color: gray;
|
||||||
position: fixed;
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
grid-template-rows: repeat(2, 1fr);
|
grid-template-rows: repeat(2, 1fr);
|
||||||
@@ -35,20 +40,16 @@ canvas {
|
|||||||
border: 10px;
|
border: 10px;
|
||||||
border-color: black;
|
border-color: black;
|
||||||
background-color: lightgray;
|
background-color: lightgray;
|
||||||
max-width: 100%;
|
|
||||||
/* height: 100%; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#speed-controller {
|
#speed-controller {
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
grid-row: 1;
|
grid-row: 1;
|
||||||
/* background-color: blue; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#stats {
|
#stats {
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
grid-row: 2;
|
grid-row: 2;
|
||||||
/* background-color: blue; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#hyperparameters {
|
#hyperparameters {
|
||||||
@@ -60,8 +61,6 @@ canvas {
|
|||||||
#abilities {
|
#abilities {
|
||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
grid-row: 1 / 3;
|
grid-row: 1 / 3;
|
||||||
/* background-color: yellow; */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-mode-button {
|
.control-mode-button {
|
||||||
|
|||||||
13
dist/html/index.html
vendored
13
dist/html/index.html
vendored
@@ -4,14 +4,15 @@
|
|||||||
<meta charste="UTF-8">
|
<meta charste="UTF-8">
|
||||||
<title>Evolution Simulator</title>
|
<title>Evolution Simulator</title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="../css/style.css">
|
||||||
|
<!-- <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> -->
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="../bundle.js"></script>
|
<script src="../bundle.js"></script>
|
||||||
|
|
||||||
<div class='env'>
|
<div class='env'>
|
||||||
<canvas id='canvas'></canvas>
|
<canvas id='canvas'></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='control-panel'>
|
<div class='control-panel'>
|
||||||
<div id='speed-controller' class='control-set'>
|
<div id='speed-controller' class='control-set'>
|
||||||
<h2>Simulation Speed</h2>
|
<h2>Simulation Speed</h2>
|
||||||
@@ -48,6 +49,15 @@
|
|||||||
<label for="remove-prob">Remove Cell:</label>
|
<label for="remove-prob">Remove Cell:</label>
|
||||||
<input class="mut-prob" type="number" id="remove-prob" min="0" max="100" value=33>
|
<input class="mut-prob" type="number" id="remove-prob" min="0" max="100" value=33>
|
||||||
<br/>
|
<br/>
|
||||||
|
<h4>Organism Rotation</h4>
|
||||||
|
<label for="mover-rot">Movers can rotate</label>
|
||||||
|
<input type="checkbox" id="mover-rot" name="scales" checked>
|
||||||
|
<br/>
|
||||||
|
<label for="offspring-rot">Offspring rotate</label>
|
||||||
|
<input type="checkbox" id="offspring-rot" name="scales" checked>
|
||||||
|
<br/>
|
||||||
|
<label for="insta-kill">Insta Kill</label>
|
||||||
|
<input type="checkbox" id="insta-kill" name="scales">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id='abilities' class='control-set'>
|
<div id='abilities' class='control-set'>
|
||||||
@@ -62,6 +72,5 @@
|
|||||||
<button id='clear-walls'>Clear All Walls</button>
|
<button id='clear-walls'>Clear All Walls</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
10
src/Cell.js
10
src/Cell.js
@@ -81,12 +81,12 @@ function killNeighbors(self, env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function killNeighbor(self, n_cell) {
|
function killNeighbor(self, n_cell) {
|
||||||
if(n_cell == null || n_cell.owner == null || n_cell.owner == self.owner || !n_cell.owner.living || n_cell.type == CellTypes.armor)
|
if(n_cell == null || n_cell.owner == null || self.owner == null || n_cell.owner == self.owner || !n_cell.owner.living || n_cell.type == CellTypes.armor)
|
||||||
return;
|
return;
|
||||||
var should_die = n_cell.type == CellTypes.killer; // has to be calculated before death
|
var is_hit = n_cell.type == CellTypes.killer; // has to be calculated before death
|
||||||
n_cell.owner.die();
|
n_cell.owner.harm();
|
||||||
if (should_die){
|
if (is_hit){
|
||||||
self.owner.die();
|
self.owner.harm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const CellTypes = {
|
|||||||
mover: 5,
|
mover: 5,
|
||||||
killer: 6,
|
killer: 6,
|
||||||
armor: 7,
|
armor: 7,
|
||||||
colors: ['#121D29', 'green', 'gray', 'orange', 'white', 'blue', 'red', 'purple'],
|
colors: ['#121D29', 'green', 'gray', 'orange', 'white', '#3493eb', 'red', 'purple'],
|
||||||
getRandomLivingType: function() {
|
getRandomLivingType: function() {
|
||||||
return Math.floor(Math.random() * 5) + 3;
|
return Math.floor(Math.random() * 5) + 3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ class ControlPanel {
|
|||||||
}
|
}
|
||||||
else if (!this.engine.running){
|
else if (!this.engine.running){
|
||||||
$('#pause-button').text("Pause");
|
$('#pause-button').text("Pause");
|
||||||
console.log(this.fps)
|
|
||||||
this.engine.start(this.fps);
|
this.engine.start(this.fps);
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
@@ -78,6 +77,16 @@ class ControlPanel {
|
|||||||
$('#change-prob').val(Math.floor(Hyperparams.changeProb));
|
$('#change-prob').val(Math.floor(Hyperparams.changeProb));
|
||||||
$('#remove-prob').val(Math.floor(Hyperparams.removeProb));
|
$('#remove-prob').val(Math.floor(Hyperparams.removeProb));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#mover-rot').change(function() {
|
||||||
|
Hyperparams.moversCanRotate = this.checked;
|
||||||
|
});
|
||||||
|
$('#offspring-rot').change(function() {
|
||||||
|
Hyperparams.offspringRotate = this.checked;
|
||||||
|
});
|
||||||
|
$('#insta-kill').change(function() {
|
||||||
|
Hyperparams.instaKill = this.checked;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
defineModeControls() {
|
defineModeControls() {
|
||||||
|
|||||||
15
src/Directions.js
Normal file
15
src/Directions.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
const Directions = {
|
||||||
|
up:0,
|
||||||
|
down:1,
|
||||||
|
left:2,
|
||||||
|
right:3,
|
||||||
|
scalars:[[0,-1],[0,1],[-1,0],[1,0]],
|
||||||
|
getRandomDirection: function() {
|
||||||
|
return Math.floor(Math.random() * 4);
|
||||||
|
},
|
||||||
|
getRandomScalar: function() {
|
||||||
|
return this.scalars[Math.floor(Math.random() * this.scalars.length)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Directions;
|
||||||
@@ -45,9 +45,9 @@ class Environment{
|
|||||||
OriginOfLife() {
|
OriginOfLife() {
|
||||||
var center = this.grid_map.getCenter();
|
var center = this.grid_map.getCenter();
|
||||||
var org = new Organism(center[0], center[1], this);
|
var org = new Organism(center[0], center[1], this);
|
||||||
org.addCell(CellTypes.mouth, 1, 1);
|
org.addCell(CellTypes.mouth, 0, 0);
|
||||||
org.addCell(CellTypes.producer, 0, 0);
|
org.addCell(CellTypes.producer, -1, -1);
|
||||||
org.addCell(CellTypes.mouth, -1, -1);
|
org.addCell(CellTypes.producer, 1, 1);
|
||||||
this.addOrganism(org);
|
this.addOrganism(org);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,11 @@ const Hyperparams = {
|
|||||||
changeProb: 33,
|
changeProb: 33,
|
||||||
removeProb: 33,
|
removeProb: 33,
|
||||||
|
|
||||||
|
moversCanRotate: true,
|
||||||
|
offspringRotate: true,
|
||||||
|
|
||||||
|
instaKill: false,
|
||||||
|
|
||||||
// calculates the optimal ratio where a producer cell is most likely to produce 1 food in its lifespan * a scalar of my choice :)
|
// calculates the optimal ratio where a producer cell is most likely to produce 1 food in its lifespan * a scalar of my choice :)
|
||||||
calcProducerFoodRatio : function(lifespan_fixed=true) {
|
calcProducerFoodRatio : function(lifespan_fixed=true) {
|
||||||
if (lifespan_fixed) {
|
if (lifespan_fixed) {
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
const CellTypes = require("./CellTypes");
|
const CellTypes = require("./CellTypes");
|
||||||
|
const Directions = require("./Directions");
|
||||||
|
const Hyperparams = require("./Hyperparameters");
|
||||||
|
|
||||||
// A local cell is a lightweight container for a cell in an organism. It does not directly exist in the grid
|
// A local cell is a lightweight container for a cell in an organism. It does not directly exist in the grid
|
||||||
class LocalCell{
|
class LocalCell{
|
||||||
@@ -7,6 +9,32 @@ class LocalCell{
|
|||||||
this.loc_col = loc_col;
|
this.loc_col = loc_col;
|
||||||
this.loc_row = loc_row;
|
this.loc_row = loc_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rotatedCol(dir){
|
||||||
|
switch(dir){
|
||||||
|
case Directions.up:
|
||||||
|
return this.loc_col;
|
||||||
|
case Directions.down:
|
||||||
|
return this.loc_col * -1;
|
||||||
|
case Directions.left:
|
||||||
|
return this.loc_row;
|
||||||
|
case Directions.right:
|
||||||
|
return this.loc_row * -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rotatedRow(dir){
|
||||||
|
switch(dir){
|
||||||
|
case Directions.up:
|
||||||
|
return this.loc_row;
|
||||||
|
case Directions.down:
|
||||||
|
return this.loc_row * -1;
|
||||||
|
case Directions.left:
|
||||||
|
return this.loc_col * -1;
|
||||||
|
case Directions.right:
|
||||||
|
return this.loc_col;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = LocalCell;
|
module.exports = LocalCell;
|
||||||
|
|||||||
119
src/Organism.js
119
src/Organism.js
@@ -4,6 +4,7 @@ const GridMap = require("./GridMap");
|
|||||||
const LocalCell = require("./LocalCell");
|
const LocalCell = require("./LocalCell");
|
||||||
const Neighbors = require("./Neighbors");
|
const Neighbors = require("./Neighbors");
|
||||||
const Hyperparams = require("./Hyperparameters");
|
const Hyperparams = require("./Hyperparameters");
|
||||||
|
const Directions = require("./Directions");
|
||||||
|
|
||||||
const directions = [[0,1],[0,-1],[1,0],[-1,0]]
|
const directions = [[0,1],[0,-1],[1,0],[-1,0]]
|
||||||
|
|
||||||
@@ -18,10 +19,13 @@ class Organism {
|
|||||||
this.cells = [];
|
this.cells = [];
|
||||||
this.is_producer = false;
|
this.is_producer = false;
|
||||||
this.is_mover = false;
|
this.is_mover = false;
|
||||||
this.direction = this.getRandomDirection();
|
this.direction = Directions.up;
|
||||||
|
this.rotation = Directions.up;
|
||||||
|
this.can_rotate = Hyperparams.moversCanRotate;
|
||||||
this.move_count = 0;
|
this.move_count = 0;
|
||||||
this.move_range = 5;
|
this.move_range = 4;
|
||||||
this.mutability = 5;
|
this.mutability = 5;
|
||||||
|
this.damage = 0;
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
this.inherit(parent);
|
this.inherit(parent);
|
||||||
}
|
}
|
||||||
@@ -38,6 +42,8 @@ class Organism {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeCell(c, r) {
|
removeCell(c, r) {
|
||||||
|
if (c == 0 && r == 0)
|
||||||
|
return false;
|
||||||
var check_change = false;
|
var check_change = false;
|
||||||
for (var i=0; i<this.cells.length; i++) {
|
for (var i=0; i<this.cells.length; i++) {
|
||||||
var cell = this.cells[i];
|
var cell = this.cells[i];
|
||||||
@@ -56,6 +62,7 @@ class Organism {
|
|||||||
this.checkProducerMover(cell.type);
|
this.checkProducerMover(cell.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkProducerMover(type) {
|
checkProducerMover(type) {
|
||||||
@@ -84,25 +91,36 @@ class Organism {
|
|||||||
return this.cells.length * Hyperparams.lifespanMultiplier;
|
return this.cells.length * Hyperparams.lifespanMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxHealth() {
|
||||||
|
return this.cells.length;
|
||||||
|
}
|
||||||
|
|
||||||
reproduce() {
|
reproduce() {
|
||||||
//produce mutated child
|
//produce mutated child
|
||||||
//check nearby locations (is there room and a direct path)
|
//check nearby locations (is there room and a direct path)
|
||||||
var org = new Organism(0, 0, this.env, this);
|
var org = new Organism(0, 0, this.env, this);
|
||||||
|
if(Hyperparams.offspringRotate){
|
||||||
|
org.rotation = Directions.getRandomDirection();
|
||||||
|
}
|
||||||
var prob = this.mutability;
|
var prob = this.mutability;
|
||||||
if (Hyperparams.useGlobalMutability)
|
if (Hyperparams.useGlobalMutability){
|
||||||
prob = Hyperparams.globalMutability;
|
prob = Hyperparams.globalMutability;
|
||||||
if (Math.random() * 100 <= this.mutability) {
|
}
|
||||||
|
else {
|
||||||
|
//mutate the mutability
|
||||||
|
if (Math.random() <= 0.5)
|
||||||
|
org.mutability++;
|
||||||
|
else{
|
||||||
|
org.mutability--;
|
||||||
|
if (org.mutability < 1)
|
||||||
|
org.mutability = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Math.random() * 100 <= prob) {
|
||||||
org.mutate();
|
org.mutate();
|
||||||
}
|
}
|
||||||
if (Math.random() <= 0.5)
|
|
||||||
org.mutability++;
|
|
||||||
else{
|
|
||||||
org.mutability--;
|
|
||||||
if (org.mutability < 1)
|
|
||||||
org.mutability = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var direction = this.getRandomDirection();
|
var direction = Directions.getRandomScalar();
|
||||||
var direction_c = direction[0];
|
var direction_c = direction[0];
|
||||||
var direction_r = direction[1];
|
var direction_r = direction[1];
|
||||||
var offset = (Math.floor(Math.random() * 2)) * 2;
|
var offset = (Math.floor(Math.random() * 2)) * 2;
|
||||||
@@ -123,6 +141,7 @@ class Organism {
|
|||||||
|
|
||||||
mutate() {
|
mutate() {
|
||||||
var choice = Math.floor(Math.random() * 100);
|
var choice = Math.floor(Math.random() * 100);
|
||||||
|
var mutated = false;
|
||||||
if (choice <= Hyperparams.addProb) {
|
if (choice <= Hyperparams.addProb) {
|
||||||
// add cell
|
// add cell
|
||||||
var type = CellTypes.getRandomLivingType();
|
var type = CellTypes.getRandomLivingType();
|
||||||
@@ -131,38 +150,42 @@ class Organism {
|
|||||||
var growth_direction = Neighbors.all[Math.floor(Math.random() * Neighbors.all.length)]
|
var growth_direction = Neighbors.all[Math.floor(Math.random() * Neighbors.all.length)]
|
||||||
var c = branch.loc_col+growth_direction[0];
|
var c = branch.loc_col+growth_direction[0];
|
||||||
var r = branch.loc_row+growth_direction[1];
|
var r = branch.loc_row+growth_direction[1];
|
||||||
return this.addCell(type, c, r);
|
mutated = this.addCell(type, c, r);
|
||||||
}
|
}
|
||||||
else if (choice <= Hyperparams.addProb + Hyperparams.changeProb){
|
else if (choice <= Hyperparams.addProb + Hyperparams.changeProb){
|
||||||
// change cell
|
// change cell
|
||||||
var cell = this.cells[Math.floor(Math.random() * this.cells.length)];
|
var cell = this.cells[Math.floor(Math.random() * this.cells.length)];
|
||||||
cell.type = CellTypes.getRandomLivingType();
|
cell.type = CellTypes.getRandomLivingType();
|
||||||
this.checkProducerMover(cell.type);
|
this.checkProducerMover(cell.type);
|
||||||
return true;
|
mutated = true;
|
||||||
}
|
}
|
||||||
else if (choice <= Hyperparams.addProb + Hyperparams.changeProb + Hyperparams.removeProb){
|
else if (choice <= Hyperparams.addProb + Hyperparams.changeProb + Hyperparams.removeProb){
|
||||||
// remove cell
|
// remove cell
|
||||||
if(this.cells.length > 1) {
|
if(this.cells.length > 1) {
|
||||||
this.cells.splice(Math.floor(Math.random() * this.cells.length), 1);
|
cell = this.cells[Math.floor(Math.random() * this.cells.length)];
|
||||||
return true;
|
mutated = this.removeCell(cell.loc_col, cell.loc_row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.is_mover) {
|
if (this.is_mover) {
|
||||||
this.move_range += Math.floor(Math.random() * 4) - 2;
|
this.move_range += Math.floor(Math.random() * 4) - 2;
|
||||||
|
if (this.move_range <= 0){
|
||||||
|
this.move_range = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return mutated;
|
||||||
}
|
}
|
||||||
|
|
||||||
attemptMove(direction) {
|
attemptMove() {
|
||||||
|
var direction = Directions.scalars[this.direction];
|
||||||
var direction_c = direction[0];
|
var direction_c = direction[0];
|
||||||
var direction_r = direction[1];
|
var direction_r = direction[1];
|
||||||
var new_c = this.c + direction_c;
|
var new_c = this.c + direction_c;
|
||||||
var new_r = this.r + direction_r;
|
var new_r = this.r + direction_r;
|
||||||
if (this.isClear(new_c, new_r)) {
|
if (this.isClear(new_c, new_r)) {
|
||||||
for (var cell of this.cells) {
|
for (var cell of this.cells) {
|
||||||
var real_c = this.c + cell.loc_col;
|
var real_c = this.c + cell.rotatedCol(this.rotation);
|
||||||
var real_r = this.r + cell.loc_row;
|
var real_r = this.r + cell.rotatedRow(this.rotation);
|
||||||
this.env.changeCell(real_c, real_r, CellTypes.empty, null);
|
this.env.changeCell(real_c, real_r, CellTypes.empty, null);
|
||||||
}
|
}
|
||||||
this.c = new_c;
|
this.c = new_c;
|
||||||
@@ -173,13 +196,30 @@ class Organism {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRandomDirection(){
|
attemptRotate() {
|
||||||
return directions[Math.floor(Math.random() * directions.length)];
|
if(!this.can_rotate){
|
||||||
|
this.direction = Directions.getRandomDirection();
|
||||||
|
this.move_count = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var new_rotation = Directions.getRandomDirection();
|
||||||
|
if(this.isClear(this.c, this.r, new_rotation)){
|
||||||
|
for (var cell of this.cells) {
|
||||||
|
var real_c = this.c + cell.rotatedCol(this.rotation);
|
||||||
|
var real_r = this.r + cell.rotatedRow(this.rotation);
|
||||||
|
this.env.changeCell(real_c, real_r, CellTypes.empty, null);
|
||||||
|
}
|
||||||
|
this.rotation = new_rotation;
|
||||||
|
this.direction = Directions.getRandomDirection();
|
||||||
|
this.updateGrid();
|
||||||
|
this.move_count = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assumes either c1==c2 or r1==r2, returns true if there is a clear path from point a to b
|
// assumes either c1==c2 or r1==r2, returns true if there is a clear path from point a to b
|
||||||
isStraightPath(c1, r1, c2, r2, parent){
|
isStraightPath(c1, r1, c2, r2, parent){
|
||||||
// TODO FIX!!!
|
|
||||||
if (c1 == c2) {
|
if (c1 == c2) {
|
||||||
if (r1 > r2){
|
if (r1 > r2){
|
||||||
var temp = r2;
|
var temp = r2;
|
||||||
@@ -214,9 +254,9 @@ class Organism {
|
|||||||
return cell != null && (cell.type == CellTypes.empty || cell.owner == this || cell.owner == parent || cell.type == CellTypes.food);
|
return cell != null && (cell.type == CellTypes.empty || cell.owner == this || cell.owner == parent || cell.type == CellTypes.food);
|
||||||
}
|
}
|
||||||
|
|
||||||
isClear(col, row) {
|
isClear(col, row, rotation=this.rotation) {
|
||||||
for(var loccell of this.cells) {
|
for(var loccell of this.cells) {
|
||||||
var cell = this.getRealCell(loccell, col, row);
|
var cell = this.getRealCell(loccell, col, row, rotation);
|
||||||
if(cell == null || cell.type != CellTypes.empty && cell.owner != this) {
|
if(cell == null || cell.type != CellTypes.empty && cell.owner != this) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -224,10 +264,17 @@ class Organism {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
harm() {
|
||||||
|
this.damage++;
|
||||||
|
if (this.damage >= this.maxHealth() || Hyperparams.instaKill) {
|
||||||
|
this.die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
die() {
|
die() {
|
||||||
for (var cell of this.cells) {
|
for (var cell of this.cells) {
|
||||||
var real_c = this.c + cell.loc_col;
|
var real_c = this.c + cell.rotatedCol(this.rotation);
|
||||||
var real_r = this.r + cell.loc_row;
|
var real_r = this.r + cell.rotatedRow(this.rotation);
|
||||||
this.env.changeCell(real_c, real_r, CellTypes.food, null);
|
this.env.changeCell(real_c, real_r, CellTypes.food, null);
|
||||||
}
|
}
|
||||||
this.living = false;
|
this.living = false;
|
||||||
@@ -235,14 +282,13 @@ class Organism {
|
|||||||
|
|
||||||
updateGrid() {
|
updateGrid() {
|
||||||
for (var cell of this.cells) {
|
for (var cell of this.cells) {
|
||||||
var real_c = this.c + cell.loc_col;
|
var real_c = this.c + cell.rotatedCol(this.rotation);
|
||||||
var real_r = this.r + cell.loc_row;
|
var real_r = this.r + cell.rotatedRow(this.rotation);
|
||||||
this.env.changeCell(real_c, real_r, cell.type, this);
|
this.env.changeCell(real_c, real_r, cell.type, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
// this.food_collected++;
|
|
||||||
this.lifetime++;
|
this.lifetime++;
|
||||||
if (this.lifetime > this.lifespan()) {
|
if (this.lifetime > this.lifespan()) {
|
||||||
this.die();
|
this.die();
|
||||||
@@ -259,19 +305,18 @@ class Organism {
|
|||||||
}
|
}
|
||||||
if (this.is_mover) {
|
if (this.is_mover) {
|
||||||
this.move_count++;
|
this.move_count++;
|
||||||
var success = this.attemptMove(this.direction);
|
var moved = this.attemptMove();
|
||||||
if (this.move_count > this.move_range || !success){
|
if (this.move_count > this.move_range){
|
||||||
this.move_count = 0;
|
this.attemptRotate();
|
||||||
this.direction = this.getRandomDirection()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.living;
|
return this.living;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRealCell(local_cell, c=this.c, r=this.r){
|
getRealCell(local_cell, c=this.c, r=this.r, rotation=this.rotation){
|
||||||
var real_c = c + local_cell.loc_col;
|
var real_c = c + local_cell.rotatedCol(rotation);
|
||||||
var real_r = r + local_cell.loc_row;
|
var real_r = r + local_cell.rotatedRow(rotation);
|
||||||
return this.env.grid_map.cellAt(real_c, real_r);
|
return this.env.grid_map.cellAt(real_c, real_r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user