diff --git a/dist/css/style.css b/dist/css/style.css index 999f1a9..f78c279 100644 --- a/dist/css/style.css +++ b/dist/css/style.css @@ -98,7 +98,10 @@ button:hover{ grid-template-columns: 1; } .editor-buttons { - display: block; + display: grid; + grid-template-rows: 3; + grid-template-columns: 1; + height: fit-content; } .col-row-input { @@ -158,6 +161,7 @@ button:hover{ .edit-mode-btn { width: 30px; height: 30px; + margin-top: 5px; } .edit-mode-btn:hover{ background-color: #81d2c7; @@ -165,6 +169,9 @@ button:hover{ .edit-mode-btn#drag-view { background-color: #81d2c7; } +#clear-walls { + margin-top: 5px; +} #organism-options { display: none; } @@ -181,6 +188,10 @@ button:hover{ } #cell-selections { display: none; + grid-template-columns: 2; + height: fit-content; + padding: 0; + margin: 0; } #cell-legend { display: flex; @@ -206,30 +217,6 @@ button:hover{ border-color: black; border: 5px; } -#mouth{ - background-color: orange; -} -#producer{ - background-color: white; -} -#mover{ - background-color: #3493eb; -} -#killer{ - background-color: red; -} -#armor{ - background-color: purple; -} -#eye{ - background-color: #d4bb3f; -} -#food{ - background-color: green; -} -#wall{ - background-color: gray; -} #editor-mode-cont{ padding-top: 20px; } diff --git a/dist/index.html b/dist/index.html index 6f46b7c..c26afb9 100644 --- a/dist/index.html +++ b/dist/index.html @@ -38,7 +38,7 @@

Grid Size

- +
@@ -82,6 +82,7 @@
+
@@ -103,32 +104,75 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-

1 cell

-
-
- - + + + +

Simulation Controls

-

Food Production vs Lifespan


@@ -145,7 +189,7 @@
- +
diff --git a/dist/js/bundle.js b/dist/js/bundle.js index b54ae3c..4aa9810 100644 --- a/dist/js/bundle.js +++ b/dist/js/bundle.js @@ -1 +1 @@ -!function(e){var t={};function i(s){if(t[s])return t[s].exports;var r=t[s]={i:s,l:!1,exports:{}};return e[s].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=e,i.c=t,i.d=function(e,t,s){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(i.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(s,r,function(t){return e[t]}.bind(null,r));return s},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=13)}([function(e,t){class i{constructor(e,t){this.name=e,this.color=t}render(e,t,i){e.fillStyle=this.color,e.fillRect(t.x,t.y,i,i)}}const s={empty:new class extends i{constructor(){super("empty","#121D29")}},food:new class extends i{constructor(){super("food","green")}},wall:new class extends i{constructor(){super("wall","gray")}},mouth:new class extends i{constructor(){super("mouth","orange")}},producer:new class extends i{constructor(){super("producer","white")}},mover:new class extends i{constructor(){super("mover","#3493EB")}},killer:new class extends i{constructor(){super("killer","red")}},armor:new class extends i{constructor(){super("armor","purple")}},eye:new class extends i{constructor(){super("eye","#d4bb3f"),this.slit_color="#121D29"}render(e,t,i){if(e.fillStyle=this.color,e.fillRect(t.x,t.y,i,i),1!=i){var s=i/2,r=-i/8,o=-s,n=i/2+i/4,l=i/4;e.translate(t.x+s,t.y+s),e.rotate(90*t.cell_owner.getAbsoluteDirection()*Math.PI/180),e.fillStyle=this.slit_color,e.fillRect(r,o,l,n),e.setTransform(1,0,0,1,0,0)}}},defineLists(){this.all=[this.empty,this.food,this.wall,this.mouth,this.producer,this.mover,this.killer,this.armor,this.eye],this.living=[this.mouth,this.producer,this.mover,this.killer,this.armor,this.eye]},getRandomName:function(){return this.all[Math.floor(Math.random()*this.all.length)].name},getRandomLivingType:function(){return this.living[Math.floor(Math.random()*this.living.length)]}};s.defineLists(),e.exports=s},function(e,t,i){const s=i(4),r={setDefaults:function(){this.lifespanMultiplier=100,this.foodProdProb=4,this.foodProdProbScalar=4,this.killableNeighbors=s.adjacent,this.edibleNeighbors=s.adjacent,this.growableNeighbors=s.adjacent,this.useGlobalMutability=!1,this.globalMutability=5,this.addProb=33,this.changeProb=33,this.removeProb=33,this.moversCanRotate=!0,this.offspringRotate=!0,this.foodBlocksReproduction=!0,this.moversCanProduce=!1,this.instaKill=!1,this.lookRange=15},balanceMutationProbs:function(e){if(1==e){var t=100-this.addProb;this.changeProb=t/2,this.removeProb=t/2}else if(2==e){t=100-this.changeProb;this.addProb=t/2,this.removeProb=t/2}else{t=100-this.removeProb;this.changeProb=t/2,this.addProb=t/2}}};r.setDefaults(),e.exports=r},function(e,t){const i={up:0,right:1,down:2,left:3,scalars:[[0,-1],[1,0],[0,1],[-1,0]],getRandomDirection:function(){return Math.floor(4*Math.random())},getRandomScalar:function(){return this.scalars[Math.floor(Math.random()*this.scalars.length)]},getOppositeDirection:function(e){switch(e){case this.up:return this.down;case this.down:return this.up;case this.left:return this.right;case this.right:return this.left}},rotateRight:function(e){return++e>3&&(e=0),e}};e.exports=i},function(e,t,i){i(0);const s=i(2);e.exports=class{constructor(e,t,i,s){this.state=e,this.org=t,this.loc_col=i,this.loc_row=s}initInherit(e){this.loc_col=e.loc_col,this.loc_row=e.loc_row}initRandom(){}initDefault(){}performFunction(e){}getRealCol(){return this.org.c+this.rotatedCol(this.org.rotation)}getRealRow(){return this.org.r+this.rotatedRow(this.org.rotation)}getRealCell(){var e=this.getRealCol(),t=this.getRealRow();return this.org.env.grid_map.cellAt(e,t)}rotatedCol(e){switch(e){case s.up:return this.loc_col;case s.down:return-1*this.loc_col;case s.left:return this.loc_row;case s.right:return-1*this.loc_row}}rotatedRow(e){switch(e){case s.up:return this.loc_row;case s.down:return-1*this.loc_row;case s.left:return-1*this.loc_col;case s.right:return this.loc_col}}}},function(e,t){e.exports={all:[[0,1],[0,-1],[1,0],[-1,0],[-1,-1],[1,1],[-1,1],[1,-1]],adjacent:[[0,1],[0,-1],[1,0],[-1,0]],corners:[[-1,-1],[1,1],[-1,1],[1,-1]],allSelf:[[0,0],[0,1],[0,-1],[1,0],[-1,0],[-1,-1],[1,1],[-1,1],[1,-1]]}},function(e,t,i){const s=i(0),r=i(15),o=i(4),n=i(1),l=i(2),a=i(23);class h{constructor(e,t,i,s=null){this.c=e,this.r=t,this.env=i,this.lifetime=0,this.food_collected=0,this.living=!0,this.cells=[],this.is_producer=!1,this.is_mover=!1,this.has_eyes=!1,this.direction=l.down,this.rotation=l.up,this.can_rotate=n.moversCanRotate,this.move_count=0,this.move_range=4,this.mutability=5,this.damage=0,this.birth_distance=4,this.brain=new a(this),null!=s&&this.inherit(s)}canAddCellAt(e,t){for(var i of this.cells)if(i.loc_col==e&&i.loc_row==t)return!1;return!0}addDefaultCell(e,t,i){var s=r.createDefault(this,e,t,i);return this.cells.push(s),s}addRandomizedCell(e,t,i){var s=r.createRandom(this,e,t,i);return this.cells.push(s),s}addInheritCell(e){var t=r.createInherited(this,e);return this.cells.push(t),t}replaceCell(e,t,i,s=!0){return this.removeCell(t,i,!0),s?this.addRandomizedCell(e,t,i):this.addDefaultCell(e,t,i)}removeCell(e,t,i=!1){if(0==e&&0==t&&!i)return!1;for(var s=0;s1){c=this.cells[Math.floor(Math.random()*this.cells.length)];t=this.removeCell(c.loc_col,c.loc_row)}return this.is_mover&&100*Math.random()<=10&&(this.move_range+=Math.floor(4*Math.random())-2,this.move_range<=0&&(this.move_range=1)),100*Math.random()<=10&&(this.birth_distance+=Math.floor(5*Math.random())-2,this.birth_distance<1&&(this.birth_distance=1)),this.is_mover&&this.has_eyes&&100*Math.random()<=10&&this.brain.mutate(),t}attemptMove(){var e=l.scalars[this.direction],t=e[0],i=e[1],r=this.c+t,o=this.r+i;if(this.isClear(r,o)){for(var n of this.cells){var a=this.c+n.rotatedCol(this.rotation),h=this.r+n.rotatedRow(this.rotation);this.env.changeCell(a,h,s.empty,null)}return this.c=r,this.r=o,this.updateGrid(),!0}return!1}attemptRotate(){if(!this.can_rotate)return this.direction=l.getRandomDirection(),this.move_count=0,!0;var e=l.getRandomDirection();if(this.isClear(this.c,this.r,e)){for(var t of this.cells){var i=this.c+t.rotatedCol(this.rotation),r=this.r+t.rotatedRow(this.rotation);this.env.changeCell(i,r,s.empty,null)}return this.rotation=e,this.direction=l.getRandomDirection(),this.updateGrid(),this.move_count=0,!0}return!1}changeDirection(e){this.direction=e,this.move_count=0}isStraightPath(e,t,i,s,r){if(e==i){if(t>s){var o=s;s=t,t=o}for(var n=t;n!=s;n++){var l=this.env.grid_map.cellAt(e,n);if(!this.isPassableCell(l,r))return!1}return!0}if(e>i){o=i;i=e,e=o}for(n=e;n!=i;n++){l=this.env.grid_map.cellAt(n,t);if(!this.isPassableCell(l,r))return!1}return!0}isPassableCell(e,t){return null!=e&&(e.state==s.empty||e.owner==this||e.owner==t||e.state==s.food)}isClear(e,t,i=this.rotation){for(var r of this.cells){var o=this.getRealCell(r,e,t,i);if(null==o)return!1;if(o.owner!=this&&o.state!=s.empty&&(n.foodBlocksReproduction||o.state!=s.food))return!1}return!0}harm(){this.damage++,(this.damage>=this.maxHealth()||n.instaKill)&&this.die()}die(){for(var e of this.cells){var t=this.c+e.rotatedCol(this.rotation),i=this.r+e.rotatedRow(this.rotation);this.env.changeCell(t,i,s.food,null)}this.living=!1}updateGrid(){for(var e of this.cells){var t=this.c+e.rotatedCol(this.rotation),i=this.r+e.rotatedRow(this.rotation);this.env.changeCell(t,i,e.state,e)}}update(){if(this.lifetime++,this.lifetime>this.lifespan())return this.die(),this.living;for(var e of(this.food_collected>=this.foodNeeded()&&this.reproduce(),this.cells))if(e.performFunction(),!this.living)return this.living;if(this.is_mover){this.move_count++;var t=this.brain.decide(),i=this.attemptMove();(this.move_count>this.move_range&&!t||!i)&&this.attemptRotate()}return this.living}getRealCell(e,t=this.c,i=this.r,s=this.rotation){var r=t+e.rotatedCol(s),o=i+e.rotatedRow(s);return this.env.grid_map.cellAt(r,o)}}e.exports=h},function(e,t){e.exports={None:0,FoodDrop:1,WallDrop:2,ClickKill:3,Select:4,Edit:5,Clone:6,Drag:7}},function(e,t){e.exports=class{constructor(){}update(){alert("Environment.update() must be overriden")}changeCell(e,t,i,s){this.grid_map.setCellType(e,t,i),this.grid_map.setCellOwner(e,t,s)}}},function(e,t,i){i(0),i(2);e.exports=class{constructor(e,t,i){this.cell_size=i,this.canvas=document.getElementById(e),this.ctx=this.canvas.getContext("2d"),this.fillWindow(t),this.height=this.canvas.height,this.width=this.canvas.width,this.cells_to_render=new Set,this.cells_to_highlight=new Set,this.highlighted_cells=new Set}fillWindow(e){this.fillShape($("#"+e).height(),$("#"+e).width())}fillShape(e,t){this.canvas.width=t,this.canvas.height=e,this.height=this.canvas.height,this.width=this.canvas.width}clear(){this.ctx.fillStyle="white",this.ctx.fillRect(0,0,this.height,this.width)}renderFullGrid(e){for(var t of e)for(var i of t)this.renderCell(i)}renderCells(){for(var e of this.cells_to_render)this.renderCell(e);this.cells_to_render.clear()}renderCell(e){e.state.render(this.ctx,e,this.cell_size)}renderOrganism(e){for(var t of e.cells){var i=e.getRealCell(t);this.renderCell(i)}}addToRender(e){this.highlighted_cells.has(e)&&this.cells_to_highlight.add(e),this.cells_to_render.add(e)}renderHighlights(){for(var e of this.cells_to_highlight)this.renderCellHighlight(e),this.highlighted_cells.add(e);this.cells_to_highlight.clear()}highlightOrganism(e){for(var t of e.cells){var i=e.getRealCell(t);this.cells_to_highlight.add(i)}}highlightCell(e){this.cells_to_highlight.add(e)}renderCellHighlight(e,t="yellow"){this.renderCell(e),this.ctx.fillStyle=t,this.ctx.globalAlpha=.5,this.ctx.fillRect(e.x,e.y,this.cell_size,this.cell_size),this.ctx.globalAlpha=1,this.highlighted_cells.add(e)}clearAllHighlights(e=!1){for(var t of this.highlighted_cells)this.renderCell(t);this.highlighted_cells.clear(),e&&this.cells_to_highlight.clear()}}},function(e,t,i){const s=i(10),r=i(0);e.exports=class{constructor(e,t,i){this.resize(e,t,i)}resize(e,t,i){this.grid=[],this.cols=e,this.rows=t,this.cell_size=i;for(var o=0;o=0&&t>=0}getCenter(){return[Math.floor(this.cols/2),Math.floor(this.rows/2)]}xyToColRow(e,t){var i=Math.floor(e/this.cell_size),s=Math.floor(t/this.cell_size);return i>=this.cols?i=this.cols-1:i<0&&(i=0),s>=this.rows?s=this.rows-1:s<0&&(s=0),[i,s]}}},function(e,t,i){i(0),i(1);e.exports=class{constructor(e,t,i,s,r){this.owner=null,this.cell_owner=null,this.setType(e),this.col=t,this.row=i,this.x=s,this.y=r}setType(e){this.state=e}}},function(e,t){e.exports=class{constructor(e,t){this.env=e,this.canvas=t,this.mouse_x,this.mouse_y,this.mouse_c,this.mouse_r,this.left_click=!1,this.right_click=!1,this.cur_cell=null,this.cur_org=null,this.highlight_org=!0,this.defineEvents()}setControlPanel(e){this.control_panel=e}defineEvents(){this.canvas.addEventListener("mousemove",e=>{this.updateMouseLocation(e.offsetX,e.offsetY),this.mouseMove()}),this.canvas.addEventListener("mouseup",function(e){e.preventDefault(),this.updateMouseLocation(e.offsetX,e.offsetY),this.mouseUp(),this.left_click=!1,this.right_click=!1}.bind(this)),this.canvas.addEventListener("mousedown",function(e){e.preventDefault(),this.updateMouseLocation(e.offsetX,e.offsetY),0==e.button&&(this.left_click=!0),2==e.button&&(this.right_click=!0),this.mouseDown()}.bind(this)),this.canvas.addEventListener("contextmenu",(function(e){e.preventDefault()})),this.canvas.addEventListener("mouseleave",function(){this.right_click=!1,this.left_click=!1,this.env.renderer.clearAllHighlights(!0)}.bind(this))}updateMouseLocation(e,t){var i=this.cur_cell,s=this.cur_org;this.mouse_x=e,this.mouse_y=t;var r=this.env.grid_map.xyToColRow(this.mouse_x,this.mouse_y);this.mouse_c=r[0],this.mouse_r=r[1],this.cur_cell=this.env.grid_map.cellAt(this.mouse_c,this.mouse_r),this.cur_org=this.cur_cell.owner,this.cur_org==s&&this.cur_cell==i||(this.env.renderer.clearAllHighlights(!0),null!=this.cur_org&&this.highlight_org?this.env.renderer.highlightOrganism(this.cur_org):null!=this.cur_cell&&this.env.renderer.highlightCell(this.cur_cell,!0))}mouseMove(){alert("mouse move must be overridden")}mouseDown(){alert("mouse down must be overridden")}mouseUp(){alert("mouse up must be overridden")}}},function(e,t,i){const s=i(14),r=i(25),o=i(26);e.exports=class{constructor(){this.fps=60,this.env=new s(5),this.organism_editor=new o,this.controlpanel=new r(this),this.env.OriginOfLife(),this.last_update=Date.now(),this.delta_time=0,this.actual_fps=0,this.running=!1}start(e=60){e<=0&&(e=1),e>300&&(e=300),this.fps=e,this.game_loop=setInterval(function(){this.environmentUpdate()}.bind(this),1e3/e),this.running=!0,this.fps>=60?null!=this.render_loop&&(clearInterval(this.render_loop),this.render_loop=null):this.setRenderLoop()}stop(){clearInterval(this.game_loop),this.running=!1,this.setRenderLoop()}setRenderLoop(){null==this.render_loop&&(this.render_loop=setInterval(function(){this.necessaryUpdate()}.bind(this),1e3/60))}environmentUpdate(){this.delta_time=Date.now()-this.last_update,this.last_update=Date.now(),this.env.update(this.delta_time),this.actual_fps=1/this.delta_time*1e3,null==this.render_loop&&this.necessaryUpdate()}necessaryUpdate(){this.env.render(),this.controlpanel.update(),this.organism_editor.update()}}},function(e,t,i){"use strict";i.r(t);var s=i(12),r=i.n(s);$("document").ready((function(){(function(){let e=!1;return function(t){(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4)))&&(e=!0)}(navigator.userAgent||navigator.vendor||window.opera),e})()&&(alert("Though the simulation still works on mobile, most features are disabled. Try it on desktop for the full experience!"),$(".control-panel").css("display","none")),(new r.a).start(60)}))},function(e,t,i){const s=i(7),r=i(8),o=i(9),n=i(5),l=i(0),a=i(24);e.exports=class extends s{constructor(e){super(),this.renderer=new r("env-canvas","env",e),this.controller=new a(this,this.renderer.canvas);var t=Math.floor(this.renderer.height/e),i=Math.floor(this.renderer.width/e);this.grid_map=new o(i,t,e),this.renderer.renderFullGrid(this.grid_map.grid),this.organisms=[],this.walls=[],this.total_mutability=0,this.auto_reset=!0,this.largest_cell_count=0,this.reset_count=0}update(e){var t=[];for(var i in this.organisms){var s=this.organisms[i];s.living&&s.update()||t.push(i)}this.removeOrganisms(t)}render(){this.renderer.renderCells(),this.renderer.renderHighlights()}removeOrganisms(e){for(var t of e.reverse())this.total_mutability-=this.organisms[t].mutability,this.organisms.splice(t,1);0==this.organisms.length&&this.auto_reset&&(this.reset_count++,this.reset())}OriginOfLife(){var e=this.grid_map.getCenter(),t=new n(e[0],e[1],this);t.addDefaultCell(l.mouth,0,0),t.addDefaultCell(l.producer,1,1),t.addDefaultCell(l.producer,-1,-1),this.addOrganism(t)}addOrganism(e){e.updateGrid(),this.total_mutability+=e.mutability,this.organisms.push(e),e.cells.length>this.largest_cell_count&&(this.largest_cell_count=e.cells.length)}averageMutability(){return this.organisms.length<1?0:this.total_mutability/this.organisms.length}changeCell(e,t,i,s){super.changeCell(e,t,i,s),this.renderer.addToRender(this.grid_map.cellAt(e,t)),i==l.wall&&this.walls.push(this.grid_map.cellAt(e,t))}clearWalls(){for(var e of this.walls)this.grid_map.cellAt(e.col,e.row).state==l.wall&&this.changeCell(e.col,e.row,l.empty,null)}clearOrganisms(){for(var e of this.organisms)e.die();this.organisms=[]}reset(e=!0){this.organisms=[],this.grid_map.fillGrid(l.empty),this.renderer.renderFullGrid(this.grid_map.grid),this.total_mutability=0,this.OriginOfLife()}resizeGridColRow(e,t,i){this.renderer.cell_size=e,this.renderer.fillShape(i*e,t*e),this.grid_map.resize(t,i,e),this.reset()}resizeFillWindow(e){this.renderer.cell_size=e,this.renderer.fillWindow("env");var t=Math.floor(this.renderer.width/e),i=Math.floor(this.renderer.height/e);this.grid_map.resize(t,i,e),this.reset()}}},function(e,t,i){const s=i(16),r=i(17),o=i(18),n=i(19),l=i(20),a=i(21),h=i(0),c={init:function(){var e={};e[h.mouth.name]=s,e[h.producer.name]=r,e[h.mover.name]=o,e[h.killer.name]=n,e[h.armor.name]=l,e[h.eye.name]=a,this.type_map=e},createInherited:function(e,t){var i=new this.type_map[t.state.name](e,t.loc_col,t.loc_row);return i.initInherit(t),i},createRandom:function(e,t,i,s){var r=new this.type_map[t.name](e,i,s);return r.initRandom(),r},createDefault:function(e,t,i,s){var r=new this.type_map[t.name](e,i,s);return r.initDefault(),r}};c.init(),e.exports=c},function(e,t,i){const s=i(0),r=i(3),o=i(1);e.exports=class extends r{constructor(e,t,i){super(s.mouth,e,t,i)}performFunction(){var e=this.org.env,t=this.getRealCol(),i=this.getRealRow();for(var s of o.edibleNeighbors){var r=e.grid_map.cellAt(t+s[0],i+s[1]);this.eatNeighbor(r,e)}}eatNeighbor(e,t){null!=e&&e.state==s.food&&(t.changeCell(e.col,e.row,s.empty,null),this.org.food_collected++)}}},function(e,t,i){const s=i(0),r=i(3),o=i(1);e.exports=class extends r{constructor(e,t,i){super(s.producer,e,t,i),this.org.is_producer=!0}performFunction(){if(!this.org.is_mover||o.moversCanProduce){var e=this.org.env,t=o.foodProdProb,i=this.getRealCol(),r=this.getRealRow();if(100*Math.random()<=t){var n=o.growableNeighbors[Math.floor(Math.random()*o.growableNeighbors.length)],l=n[0],a=n[1],h=e.grid_map.cellAt(i+l,r+a);if(null!=h&&h.state==s.empty)return void e.changeCell(i+l,r+a,s.food,null)}}}}},function(e,t,i){const s=i(0),r=i(3);e.exports=class extends r{constructor(e,t,i){super(s.mover,e,t,i),this.org.is_mover=!0}}},function(e,t,i){const s=i(0),r=i(3),o=i(1);e.exports=class extends r{constructor(e,t,i){super(s.killer,e,t,i)}performFunction(){var e=this.org.env,t=this.getRealCol(),i=this.getRealRow();for(var s of o.killableNeighbors){var r=e.grid_map.cellAt(t+s[0],i+s[1]);this.killNeighbor(r)}}killNeighbor(e){if(null!=e&&null!=e.owner&&e.owner!=this.org&&e.owner.living&&e.state!=s.armor){var t=e.state==s.killer;e.owner.harm(),t&&this.org.harm()}}}},function(e,t,i){const s=i(0),r=i(3);e.exports=class extends r{constructor(e,t,i){super(s.armor,e,t,i)}}},function(e,t,i){const s=i(0),r=i(3),o=i(1),n=i(2),l=i(22);e.exports=class extends r{constructor(e,t,i){super(s.eye,e,t,i),this.org.has_eyes=!0}initInherit(e){super.initInherit(e),this.direction=e.direction}initRandom(){this.direction=n.getRandomDirection()}initDefault(){this.direction=n.up}getAbsoluteDirection(){var e=this.org.rotation+this.direction;return e>3&&(e-=4),e}performFunction(){var e=this.look();this.org.brain.observe(e)}look(){var e=this.org.env,t=this.getAbsoluteDirection(),i=0,r=0;switch(t){case n.up:r=-1;break;case n.down:r=1;break;case n.right:i=1;break;case n.left:i=-1}for(var a=this.getRealCol(),h=this.getRealRow(),c=a,d=h,u=null,g=0;gthis.organism_record&&(this.organism_record=e),$("#org-record").text("Highest count: "+this.organism_record),$("#avg-mut").text("Average Mutation Rate: "+Math.round(100*this.engine.env.averageMutability())/100),$("#largest-org").text("Largest Organism: "+this.engine.env.largest_cell_count+" cells"),$("#reset-count").text("Auto reset count: "+this.engine.env.reset_count),this.editor_controller.env.organism.cells.length>1?$("#editor-cell-count").text(this.editor_controller.env.organism.cells.length+" cells"):$("#editor-cell-count").text("1 cell")}}},function(e,t,i){const s=i(7),r=i(5),o=i(9),n=i(8),l=i(0),a=i(27);i(2);e.exports=class extends s{constructor(){super(),this.is_active=!0;this.renderer=new n("editor-canvas","editor-env",13),this.controller=new a(this,this.renderer.canvas),this.grid_map=new o(15,15,13),this.clear(),this.renderer.renderFullGrid(this.grid_map.grid)}update(){this.is_active&&this.renderer.renderHighlights()}changeCell(e,t,i,s){super.changeCell(e,t,i,s),this.renderFull()}renderFull(){this.renderer.renderFullGrid(this.grid_map.grid)}addCellToOrg(e,t,i){var s=this.grid_map.getCenter(),r=e-s[0],o=t-s[1],n=this.organism.getLocalCell(r,o);if(null!=n){var l=this.organism.replaceCell(i,n.loc_col,n.loc_row,!1);this.changeCell(e,t,i,l)}else this.organism.canAddCellAt(r,o)&&this.changeCell(e,t,i,this.organism.addDefaultCell(i,r,o))}removeCellFromOrg(e,t){var i=this.grid_map.getCenter(),s=e-i[0],r=t-i[1];0!=s||0!=r?null!=this.organism.getLocalCell(s,r)&&this.organism.removeCell(s,r)&&this.changeCell(e,t,l.empty,null):alert("Cannot remove center cell")}setOrganismToCopyOf(e){this.grid_map.fillGrid(l.empty);var t=this.grid_map.getCenter();this.organism=new r(t[0],t[1],this,e),this.organism.updateGrid(),this.controller.updateDetails()}getCopyOfOrg(){return new r(0,0,null,this.organism)}clear(){this.grid_map.fillGrid(l.empty);var e=this.grid_map.getCenter();this.organism=new r(e[0],e[1],this,null),this.organism.addDefaultCell(l.mouth,0,0),this.organism.updateGrid()}}},function(e,t,i){const s=i(11),r=i(6),o=i(0),n=i(2);e.exports=class extends s{constructor(e,t){super(e,t),this.mode=r.None,this.edit_cell_type=null,this.highlight_org=!1,this.defineCellTypeSelection(),this.defineEditorOptions()}mouseMove(){(this.right_click||this.left_click)&&this.editOrganism()}mouseDown(){this.editOrganism()}mouseUp(){}getCurLocalCell(){return this.env.organism.getLocalCell(this.mouse_c-this.env.organism.c,this.mouse_r-this.env.organism.r)}editOrganism(){if(null!=this.edit_cell_type&&this.mode==r.Edit){if(this.left_click)if(this.edit_cell_type==o.eye&&this.cur_cell.state==o.eye){var e=this.getCurLocalCell();e.direction=n.rotateRight(e.direction),this.env.renderFull()}else this.env.addCellToOrg(this.mouse_c,this.mouse_r,this.edit_cell_type);this.right_click&&this.env.removeCellFromOrg(this.mouse_c,this.mouse_r)}}updateDetails(){$("#birth-distance").val(this.env.organism.birth_distance)}defineCellTypeSelection(){var e=this;$(".cell-type").click((function(){switch(this.id){case"mouth":e.edit_cell_type=o.mouth;break;case"producer":e.edit_cell_type=o.producer;break;case"mover":e.edit_cell_type=o.mover;break;case"killer":e.edit_cell_type=o.killer;break;case"armor":e.edit_cell_type=o.armor;break;case"eye":e.edit_cell_type=o.eye}$(".cell-type").css("border-color","black");var t="#"+this.id+".cell-type";$(t).css("border-color","yellow")}))}defineEditorOptions(){$("#birth-distance").change(function(){this.env.organism.birth_distance=parseInt($("#birth-distance").val())}.bind(this))}}}]); \ No newline at end of file +!function(e){var t={};function i(s){if(t[s])return t[s].exports;var r=t[s]={i:s,l:!1,exports:{}};return e[s].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=e,i.c=t,i.d=function(e,t,s){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(i.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(s,r,function(t){return e[t]}.bind(null,r));return s},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=13)}([function(e,t){class i{constructor(e){this.name=e,this.color="black"}render(e,t,i){e.fillStyle=this.color,e.fillRect(t.x,t.y,i,i)}}const s={empty:new class extends i{constructor(){super("empty")}},food:new class extends i{constructor(){super("food")}},wall:new class extends i{constructor(){super("wall")}},mouth:new class extends i{constructor(){super("mouth")}},producer:new class extends i{constructor(){super("producer")}},mover:new class extends i{constructor(){super("mover")}},killer:new class extends i{constructor(){super("killer")}},armor:new class extends i{constructor(){super("armor")}},eye:new class extends i{constructor(){super("eye"),this.slit_color="black"}render(e,t,i){if(e.fillStyle=this.color,e.fillRect(t.x,t.y,i,i),1!=i){var s=i/2,r=-i/8,o=-s,n=i/2+i/4,l=i/4;e.translate(t.x+s,t.y+s),e.rotate(90*t.cell_owner.getAbsoluteDirection()*Math.PI/180),e.fillStyle=this.slit_color,e.fillRect(r,o,l,n),e.setTransform(1,0,0,1,0,0)}}},defineLists(){this.all=[this.empty,this.food,this.wall,this.mouth,this.producer,this.mover,this.killer,this.armor,this.eye],this.living=[this.mouth,this.producer,this.mover,this.killer,this.armor,this.eye]},getRandomName:function(){return this.all[Math.floor(Math.random()*this.all.length)].name},getRandomLivingType:function(){return this.living[Math.floor(Math.random()*this.living.length)]}};s.defineLists(),e.exports=s},function(e,t,i){const s=i(4),r={setDefaults:function(){this.lifespanMultiplier=100,this.foodProdProb=4,this.foodProdProbScalar=4,this.killableNeighbors=s.adjacent,this.edibleNeighbors=s.adjacent,this.growableNeighbors=s.adjacent,this.useGlobalMutability=!1,this.globalMutability=5,this.addProb=33,this.changeProb=33,this.removeProb=33,this.moversCanRotate=!0,this.offspringRotate=!0,this.foodBlocksReproduction=!0,this.moversCanProduce=!1,this.instaKill=!1,this.lookRange=20},balanceMutationProbs:function(e){if(1==e){var t=100-this.addProb;this.changeProb=t/2,this.removeProb=t/2}else if(2==e){t=100-this.changeProb;this.addProb=t/2,this.removeProb=t/2}else{t=100-this.removeProb;this.changeProb=t/2,this.addProb=t/2}}};r.setDefaults(),e.exports=r},function(e,t){const i={up:0,right:1,down:2,left:3,scalars:[[0,-1],[1,0],[0,1],[-1,0]],getRandomDirection:function(){return Math.floor(4*Math.random())},getRandomScalar:function(){return this.scalars[Math.floor(Math.random()*this.scalars.length)]},getOppositeDirection:function(e){switch(e){case this.up:return this.down;case this.down:return this.up;case this.left:return this.right;case this.right:return this.left}},rotateRight:function(e){return++e>3&&(e=0),e}};e.exports=i},function(e,t,i){i(0);const s=i(2);e.exports=class{constructor(e,t,i,s){this.state=e,this.org=t,this.loc_col=i,this.loc_row=s}initInherit(e){this.loc_col=e.loc_col,this.loc_row=e.loc_row}initRandom(){}initDefault(){}performFunction(e){}getRealCol(){return this.org.c+this.rotatedCol(this.org.rotation)}getRealRow(){return this.org.r+this.rotatedRow(this.org.rotation)}getRealCell(){var e=this.getRealCol(),t=this.getRealRow();return this.org.env.grid_map.cellAt(e,t)}rotatedCol(e){switch(e){case s.up:return this.loc_col;case s.down:return-1*this.loc_col;case s.left:return this.loc_row;case s.right:return-1*this.loc_row}}rotatedRow(e){switch(e){case s.up:return this.loc_row;case s.down:return-1*this.loc_row;case s.left:return-1*this.loc_col;case s.right:return this.loc_col}}}},function(e,t){e.exports={all:[[0,1],[0,-1],[1,0],[-1,0],[-1,-1],[1,1],[-1,1],[1,-1]],adjacent:[[0,1],[0,-1],[1,0],[-1,0]],corners:[[-1,-1],[1,1],[-1,1],[1,-1]],allSelf:[[0,0],[0,1],[0,-1],[1,0],[-1,0],[-1,-1],[1,1],[-1,1],[1,-1]]}},function(e,t,i){const s=i(0),r=i(15),o=i(4),n=i(1),l=i(2),a=i(23);class h{constructor(e,t,i,s=null){this.c=e,this.r=t,this.env=i,this.lifetime=0,this.food_collected=0,this.living=!0,this.cells=[],this.is_producer=!1,this.is_mover=!1,this.has_eyes=!1,this.direction=l.down,this.rotation=l.up,this.can_rotate=n.moversCanRotate,this.move_count=0,this.move_range=4,this.ignore_brain_for=0,this.mutability=5,this.damage=0,this.birth_distance=4,this.brain=new a(this),null!=s&&this.inherit(s)}canAddCellAt(e,t){for(var i of this.cells)if(i.loc_col==e&&i.loc_row==t)return!1;return!0}addDefaultCell(e,t,i){var s=r.createDefault(this,e,t,i);return this.cells.push(s),s}addRandomizedCell(e,t,i){e!=s.eye||this.has_eyes||this.brain.randomizeDecisions();var o=r.createRandom(this,e,t,i);return this.cells.push(o),o}addInheritCell(e){var t=r.createInherited(this,e);return this.cells.push(t),t}replaceCell(e,t,i,s=!0){return this.removeCell(t,i,!0),s?this.addRandomizedCell(e,t,i):this.addDefaultCell(e,t,i)}removeCell(e,t,i=!1){if(0==e&&0==t&&!i)return!1;for(var s=0;s1){c=this.cells[Math.floor(Math.random()*this.cells.length)];t=this.removeCell(c.loc_col,c.loc_row)}return this.is_mover&&100*Math.random()<=10&&(this.move_range+=Math.floor(4*Math.random())-2,this.move_range<=0&&(this.move_range=1)),100*Math.random()<=10&&(this.birth_distance+=Math.floor(5*Math.random())-2,this.birth_distance<1&&(this.birth_distance=1)),this.is_mover&&this.has_eyes&&100*Math.random()<=10&&this.brain.mutate(),t}attemptMove(){var e=l.scalars[this.direction],t=e[0],i=e[1],r=this.c+t,o=this.r+i;if(this.isClear(r,o)){for(var n of this.cells){var a=this.c+n.rotatedCol(this.rotation),h=this.r+n.rotatedRow(this.rotation);this.env.changeCell(a,h,s.empty,null)}return this.c=r,this.r=o,this.updateGrid(),!0}return!1}attemptRotate(){if(!this.can_rotate)return this.direction=l.getRandomDirection(),this.move_count=0,!0;var e=l.getRandomDirection();if(this.isClear(this.c,this.r,e)){for(var t of this.cells){var i=this.c+t.rotatedCol(this.rotation),r=this.r+t.rotatedRow(this.rotation);this.env.changeCell(i,r,s.empty,null)}return this.rotation=e,this.direction=l.getRandomDirection(),this.updateGrid(),this.move_count=0,!0}return!1}changeDirection(e){this.direction=e,this.move_count=0}isStraightPath(e,t,i,s,r){if(e==i){if(t>s){var o=s;s=t,t=o}for(var n=t;n!=s;n++){var l=this.env.grid_map.cellAt(e,n);if(!this.isPassableCell(l,r))return!1}return!0}if(e>i){o=i;i=e,e=o}for(n=e;n!=i;n++){l=this.env.grid_map.cellAt(n,t);if(!this.isPassableCell(l,r))return!1}return!0}isPassableCell(e,t){return null!=e&&(e.state==s.empty||e.owner==this||e.owner==t||e.state==s.food)}isClear(e,t,i=this.rotation){for(var r of this.cells){var o=this.getRealCell(r,e,t,i);if(null==o)return!1;if(o.owner!=this&&o.state!=s.empty&&(n.foodBlocksReproduction||o.state!=s.food))return!1}return!0}harm(){this.damage++,(this.damage>=this.maxHealth()||n.instaKill)&&this.die()}die(){for(var e of this.cells){var t=this.c+e.rotatedCol(this.rotation),i=this.r+e.rotatedRow(this.rotation);this.env.changeCell(t,i,s.food,null)}this.living=!1}updateGrid(){for(var e of this.cells){var t=this.c+e.rotatedCol(this.rotation),i=this.r+e.rotatedRow(this.rotation);this.env.changeCell(t,i,e.state,e)}}update(){if(this.lifetime++,this.lifetime>this.lifespan())return this.die(),this.living;for(var e of(this.food_collected>=this.foodNeeded()&&this.reproduce(),this.cells))if(e.performFunction(),!this.living)return this.living;if(this.is_mover){this.move_count++;var t=!1;0==this.ignore_brain_for?t=this.brain.decide():this.ignore_brain_for--;var i=this.attemptMove();if(this.move_count>this.move_range&&!t||!i)this.attemptRotate()||(this.changeDirection(l.getRandomDirection()),t&&(this.ignore_brain_for=this.move_range+1))}return this.living}getRealCell(e,t=this.c,i=this.r,s=this.rotation){var r=t+e.rotatedCol(s),o=i+e.rotatedRow(s);return this.env.grid_map.cellAt(r,o)}}e.exports=h},function(e,t){e.exports={None:0,FoodDrop:1,WallDrop:2,ClickKill:3,Select:4,Edit:5,Clone:6,Drag:7}},function(e,t){e.exports=class{constructor(){}update(){alert("Environment.update() must be overriden")}changeCell(e,t,i,s){this.grid_map.setCellType(e,t,i),this.grid_map.setCellOwner(e,t,s)}}},function(e,t,i){i(0),i(2);e.exports=class{constructor(e,t,i){this.cell_size=i,this.canvas=document.getElementById(e),this.ctx=this.canvas.getContext("2d"),this.fillWindow(t),this.height=this.canvas.height,this.width=this.canvas.width,this.cells_to_render=new Set,this.cells_to_highlight=new Set,this.highlighted_cells=new Set}fillWindow(e){this.fillShape($("#"+e).height(),$("#"+e).width())}fillShape(e,t){this.canvas.width=t,this.canvas.height=e,this.height=this.canvas.height,this.width=this.canvas.width}clear(){this.ctx.fillStyle="white",this.ctx.fillRect(0,0,this.height,this.width)}renderFullGrid(e){for(var t of e)for(var i of t)this.renderCell(i)}renderCells(){for(var e of this.cells_to_render)this.renderCell(e);this.cells_to_render.clear()}renderCell(e){e.state.render(this.ctx,e,this.cell_size)}renderOrganism(e){for(var t of e.cells){var i=e.getRealCell(t);this.renderCell(i)}}addToRender(e){this.highlighted_cells.has(e)&&this.cells_to_highlight.add(e),this.cells_to_render.add(e)}renderHighlights(){for(var e of this.cells_to_highlight)this.renderCellHighlight(e),this.highlighted_cells.add(e);this.cells_to_highlight.clear()}highlightOrganism(e){for(var t of e.cells){var i=e.getRealCell(t);this.cells_to_highlight.add(i)}}highlightCell(e){this.cells_to_highlight.add(e)}renderCellHighlight(e,t="yellow"){this.renderCell(e),this.ctx.fillStyle=t,this.ctx.globalAlpha=.5,this.ctx.fillRect(e.x,e.y,this.cell_size,this.cell_size),this.ctx.globalAlpha=1,this.highlighted_cells.add(e)}clearAllHighlights(e=!1){for(var t of this.highlighted_cells)this.renderCell(t);this.highlighted_cells.clear(),e&&this.cells_to_highlight.clear()}}},function(e,t,i){const s=i(10),r=i(0);e.exports=class{constructor(e,t,i){this.resize(e,t,i)}resize(e,t,i){this.grid=[],this.cols=e,this.rows=t,this.cell_size=i;for(var o=0;o=0&&t>=0}getCenter(){return[Math.floor(this.cols/2),Math.floor(this.rows/2)]}xyToColRow(e,t){var i=Math.floor(e/this.cell_size),s=Math.floor(t/this.cell_size);return i>=this.cols?i=this.cols-1:i<0&&(i=0),s>=this.rows?s=this.rows-1:s<0&&(s=0),[i,s]}}},function(e,t,i){i(0),i(1);e.exports=class{constructor(e,t,i,s,r){this.owner=null,this.cell_owner=null,this.setType(e),this.col=t,this.row=i,this.x=s,this.y=r}setType(e){this.state=e}}},function(e,t){e.exports=class{constructor(e,t){this.env=e,this.canvas=t,this.mouse_x,this.mouse_y,this.mouse_c,this.mouse_r,this.left_click=!1,this.right_click=!1,this.cur_cell=null,this.cur_org=null,this.highlight_org=!0,this.defineEvents()}setControlPanel(e){this.control_panel=e}defineEvents(){this.canvas.addEventListener("mousemove",e=>{this.updateMouseLocation(e.offsetX,e.offsetY),this.mouseMove()}),this.canvas.addEventListener("mouseup",function(e){e.preventDefault(),this.updateMouseLocation(e.offsetX,e.offsetY),this.mouseUp(),this.left_click=!1,this.right_click=!1}.bind(this)),this.canvas.addEventListener("mousedown",function(e){e.preventDefault(),this.updateMouseLocation(e.offsetX,e.offsetY),0==e.button&&(this.left_click=!0),2==e.button&&(this.right_click=!0),this.mouseDown()}.bind(this)),this.canvas.addEventListener("contextmenu",(function(e){e.preventDefault()})),this.canvas.addEventListener("mouseleave",function(){this.right_click=!1,this.left_click=!1,this.env.renderer.clearAllHighlights(!0)}.bind(this))}updateMouseLocation(e,t){var i=this.cur_cell,s=this.cur_org;this.mouse_x=e,this.mouse_y=t;var r=this.env.grid_map.xyToColRow(this.mouse_x,this.mouse_y);this.mouse_c=r[0],this.mouse_r=r[1],this.cur_cell=this.env.grid_map.cellAt(this.mouse_c,this.mouse_r),this.cur_org=this.cur_cell.owner,this.cur_org==s&&this.cur_cell==i||(this.env.renderer.clearAllHighlights(!0),null!=this.cur_org&&this.highlight_org?this.env.renderer.highlightOrganism(this.cur_org):null!=this.cur_cell&&this.env.renderer.highlightCell(this.cur_cell,!0))}mouseMove(){alert("mouse move must be overridden")}mouseDown(){alert("mouse down must be overridden")}mouseUp(){alert("mouse up must be overridden")}}},function(e,t,i){const s=i(14),r=i(25),o=i(26),n=i(28);e.exports=class{constructor(){this.fps=60,this.env=new s(5),this.organism_editor=new o,this.controlpanel=new r(this),this.colorscheme=new n(this.env,this.organism_editor),this.colorscheme.loadColorScheme(),this.env.OriginOfLife(),this.last_update=Date.now(),this.delta_time=0,this.actual_fps=0,this.running=!1}start(e=60){e<=0&&(e=1),e>300&&(e=300),this.fps=e,this.game_loop=setInterval(function(){this.environmentUpdate()}.bind(this),1e3/e),this.running=!0,this.fps>=60?null!=this.render_loop&&(clearInterval(this.render_loop),this.render_loop=null):this.setRenderLoop()}stop(){clearInterval(this.game_loop),this.running=!1,this.setRenderLoop()}setRenderLoop(){null==this.render_loop&&(this.render_loop=setInterval(function(){this.necessaryUpdate()}.bind(this),1e3/60))}environmentUpdate(){this.delta_time=Date.now()-this.last_update,this.last_update=Date.now(),this.env.update(this.delta_time),this.actual_fps=1/this.delta_time*1e3,null==this.render_loop&&this.necessaryUpdate()}necessaryUpdate(){this.env.render(),this.controlpanel.update(),this.organism_editor.update()}}},function(e,t,i){"use strict";i.r(t);var s=i(12),r=i.n(s);$("document").ready((function(){(function(){let e=!1;return function(t){(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4)))&&(e=!0)}(navigator.userAgent||navigator.vendor||window.opera),e})()&&(alert("Though the simulation still works on mobile, most features are disabled. Try it on desktop for the full experience!"),$(".control-panel").css("display","none")),(new r.a).start(60)}))},function(e,t,i){const s=i(7),r=i(8),o=i(9),n=i(5),l=i(0),a=i(24);e.exports=class extends s{constructor(e){super(),this.renderer=new r("env-canvas","env",e),this.controller=new a(this,this.renderer.canvas);var t=Math.floor(this.renderer.height/e),i=Math.floor(this.renderer.width/e);this.grid_map=new o(i,t,e),this.organisms=[],this.walls=[],this.total_mutability=0,this.auto_reset=!0,this.largest_cell_count=0,this.reset_count=0}update(e){var t=[];for(var i in this.organisms){var s=this.organisms[i];s.living&&s.update()||t.push(i)}this.removeOrganisms(t)}render(){this.renderer.renderCells(),this.renderer.renderHighlights()}removeOrganisms(e){for(var t of e.reverse())this.total_mutability-=this.organisms[t].mutability,this.organisms.splice(t,1);0==this.organisms.length&&this.auto_reset&&(this.reset_count++,this.reset())}OriginOfLife(){var e=this.grid_map.getCenter(),t=new n(e[0],e[1],this);t.addDefaultCell(l.mouth,0,0),t.addDefaultCell(l.producer,1,1),t.addDefaultCell(l.producer,-1,-1),this.addOrganism(t)}addOrganism(e){e.updateGrid(),this.total_mutability+=e.mutability,this.organisms.push(e),e.cells.length>this.largest_cell_count&&(this.largest_cell_count=e.cells.length)}averageMutability(){return this.organisms.length<1?0:this.total_mutability/this.organisms.length}changeCell(e,t,i,s){super.changeCell(e,t,i,s),this.renderer.addToRender(this.grid_map.cellAt(e,t)),i==l.wall&&this.walls.push(this.grid_map.cellAt(e,t))}clearWalls(){for(var e of this.walls)this.grid_map.cellAt(e.col,e.row).state==l.wall&&this.changeCell(e.col,e.row,l.empty,null)}clearOrganisms(){for(var e of this.organisms)e.die();this.organisms=[]}reset(e=!0){this.organisms=[],this.grid_map.fillGrid(l.empty),this.renderer.renderFullGrid(this.grid_map.grid),this.total_mutability=0,this.OriginOfLife()}resizeGridColRow(e,t,i){this.renderer.cell_size=e,this.renderer.fillShape(i*e,t*e),this.grid_map.resize(t,i,e),this.reset()}resizeFillWindow(e){this.renderer.cell_size=e,this.renderer.fillWindow("env");var t=Math.floor(this.renderer.width/e),i=Math.floor(this.renderer.height/e);this.grid_map.resize(t,i,e),this.reset()}}},function(e,t,i){const s=i(16),r=i(17),o=i(18),n=i(19),l=i(20),a=i(21),h=i(0),c={init:function(){var e={};e[h.mouth.name]=s,e[h.producer.name]=r,e[h.mover.name]=o,e[h.killer.name]=n,e[h.armor.name]=l,e[h.eye.name]=a,this.type_map=e},createInherited:function(e,t){var i=new this.type_map[t.state.name](e,t.loc_col,t.loc_row);return i.initInherit(t),i},createRandom:function(e,t,i,s){var r=new this.type_map[t.name](e,i,s);return r.initRandom(),r},createDefault:function(e,t,i,s){var r=new this.type_map[t.name](e,i,s);return r.initDefault(),r}};c.init(),e.exports=c},function(e,t,i){const s=i(0),r=i(3),o=i(1);e.exports=class extends r{constructor(e,t,i){super(s.mouth,e,t,i)}performFunction(){var e=this.org.env,t=this.getRealCol(),i=this.getRealRow();for(var s of o.edibleNeighbors){var r=e.grid_map.cellAt(t+s[0],i+s[1]);this.eatNeighbor(r,e)}}eatNeighbor(e,t){null!=e&&e.state==s.food&&(t.changeCell(e.col,e.row,s.empty,null),this.org.food_collected++)}}},function(e,t,i){const s=i(0),r=i(3),o=i(1);e.exports=class extends r{constructor(e,t,i){super(s.producer,e,t,i),this.org.is_producer=!0}performFunction(){if(!this.org.is_mover||o.moversCanProduce){var e=this.org.env,t=o.foodProdProb,i=this.getRealCol(),r=this.getRealRow();if(100*Math.random()<=t){var n=o.growableNeighbors[Math.floor(Math.random()*o.growableNeighbors.length)],l=n[0],a=n[1],h=e.grid_map.cellAt(i+l,r+a);if(null!=h&&h.state==s.empty)return void e.changeCell(i+l,r+a,s.food,null)}}}}},function(e,t,i){const s=i(0),r=i(3);e.exports=class extends r{constructor(e,t,i){super(s.mover,e,t,i),this.org.is_mover=!0}}},function(e,t,i){const s=i(0),r=i(3),o=i(1);e.exports=class extends r{constructor(e,t,i){super(s.killer,e,t,i)}performFunction(){var e=this.org.env,t=this.getRealCol(),i=this.getRealRow();for(var s of o.killableNeighbors){var r=e.grid_map.cellAt(t+s[0],i+s[1]);this.killNeighbor(r)}}killNeighbor(e){if(null!=e&&null!=e.owner&&e.owner!=this.org&&e.owner.living&&e.state!=s.armor){var t=e.state==s.killer;e.owner.harm(),t&&this.org.harm()}}}},function(e,t,i){const s=i(0),r=i(3);e.exports=class extends r{constructor(e,t,i){super(s.armor,e,t,i)}}},function(e,t,i){const s=i(0),r=i(3),o=i(1),n=i(2),l=i(22);e.exports=class extends r{constructor(e,t,i){super(s.eye,e,t,i),this.org.has_eyes=!0}initInherit(e){super.initInherit(e),this.direction=e.direction}initRandom(){this.direction=n.getRandomDirection()}initDefault(){this.direction=n.up}getAbsoluteDirection(){var e=this.org.rotation+this.direction;return e>3&&(e-=4),e}performFunction(){var e=this.look();this.org.brain.observe(e)}look(){var e=this.org.env,t=this.getAbsoluteDirection(),i=0,r=0;switch(t){case n.up:r=-1;break;case n.down:r=1;break;case n.right:i=1;break;case n.left:i=-1}for(var a=this.getRealCol(),h=this.getRealRow(),c=a,d=h,u=null,g=0;gthis.organism_record&&(this.organism_record=e),$("#org-record").text("Highest count: "+this.organism_record),$("#avg-mut").text("Average Mutation Rate: "+Math.round(100*this.engine.env.averageMutability())/100),$("#largest-org").text("Largest Organism: "+this.engine.env.largest_cell_count+" cells"),$("#reset-count").text("Auto reset count: "+this.engine.env.reset_count)}}},function(e,t,i){const s=i(7),r=i(5),o=i(9),n=i(8),l=i(0),a=i(27);i(2);e.exports=class extends s{constructor(){super(),this.is_active=!0;this.renderer=new n("editor-canvas","editor-env",13),this.controller=new a(this,this.renderer.canvas),this.grid_map=new o(15,15,13),this.clear()}update(){this.is_active&&this.renderer.renderHighlights()}changeCell(e,t,i,s){super.changeCell(e,t,i,s),this.renderFull()}renderFull(){this.renderer.renderFullGrid(this.grid_map.grid)}addCellToOrg(e,t,i){var s=this.grid_map.getCenter(),r=e-s[0],o=t-s[1],n=this.organism.getLocalCell(r,o);if(null!=n){var l=this.organism.replaceCell(i,n.loc_col,n.loc_row,!1);this.changeCell(e,t,i,l)}else this.organism.canAddCellAt(r,o)&&this.changeCell(e,t,i,this.organism.addDefaultCell(i,r,o))}removeCellFromOrg(e,t){var i=this.grid_map.getCenter(),s=e-i[0],r=t-i[1];0!=s||0!=r?null!=this.organism.getLocalCell(s,r)&&this.organism.removeCell(s,r)&&this.changeCell(e,t,l.empty,null):alert("Cannot remove center cell")}setOrganismToCopyOf(e){this.grid_map.fillGrid(l.empty);var t=this.grid_map.getCenter();this.organism=new r(t[0],t[1],this,e),this.organism.updateGrid(),this.controller.updateDetails()}getCopyOfOrg(){return new r(0,0,null,this.organism)}clear(){this.grid_map.fillGrid(l.empty);var e=this.grid_map.getCenter();this.organism=new r(e[0],e[1],this,null),this.organism.addDefaultCell(l.mouth,0,0),this.organism.updateGrid()}}},function(e,t,i){const s=i(11),r=i(6),o=i(0),n=i(2),l=i(1);e.exports=class extends s{constructor(e,t){super(e,t),this.mode=r.None,this.edit_cell_type=null,this.highlight_org=!1,this.defineCellTypeSelection(),this.defineEditorDetails()}mouseMove(){(this.right_click||this.left_click)&&this.editOrganism()}mouseDown(){this.editOrganism()}mouseUp(){}getCurLocalCell(){return this.env.organism.getLocalCell(this.mouse_c-this.env.organism.c,this.mouse_r-this.env.organism.r)}editOrganism(){if(null!=this.edit_cell_type&&this.mode==r.Edit){if(this.left_click)if(this.edit_cell_type==o.eye&&this.cur_cell.state==o.eye){var e=this.getCurLocalCell();e.direction=n.rotateRight(e.direction),this.env.renderFull()}else this.env.addCellToOrg(this.mouse_c,this.mouse_r,this.edit_cell_type);this.right_click&&this.env.removeCellFromOrg(this.mouse_c,this.mouse_r),this.setBrainPanelVisibility(),this.setMoveRangeVisibility()}}updateDetails(){$("#birth-distance").val(this.env.organism.birth_distance),$(".cell-count").text("Cell count: "+this.env.organism.cells.length)}defineCellTypeSelection(){var e=this;$(".cell-type").click((function(){switch(this.id){case"mouth":e.edit_cell_type=o.mouth;break;case"producer":e.edit_cell_type=o.producer;break;case"mover":e.edit_cell_type=o.mover;break;case"killer":e.edit_cell_type=o.killer;break;case"armor":e.edit_cell_type=o.armor;break;case"eye":e.edit_cell_type=o.eye}$(".cell-type").css("border-color","black");var t="#"+this.id+".cell-type";$(t).css("border-color","yellow")}))}defineEditorDetails(){this.details_html=$("#organism-details"),this.edit_details_html=$("#edit-organism-details"),this.decision_names=["ignore","move away","move towards"],$("#birth-distance-edit").change(function(){this.env.organism.birth_distance=parseInt($("#birth-distance-edit").val())}.bind(this)),$("#move-range-edit").change(function(){this.env.organism.move_range=parseInt($("#move-range-edit").val())}.bind(this)),$("#observation-type-edit").change(function(){this.setBrainEditorValues($("#observation-type-edit").val())}.bind(this)),$("#reaction-edit").change(function(){var e=$("#observation-type-edit").val(),t=parseInt($("#reaction-edit").val());this.env.organism.brain.decisions[e]=t}.bind(this))}clearDetailsPanel(){$("#organism-details").css("display","none"),$("#edit-organism-details").css("display","none")}setDetailsPanel(){var e=this.env.organism;if($(".cell-count").text("Cell count: "+e.cells.length),$("#birth-distance").text("Reproduction Distance: "+e.birth_distance),$("#move-range").text("Move Range: "+e.move_range),$("#mutation-rate").text("Mutation Rate: "+e.mutability),l.useGlobalMutability?$("#mutation-rate").css("display","none"):$("#mutation-rate").css("display","block"),this.setMoveRangeVisibility(),this.setBrainPanelVisibility()){var t=[],i=[];for(var s in e.brain.decisions){var r=e.brain.decisions[s];1==r?i.push(s):2==r&&t.push(s)}$("#chase-types").text("Move Towards: "+t),$("#retreat-types").text("Move Away From: "+i)}$("#organism-details").css("display","block")}setEditorPanel(){this.clearDetailsPanel();var e=this.env.organism;$(".cell-count").text("Cell count: "+e.cells.length),$("#birth-distance-edit").val(e.birth_distance),this.setMoveRangeVisibility()&&$("#move-range-edit").val(e.move_range),this.setBrainPanelVisibility()&&this.setBrainEditorValues($("#observation-type-edit").val()),$("#cell-selections").css("display","grid"),$("#edit-organism-details").css("display","block")}setBrainPanelVisibility(){var e=this.env.organism;return e.has_eyes&&e.is_mover?($(".brain-details").css("display","block"),!0):($(".brain-details").css("display","none"),!1)}setMoveRangeVisibility(){return this.env.organism.is_mover?($("#move-range-cont").css("display","block"),$("#move-range").css("display","block"),!0):($("#move-range-cont").css("display","none"),$("#move-range").css("display","none"),!1)}setBrainEditorValues(e){$("#observation-type-edit").val(e);var t=this.env.organism.brain.decisions[e];$("#reaction-edit").val(t)}}},function(e,t,i){const s=i(0);var r={empty:"#0E1318",food:"#2F7AB7",wall:"gray",mouth:"#DEB14D",producer:"#15DE59",mover:"#60D4FF",killer:"#F82380",armor:"#7230DB",eye:"#B6C1EA","eye-slit":"#0E1318"};e.exports=class{constructor(e,t){this.world_env=e,this.editor_env=t}loadColorScheme(){for(var e of s.all)e.color=r[e.name];for(var t in s.eye.slit_color=r["eye-slit"],r)$("#"+t+".cell-type ").css("background-color",r[t]),$("#"+t+".cell-legend-type").css("background-color",r[t]);this.world_env.renderer.renderFullGrid(this.world_env.grid_map.grid),this.editor_env.renderer.renderFullGrid(this.editor_env.grid_map.grid)}}}]); \ No newline at end of file diff --git a/dist/json/color_scheme.json b/dist/json/color_scheme.json new file mode 100644 index 0000000..d02fab0 --- /dev/null +++ b/dist/json/color_scheme.json @@ -0,0 +1,3 @@ +{ + "hello": "world" +} \ No newline at end of file diff --git a/src/Controllers/ControlPanel.js b/src/Controllers/ControlPanel.js index d910745..714cd62 100644 --- a/src/Controllers/ControlPanel.js +++ b/src/Controllers/ControlPanel.js @@ -173,9 +173,9 @@ class ControlPanel { defineModeControls() { var self = this; $('.edit-mode-btn').click( function() { - var prev_mode = self.env_controller.mode; $('#cell-selections').css('display', 'none'); $('#organism-options').css('display', 'none'); + self.editor_controller.clearDetailsPanel(); switch(this.id){ case "food-drop": self.setMode(Modes.FoodDrop); @@ -191,8 +191,7 @@ class ControlPanel { break; case "edit": self.setMode(Modes.Edit); - $('#cell-selections').css('display', 'block'); - $('#organism-options').css('display', 'block'); + self.editor_controller.setEditorPanel(); break; case "drop-org": self.setMode(Modes.Clone); @@ -203,7 +202,6 @@ class ControlPanel { } $('.edit-mode-btn').css('background-color', '#9099c2'); $('#'+this.id).css('background-color', '#81d2c7'); - }); $('.reset-view').click( function(){ @@ -224,6 +222,7 @@ class ControlPanel { }.bind(this)); $('#clear-editor').click( function() { this.engine.organism_editor.clear(); + this.editor_controller.setEditorPanel(); }.bind(this)); } @@ -241,6 +240,8 @@ class ControlPanel { setEditorOrganism(org) { this.engine.organism_editor.setOrganismToCopyOf(org); + this.editor_controller.clearDetailsPanel(); + this.editor_controller.setDetailsPanel(); } changeEngineSpeed(change_val) { @@ -259,10 +260,6 @@ class ControlPanel { $('#avg-mut').text("Average Mutation Rate: " + Math.round(this.engine.env.averageMutability() * 100) / 100); $('#largest-org').text("Largest Organism: " + this.engine.env.largest_cell_count + " cells"); $('#reset-count').text("Auto reset count: " + this.engine.env.reset_count); - if (this.editor_controller.env.organism.cells.length > 1) - $('#editor-cell-count').text(this.editor_controller.env.organism.cells.length+' cells'); - else - $('#editor-cell-count').text('1 cell'); } } diff --git a/src/Controllers/EditorController.js b/src/Controllers/EditorController.js index f802459..3702745 100644 --- a/src/Controllers/EditorController.js +++ b/src/Controllers/EditorController.js @@ -2,6 +2,7 @@ const CanvasController = require("./CanvasController"); const Modes = require("./ControlModes"); const CellStates = require("../Organism/Cell/CellStates"); const Directions = require("../Organism/Directions"); +const Hyperparams = require("../Hyperparameters"); class EditorController extends CanvasController{ constructor(env, canvas) { @@ -10,7 +11,7 @@ class EditorController extends CanvasController{ this.edit_cell_type = null; this.highlight_org = false; this.defineCellTypeSelection(); - this.defineEditorOptions(); + this.defineEditorDetails(); } mouseMove() { @@ -42,10 +43,13 @@ class EditorController extends CanvasController{ } if (this.right_click) this.env.removeCellFromOrg(this.mouse_c, this.mouse_r); + this.setBrainPanelVisibility(); + this.setMoveRangeVisibility(); } updateDetails() { $('#birth-distance').val(this.env.organism.birth_distance); + $('.cell-count').text("Cell count: "+this.env.organism.cells.length); } defineCellTypeSelection() { @@ -77,11 +81,112 @@ class EditorController extends CanvasController{ }); } - defineEditorOptions() { - $('#birth-distance').change ( function() { - this.env.organism.birth_distance = parseInt($('#birth-distance').val()); + defineEditorDetails() { + this.details_html = $('#organism-details'); + this.edit_details_html = $('#edit-organism-details'); + + this.decision_names = ["ignore", "move away", "move towards"]; + + $('#birth-distance-edit').change ( function() { + this.env.organism.birth_distance = parseInt($('#birth-distance-edit').val()); }.bind(this)); + $('#move-range-edit').change ( function() { + this.env.organism.move_range = parseInt($('#move-range-edit').val()); + }.bind(this)); + $('#observation-type-edit').change ( function() { + this.setBrainEditorValues($('#observation-type-edit').val()); + }.bind(this)); + $('#reaction-edit').change ( function() { + var obs = $('#observation-type-edit').val(); + var decision = parseInt($('#reaction-edit').val()); + this.env.organism.brain.decisions[obs] = decision; + }.bind(this)); + } + + clearDetailsPanel() { + $('#organism-details').css('display', 'none'); + $('#edit-organism-details').css('display', 'none'); + } + + setDetailsPanel() { + var org = this.env.organism; + $('.cell-count').text("Cell count: "+org.cells.length); + $('#birth-distance').text("Reproduction Distance: "+org.birth_distance); + $('#move-range').text("Move Range: "+org.move_range); + $('#mutation-rate').text("Mutation Rate: "+org.mutability); + if (Hyperparams.useGlobalMutability) { + $('#mutation-rate').css('display', 'none'); + } + else { + $('#mutation-rate').css('display', 'block'); + } + + this.setMoveRangeVisibility(); + + if (this.setBrainPanelVisibility()) { + var chase_types = []; + var retreat_types = []; + for(var cell_name in org.brain.decisions) { + var decision = org.brain.decisions[cell_name]; + if (decision == 1) { + retreat_types.push(cell_name) + } + else if (decision == 2) { + chase_types.push(cell_name); + } + } + $('#chase-types').text("Move Towards: " + chase_types); + $('#retreat-types').text("Move Away From: " + retreat_types); + + } + $('#organism-details').css('display', 'block'); + } + + setEditorPanel() { + this.clearDetailsPanel(); + var org = this.env.organism; + + $('.cell-count').text("Cell count: "+org.cells.length); + $('#birth-distance-edit').val(org.birth_distance); + if (this.setMoveRangeVisibility()){ + $('#move-range-edit').val(org.move_range); + } + + if (this.setBrainPanelVisibility()){ + this.setBrainEditorValues($('#observation-type-edit').val()); + } + + $('#cell-selections').css('display', 'grid'); + $('#edit-organism-details').css('display', 'block'); + } + + setBrainPanelVisibility() { + var org = this.env.organism; + if (org.has_eyes && org.is_mover) { + $('.brain-details').css('display', 'block'); + return true; + } + $('.brain-details').css('display', 'none'); + return false; + } + + setMoveRangeVisibility() { + var org = this.env.organism; + if (org.is_mover) { + $('#move-range-cont').css('display', 'block'); + $('#move-range').css('display', 'block'); + return true; + } + $('#move-range-cont').css('display', 'none'); + $('#move-range').css('display', 'none'); + return false; + } + + setBrainEditorValues(name) { + $('#observation-type-edit').val(name); + var reaction = this.env.organism.brain.decisions[name]; + $('#reaction-edit').val(reaction); } } diff --git a/src/Controllers/EnvironmentController.js b/src/Controllers/EnvironmentController.js index 8685e68..055157f 100644 --- a/src/Controllers/EnvironmentController.js +++ b/src/Controllers/EnvironmentController.js @@ -94,7 +94,6 @@ class EnvironmentController extends CanvasController{ } if (this.cur_org != null){ this.control_panel.setEditorOrganism(this.cur_org); - console.log(this.cur_org) } break; diff --git a/src/Engine.js b/src/Engine.js index 66ca4ce..7143629 100644 --- a/src/Engine.js +++ b/src/Engine.js @@ -1,6 +1,7 @@ const WorldEnvironment = require('./Environments/WorldEnvironment'); const ControlPanel = require('./Controllers/ControlPanel'); const OrganismEditor = require('./Environments/OrganismEditor'); +const ColorScheme = require('./Rendering/ColorScheme'); const render_speed = 60; @@ -10,6 +11,8 @@ class Engine{ this.env = new WorldEnvironment(5); this.organism_editor = new OrganismEditor(); this.controlpanel = new ControlPanel(this); + this.colorscheme = new ColorScheme(this.env, this.organism_editor); + this.colorscheme.loadColorScheme(); this.env.OriginOfLife(); this.last_update = Date.now(); this.delta_time = 0; diff --git a/src/Environments/OrganismEditor.js b/src/Environments/OrganismEditor.js index 0c8864c..9294549 100644 --- a/src/Environments/OrganismEditor.js +++ b/src/Environments/OrganismEditor.js @@ -15,8 +15,6 @@ class OrganismEditor extends Environment{ this.controller = new EditorController(this, this.renderer.canvas); this.grid_map = new GridMap(15, 15, cell_size); this.clear(); - - this.renderer.renderFullGrid(this.grid_map.grid); } update() { @@ -72,7 +70,7 @@ class OrganismEditor extends Environment{ this.organism.updateGrid(); this.controller.updateDetails(); } - + getCopyOfOrg() { var new_org = new Organism(0, 0, null, this.organism); return new_org; diff --git a/src/Environments/WorldEnvironment.js b/src/Environments/WorldEnvironment.js index db3930f..0e89a84 100644 --- a/src/Environments/WorldEnvironment.js +++ b/src/Environments/WorldEnvironment.js @@ -13,7 +13,6 @@ class WorldEnvironment extends Environment{ var grid_rows = Math.floor(this.renderer.height / cell_size); var grid_cols = Math.floor(this.renderer.width / cell_size); this.grid_map = new GridMap(grid_cols, grid_rows, cell_size); - this.renderer.renderFullGrid(this.grid_map.grid); this.organisms = []; this.walls = []; this.total_mutability = 0; diff --git a/src/Hyperparameters.js b/src/Hyperparameters.js index a2c1cdc..8d32145 100644 --- a/src/Hyperparameters.js +++ b/src/Hyperparameters.js @@ -23,7 +23,7 @@ const Hyperparams = { this.instaKill = false; - this.lookRange = 15; + this.lookRange = 20; }, balanceMutationProbs : function(choice) { diff --git a/src/Organism/Cell/CellStates.js b/src/Organism/Cell/CellStates.js index 7919326..b063410 100644 --- a/src/Organism/Cell/CellStates.js +++ b/src/Organism/Cell/CellStates.js @@ -1,8 +1,8 @@ // A cell state is used to differentiate type and render the cell class CellState{ - constructor(name, color) { + constructor(name) { this.name = name; - this.color = color + this.color = 'black'; } render(ctx, cell, size) { @@ -13,48 +13,48 @@ class CellState{ class Empty extends CellState { constructor() { - super('empty', '#121D29'); + super('empty'); } } class Food extends CellState { constructor() { - super('food', 'green'); + super('food'); } } class Wall extends CellState { constructor() { - super('wall', 'gray'); + super('wall'); } } class Mouth extends CellState { constructor() { - super('mouth', 'orange'); + super('mouth'); } } class Producer extends CellState { constructor() { - super('producer', 'white'); + super('producer'); } } class Mover extends CellState { constructor() { - super('mover', '#3493EB'); + super('mover'); } } class Killer extends CellState { constructor() { - super('killer', 'red'); + super('killer'); } } class Armor extends CellState { constructor() { - super('armor', 'purple'); + super('armor'); } } class Eye extends CellState { constructor() { - super('eye', '#d4bb3f'); - this.slit_color = '#121D29'; + super('eye'); + this.slit_color = 'black'; } render(ctx, cell, size) { ctx.fillStyle = this.color; diff --git a/src/Organism/Organism.js b/src/Organism/Organism.js index 8e54005..0812981 100644 --- a/src/Organism/Organism.js +++ b/src/Organism/Organism.js @@ -1,4 +1,3 @@ -// const CellTypes = require("./Cell/CellTypes"); const CellStates = require("../Organism/Cell/CellStates"); const BodyCellFactory = require("./Cell/BodyCells/BodyCellFactory"); const Neighbors = require("../Grid/Neighbors"); @@ -6,8 +5,6 @@ const Hyperparams = require("../Hyperparameters"); const Directions = require("./Directions"); const Brain = require("./Perception/Brain"); -const directions = [[0,1],[0,-1],[1,0],[-1,0]] - class Organism { constructor(col, row, env, parent=null) { this.c = col; @@ -25,6 +22,7 @@ class Organism { this.can_rotate = Hyperparams.moversCanRotate; this.move_count = 0; this.move_range = 4; + this.ignore_brain_for = 0; this.mutability = 5; this.damage = 0; this.birth_distance = 4; @@ -50,6 +48,9 @@ class Organism { } addRandomizedCell(state, c, r) { + if (state==CellStates.eye && !this.has_eyes) { + this.brain.randomizeDecisions(); + } var new_cell = BodyCellFactory.createRandom(this, state, c, r); this.cells.push(new_cell); return new_cell; @@ -188,8 +189,8 @@ class Organism { // add cell // console.log("add cell") - var state = CellStates.getRandomLivingType(); var branch = this.cells[Math.floor(Math.random() * this.cells.length)]; + var state = CellStates.getRandomLivingType();//branch.state; var growth_direction = Neighbors.all[Math.floor(Math.random() * Neighbors.all.length)] var c = branch.loc_col+growth_direction[0]; var r = branch.loc_row+growth_direction[1]; @@ -216,7 +217,7 @@ class Organism { var cell = this.cells[Math.floor(Math.random() * this.cells.length)]; mutated = this.removeCell(cell.loc_col, cell.loc_row); } - } + } if (this.is_mover && Math.random() * 100 <= 10) { this.move_range += Math.floor(Math.random() * 4) - 2; @@ -373,10 +374,21 @@ class Organism { if (this.is_mover) { this.move_count++; - var changed_dir = this.brain.decide(); + var changed_dir = false; + if (this.ignore_brain_for == 0){ + changed_dir = this.brain.decide(); + } + else{ + this.ignore_brain_for --; + } var moved = this.attemptMove(); if ((this.move_count > this.move_range && !changed_dir) || !moved){ - this.attemptRotate(); + var rotated = this.attemptRotate(); + if (!rotated) { + this.changeDirection(Directions.getRandomDirection()); + if (changed_dir) + this.ignore_brain_for = this.move_range + 1; + } } } diff --git a/src/Organism/Perception/Brain.js b/src/Organism/Perception/Brain.js index 8ff8ec4..e52d8a3 100644 --- a/src/Organism/Perception/Brain.js +++ b/src/Organism/Perception/Brain.js @@ -8,6 +8,9 @@ const Decision = { chase: 2, getRandom: function(){ return Math.floor(Math.random() * 3); + }, + getRandomNonNeutral: function() { + return Math.floor(Math.random() * 2)+1; } } @@ -27,7 +30,15 @@ class Brain { this.decisions[CellStates.killer.name] = Decision.retreat; this.decisions[CellStates.armor.name] = Decision.neutral; this.decisions[CellStates.eye.name] = Decision.neutral; - + } + + randomizeDecisions() { + // randomize the non obvious decisions + this.decisions[CellStates.mouth.name] = Decision.getRandom(); + this.decisions[CellStates.producer.name] = Decision.getRandom(); + this.decisions[CellStates.mover.name] = Decision.getRandom(); + this.decisions[CellStates.armor.name] = Decision.getRandom(); + this.decisions[CellStates.eye.name] = Decision.getRandom(); } observe(observation) { diff --git a/src/Rendering/ColorScheme.js b/src/Rendering/ColorScheme.js new file mode 100644 index 0000000..30ce7f9 --- /dev/null +++ b/src/Rendering/ColorScheme.js @@ -0,0 +1,38 @@ +const CellStates = require("../Organism/Cell/CellStates"); + +var color_scheme = { + "empty":"#0E1318", + "food":"#2F7AB7", + "wall":"gray", + "mouth":"#DEB14D", + "producer":"#15DE59", + "mover":"#60D4FF", + "killer":"#F82380", + "armor":"#7230DB", + "eye":"#B6C1EA", + "eye-slit": "#0E1318" +} + +// Renderer controls access to a canvas. There is one renderer for each canvas +class ColorScheme { + constructor(world_env, editor_env) { + this.world_env = world_env; + this.editor_env = editor_env; + } + + loadColorScheme() { + for (var state of CellStates.all) { + state.color = color_scheme[state.name]; + } + CellStates.eye.slit_color=color_scheme['eye-slit'] + for (var cell_type in color_scheme) { + $('#'+cell_type+'.cell-type ').css('background-color', color_scheme[cell_type]); + $('#'+cell_type+'.cell-legend-type').css('background-color', color_scheme[cell_type]); + + } + this.world_env.renderer.renderFullGrid(this.world_env.grid_map.grid); + this.editor_env.renderer.renderFullGrid(this.editor_env.grid_map.grid); + } +} + +module.exports = ColorScheme; \ No newline at end of file