diff --git a/dist/css/style.css b/dist/css/style.css index 3ac6f65..4a88103 100644 --- a/dist/css/style.css +++ b/dist/css/style.css @@ -19,7 +19,10 @@ body{ width: 100%; text-align: center; transform: scale(1); - image-rendering: pixelated; + image-rendering: -moz-crisp-edges; + image-rendering: -webkit-crisp-edges; + image-rendering: pixelated; + image-rendering: crisp-edges; } #env-canvas { @@ -49,7 +52,10 @@ body{ } img { - image-rendering: pixelated; + image-rendering: -moz-crisp-edges; + image-rendering: -webkit-crisp-edges; + image-rendering: pixelated; + image-rendering: crisp-edges; width: 60%; border-radius: 10px; } @@ -152,7 +158,10 @@ button:hover{ bottom: 0; } #editor-env { - image-rendering: pixelated; + image-rendering: -moz-crisp-edges; + image-rendering: -webkit-crisp-edges; + image-rendering: pixelated; + image-rendering: crisp-edges; height: 195px; width: 195px; } diff --git a/dist/index.html b/dist/index.html index b1e9c5c..9ff24a8 100644 --- a/dist/index.html +++ b/dist/index.html @@ -56,7 +56,7 @@

About

Editor

-

Rule Tuning

+

Simulation Controls

Stats

@@ -118,7 +118,7 @@
-

Rule Tuning

+

Simulation Controls

Food Production vs Lifespan

@@ -161,7 +161,7 @@
- +
diff --git a/dist/js/bundle.js b/dist/js/bundle.js index 3f8c340..2d7f096 100644 --- a/dist/js/bundle.js +++ b/dist/js/bundle.js @@ -1 +1,288 @@ -!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=11)}([function(e,t){const i={empty:0,food:1,wall:2,mouth:3,producer:4,mover:5,killer:6,armor:7,colors:["#121D29","green","gray","orange","white","#3493eb","red","purple"],getRandomLivingType:function(){return Math.floor(5*Math.random())+3}};e.exports=i},function(e,t,i){const s=i(0),r=i(3);function o(e,t,i){null!=t&&t.type==s.food&&(i.changeCell(t.col,t.row,s.empty,null),e.owner.food_collected++)}function l(e,t){if(null!=t&&null!=t.owner&&null!=e.owner&&t.owner!=e.owner&&t.owner.living&&t.type!=s.armor){var i=t.type==s.killer;t.owner.harm(),i&&e.owner.harm()}}e.exports=class{constructor(e,t,i,s,r){this.owner=null,this.setType(e),this.col=t,this.row=i,this.x=s,this.y=r}setType(e){this.type=e}performFunction(e){switch(this.type){case s.mouth:!function(e,t){for(var i of r.edibleNeighbors){var s=t.grid_map.cellAt(e.col+i[0],e.row+i[1]);o(e,s,t)}}(this,e);break;case s.producer:!function(e,t){if(e.owner.is_mover&&!r.moversCanProduce)return;var i=r.foodProdProb;if(100*Math.random()<=i){var o=r.growableNeighbors[Math.floor(Math.random()*r.growableNeighbors.length)],l=o[0],n=o[1],a=t.grid_map.cellAt(e.col+l,e.row+n);if(null!=a&&a.type==s.empty)t.changeCell(e.col+l,e.row+n,s.food,null)}}(this,e);break;case s.killer:!function(e,t){for(var i of r.killableNeighbors){var s=t.grid_map.cellAt(e.col+i[0],e.row+i[1]);l(e,s)}}(this,e)}}getColor(){return s.colors[this.type]}isLiving(){return this.type!=s.empty&&this.type!=s.food&&this.type!=s.wall}}},function(e,t,i){const s=i(1),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){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},calcProducerFoodRatio:function(e=!0){e?this.foodProdProb=100/this.lifespanMultiplier*this.foodProdProbScalar:this.lifespanMultiplier=Math.floor(100/(this.foodProdProb/this.foodProdProbScalar))},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){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(1),i(2),i(13)),o=i(4),l=i(3),n=i(8);class a{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.direction=n.up,this.rotation=n.up,this.can_rotate=l.moversCanRotate,this.move_count=0,this.move_range=4,this.mutability=5,this.damage=0,null!=s&&this.inherit(s)}addCell(e,t,i){for(var s of this.cells)if(s.loc_col==t&&s.loc_row==i)return!1;return this.checkProducerMover(e),this.cells.push(new r(e,t,i)),!0}removeCell(e,t){if(0==e&&0==t)return!1;for(var i=!1,r=0;r1&&(c=this.cells[Math.floor(Math.random()*this.cells.length)],t=this.removeCell(c.loc_col,c.loc_row));return this.is_mover&&(this.move_range+=Math.floor(4*Math.random())-2,this.move_range<=0&&(this.move_range=1)),t}attemptMove(){var e=n.scalars[this.direction],t=e[0],i=e[1],r=this.c+t,o=this.r+i;if(this.isClear(r,o)){for(var l of this.cells){var a=this.c+l.rotatedCol(this.rotation),h=this.r+l.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=n.getRandomDirection(),this.move_count=0,!0;var e=n.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=n.getRandomDirection(),this.updateGrid(),this.move_count=0,!0}return!1}isStraightPath(e,t,i,s,r){if(e==i){if(t>s){var o=s;s=t,t=o}for(var l=t;l!=s;l++){var n=this.env.grid_map.cellAt(e,l);if(!this.isPassableCell(n,r))return!1}return!0}if(e>i){o=i;i=e,e=o}for(l=e;l!=i;l++){n=this.env.grid_map.cellAt(l,t);if(!this.isPassableCell(n,r))return!1}return!0}isPassableCell(e,t){return null!=e&&(e.type==s.empty||e.owner==this||e.owner==t||e.type==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.type!=s.empty&&(l.foodBlocksReproduction||o.type!=s.food))return!1}return!0}harm(){this.damage++,(this.damage>=this.maxHealth()||l.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.type,this)}}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))this.getRealCell(e).performFunction(this.env);if(!this.living)return this.living;if(this.is_mover){this.move_count++;this.attemptMove();this.move_count>this.move_range&&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=a},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(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.ctx.fillStyle=i.getColor(),this.ctx.fillRect(i.x,i.y,this.cell_size,this.cell_size)}renderCells(){for(var e of this.cells_to_render)this.renderCell(e);this.cells_to_render.clear()}renderCell(e){this.ctx.fillStyle=e.getColor(),this.ctx.fillRect(e.x,e.y,this.cell_size,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){const i={up:0,down:1,left:2,right:3,scalars:[[0,-1],[0,1],[-1,0],[1,0]],getRandomDirection:function(){return Math.floor(4*Math.random())},getRandomScalar:function(){return this.scalars[Math.floor(Math.random()*this.scalars.length)]}};e.exports=i},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.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 overriden")}mouseDown(){alert("mouse down must be overriden")}}},function(e,t,i){const s=i(12),r=i(15),o=i(16);e.exports=class{constructor(){this.fps=60,this.env=new s(4),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(10),r=i.n(s);$("document").ready((function(){(new r.a).start(60)}))},function(e,t,i){i(2);const s=i(7),r=i(2),o=i(5),l=i(0),n=(i(1),i(14));e.exports=class{constructor(e){this.renderer=new s("env-canvas","env",e),this.controller=new n(this,this.renderer.canvas),this.grid_rows=Math.floor(this.renderer.height/e),this.grid_cols=Math.floor(this.renderer.width/e),this.grid_map=new r(this.grid_cols,this.grid_rows,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 o(e[0],e[1],this);t.addCell(l.mouth,0,0),t.addCell(l.producer,-1,-1),t.addCell(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){this.grid_map.setCellType(e,t,i),this.grid_map.setCellOwner(e,t,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).type==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){i(0);const s=i(8);i(3);e.exports=class{constructor(e,t,i){this.type=e,this.loc_col=t,this.loc_row=i}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,i){const s=i(9),r=i(5),o=i(6),l=i(0),n=i(4);i(1);e.exports=class extends s{constructor(e,t){super(e,t),this.mode=o.Drag,this.org_to_clone=null,this.defineZoomControls(),this.prev_x,this.prev_y,this.scale=1}defineZoomControls(){var e=1;const t=document.querySelector("#env-canvas");t.onwheel=function(i){i.preventDefault();var s=-1*Math.sign(i.deltaY);e=Math.max(.5,e+.5*s),t.style.transform=`scale(${e})`,this.scale=e}.bind(this)}resetView(){$("#env-canvas").css("transform","scale(1)"),$("#env-canvas").css("top","0px"),$("#env-canvas").css("left","0px"),this.scale=1}updateMouseLocation(e,t){this.prev_x=this.mouse_x,this.prev_y=this.mouse_y,super.updateMouseLocation(e,t)}mouseMove(){this.performModeAction()}mouseDown(){this.performModeAction()}performModeAction(){var e=this.mode,t=this.right_click,i=this.left_click;if(e!=o.None&&(t||i)){var s=this.cur_cell;if(null==s)return;switch(e){case o.FoodDrop:i?this.dropCellType(s.col,s.row,l.food,!1):t&&this.dropCellType(s.col,s.row,l.empty,!1);break;case o.WallDrop:i?this.dropCellType(s.col,s.row,l.wall,!0):t&&this.dropCellType(s.col,s.row,l.empty,!1);break;case o.ClickKill:this.killNearOrganisms();break;case o.Select:null==this.cur_org&&(this.cur_org=this.findNearOrganism()),null!=this.cur_org&&this.control_panel.setEditorOrganism(this.cur_org);break;case o.Clone:if(null!=this.org_to_clone){var n=new r(this.mouse_c,this.mouse_r,this.env,this.org_to_clone);n.isClear(this.mouse_c,this.mouse_r)&&this.env.addOrganism(n)}break;case o.Drag:var a=parseInt($("#env-canvas").css("top"),10),h=parseInt($("#env-canvas").css("left"),10),c=a+(this.mouse_y-this.prev_y)*this.scale,d=h+(this.mouse_x-this.prev_x)*this.scale;$("#env-canvas").css("top",c+"px"),$("#env-canvas").css("left",d+"px")}}}dropCellType(e,t,i,s=!1){for(var r of n.allSelf){var o=e+r[0],l=t+r[1],a=this.env.grid_map.cellAt(o,l);if(null!=a){if(s&&null!=a.owner)a.owner.die();else if(null!=a.owner)continue;this.env.changeCell(o,l,i,null)}}}findNearOrganism(){for(var e of n.all){var t=this.cur_cell.col+e[0],i=this.cur_cell.row+e[1],s=this.env.grid_map.cellAt(t,i);if(null!=s.owner)return s.owner}return null}killNearOrganisms(){for(var e of n.allSelf){var t=this.cur_cell.col+e[0],i=this.cur_cell.row+e[1],s=this.env.grid_map.cellAt(t,i);null!=s.owner&&s.owner.die()}}}},function(e,t,i){const s=i(3),r=i(6);i(0);e.exports=class{constructor(e){this.engine=e,this.defineMinMaxControls(),this.defineEngineSpeedControls(),this.defineGridSizeControls(),this.defineTabNavigation(),this.defineHyperparameterControls(),this.defineModeControls(),this.fps=e.fps,this.organism_record=0,this.env_controller=this.engine.env.controller,this.editor_controller=this.engine.organism_editor.controller,this.env_controller.setControlPanel(this),this.editor_controller.setControlPanel(this)}defineMinMaxControls(){$("#minimize").click((function(){console.log("hello"),$(".control-panel").css("display","none"),$("#maximize").css("display","block")})),$("#maximize").click((function(){$(".control-panel").css("display","grid"),$("#maximize").css("display","none")}))}defineEngineSpeedControls(){this.slider=document.getElementById("slider"),this.slider.oninput=function(){this.fps=this.slider.value,this.engine.running&&this.changeEngineSpeed(this.fps),$("#fps").text("Target FPS: "+this.fps)}.bind(this),$("#pause-button").click(function(){$("#pause-button").find("i").toggleClass("fa fa-pause"),$("#pause-button").find("i").toggleClass("fa fa-play"),this.engine.running?this.engine.stop():this.engine.running||this.engine.start(this.fps)}.bind(this))}defineGridSizeControls(){$("#fill-window").change((function(){this.checked?$(".col-row-input").css("display","none"):$(".col-row-input").css("display","block")})),$("#resize").click(function(){var e=$("#cell-size").val();if($("#fill-window").is(":checked"))this.engine.env.resizeFillWindow(e);else{var t=$("#col-input").val(),i=$("#row-input").val();this.engine.env.resizeGridColRow(e,t,i)}}.bind(this))}defineTabNavigation(){var e=this;$(".tabnav-item").click((function(){$(".tab").css("display","none");var t="#"+this.id+".tab";e.engine.organism_editor.is_active="editor"==this.id,$(t).css("display","grid")}))}defineHyperparameterControls(){$("#food-prod-prob").change(function(){var e=$("#food-prod-prob").val();$("#fixed-ratio").is(":checked")?(s.foodProdProb=e,s.calcProducerFoodRatio(!1),$("#lifespan-multiplier").val(s.lifespanMultiplier)):s.foodProdProb=e}.bind(this)),$("#lifespan-multiplier").change(function(){var e=$("#lifespan-multiplier").val();$("#fixed-ratio").is(":checked")?(s.lifespanMultiplier=e,s.calcProducerFoodRatio(!0),$("#food-prod-prob").val(s.foodProdProb)):s.lifespanMultiplier=e}.bind(this)),$("#mover-rot").change((function(){s.moversCanRotate=this.checked})),$("#offspring-rot").change((function(){s.offspringRotate=this.checked})),$("#insta-kill").change((function(){s.instaKill=this.checked})),$("#evolved-mutation").change((function(){this.checked?($(".global-mutation-in").css("display","none"),$("#avg-mut").css("display","block")):($(".global-mutation-in").css("display","block"),$("#avg-mut").css("display","none")),s.useGlobalMutability=!this.checked})),$("#global-mutation").change((function(){s.globalMutability=$("#global-mutation").val()})),$(".mut-prob").change((function(){switch(this.id){case"add-prob":s.addProb=this.value,s.balanceMutationProbs(1);break;case"change-prob":s.changeProb=this.value,s.balanceMutationProbs(2);break;case"remove-prob":s.removeProb=this.value,s.balanceMutationProbs(3)}$("#add-prob").val(Math.floor(s.addProb)),$("#change-prob").val(Math.floor(s.changeProb)),$("#remove-prob").val(Math.floor(s.removeProb))})),$("#movers-produce").change((function(){s.moversCanProduce=this.checked})),$("#food-blocks").change((function(){s.foodBlocksReproduction=this.checked})),$("#reset-rules").click((function(){s.setDefaults(),$("#food-prod-prob").val(s.foodProdProb),$("#lifespan-multiplier").val(s.lifespanMultiplier),$("#fixed-ratio").prop("checked",!0),$("#mover-rot").prop("checked",s.moversCanRotate),$("#offspring-rot").prop("checked",s.offspringRotate),$("#insta-kill").prop("checked",s.instaKill),$("#evolved-mutation").prop("checked",!s.useGlobalMutability),$("#add-prob").val(s.addProb),$("#change-prob").val(s.changeProb),$("#remove-prob").val(s.removeProb),$("#movers-produce").prop("checked",s.moversCanProduce),$("#food-blocks").prop("checked",s.foodBlocksReproduction),s.useGlobalMutability?($(".global-mutation-in").css("display","block"),$("#avg-mut").css("display","none")):($(".global-mutation-in").css("display","none"),$("#avg-mut").css("display","block"))}))}defineModeControls(){var e=this;$(".edit-mode-btn").click((function(){e.env_controller.mode;switch($("#cell-selections").css("display","none"),this.id){case"food-drop":e.setMode(r.FoodDrop);break;case"wall-drop":e.setMode(r.WallDrop);break;case"click-kill":e.setMode(r.ClickKill);break;case"select":e.setMode(r.Select);break;case"edit":e.setMode(r.Edit),$("#cell-selections").css("display","block");break;case"drop-org":e.setMode(r.Clone),e.env_controller.org_to_clone=e.engine.organism_editor.getCopyOfOrg();break;case"drag-view":e.setMode(r.Drag)}$(".edit-mode-btn").css("background-color","#9099c2"),$("#"+this.id).css("background-color","#81d2c7")})),$("#reset-view").click(function(){this.env_controller.resetView()}.bind(this));var t=this.engine.env;$("#reset-env").click(function(){this.engine.env.reset()}.bind(this)),$("#auto-reset").change((function(){t.auto_reset=this.checked})),$("#clear-walls").click(function(){confirm("Are you sure you want to clear all the walls?")&&this.engine.env.clearWalls()}.bind(this)),$("#clear-editor").click(function(){this.engine.organism_editor.clear()}.bind(this))}setMode(e){this.env_controller.mode=e,this.editor_controller.mode=e}setEditorOrganism(e){this.engine.organism_editor.setOrganismToCopyOf(e)}changeEngineSpeed(e){this.engine.stop(),this.engine.start(e),this.fps=this.engine.fps}update(){$("#fps-actual").text("Actual FPS: "+Math.floor(this.engine.actual_fps));var e=this.engine.env.organisms.length;$("#org-count").text("Organism count: "+e),e>this.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(5),r=i(2),o=i(7),l=i(0),n=i(17);i(1);e.exports=class{constructor(){this.is_active=!0;this.grid_map=new r(15,15,13),this.renderer=new o("editor-canvas","editor-env",13),this.controller=new n(this,this.renderer.canvas),this.clear(),this.renderer.renderFullGrid(this.grid_map.grid)}update(){this.is_active&&this.renderer.renderHighlights()}changeCell(e,t,i,s){this.grid_map.setCellType(e,t,i),this.grid_map.setCellOwner(e,t,s),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],l=this.organism.getLocalCell(r,o);null!=l?(l.type=i,this.changeCell(e,t,i,this.organism)):this.organism.addCell(i,r,o)&&this.changeCell(e,t,i,this.organism)}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 s(t[0],t[1],this,e),this.organism.updateGrid()}getCopyOfOrg(){return new s(0,0,null,this.organism)}clear(){this.grid_map.fillGrid(l.empty);var e=this.grid_map.getCenter();this.organism=new s(e[0],e[1],this,null),this.organism.addCell(l.mouth,0,0),this.organism.updateGrid()}}},function(e,t,i){const s=i(9),r=i(6),o=i(0);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()}mouseMove(){(this.right_click||this.left_click)&&this.editOrganism()}mouseDown(){this.editOrganism()}editOrganism(){null!=this.edit_cell_type&&this.mode==r.Edit&&(this.left_click&&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))}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}$(".cell-type").css("border-color","black");var t="#"+this.id+".cell-type";$(t).css("border-color","yellow")}))}}}]); \ No newline at end of file +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = "./src/index.js"); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./src/Controllers/CanvasController.js": +/*!*********************************************!*\ + !*** ./src/Controllers/CanvasController.js ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("\r\n\r\nclass CanvasController{\r\n constructor(env, canvas) {\r\n this.env = env;\r\n this.canvas = canvas;\r\n this.mouse_x;\r\n this.mouse_y;\r\n this.mouse_c;\r\n this.mouse_r;\r\n this.left_click = false;\r\n this.right_click = false;\r\n this.cur_cell = null;\r\n this.cur_org = null;\r\n this.highlight_org = true;\r\n this.defineEvents();\r\n }\r\n\r\n setControlPanel(panel){\r\n this.control_panel = panel;\r\n }\r\n\r\n defineEvents() {\r\n this.canvas.addEventListener('mousemove', e => {\r\n this.updateMouseLocation(e.offsetX, e.offsetY)\r\n this.mouseMove();\r\n });\r\n\r\n this.canvas.addEventListener('mouseup', function(evt) {\r\n evt.preventDefault();\r\n this.updateMouseLocation(evt.offsetX, evt.offsetY)\r\n this.left_click=false;\r\n this.right_click=false;\r\n }.bind(this));\r\n\r\n this.canvas.addEventListener('mousedown', function(evt) {\r\n evt.preventDefault();\r\n this.updateMouseLocation(evt.offsetX, evt.offsetY)\r\n if (evt.button == 0) {\r\n this.left_click = true;\r\n }\r\n if (evt.button == 2) \r\n this.right_click = true;\r\n this.mouseDown();\r\n }.bind(this));\r\n\r\n this.canvas.addEventListener('contextmenu', function(evt) {\r\n evt.preventDefault();\r\n });\r\n\r\n this.canvas.addEventListener('mouseleave', function(){\r\n this.right_click = false;\r\n this.left_click = false;\r\n this.env.renderer.clearAllHighlights(true);\r\n }.bind(this));\r\n\r\n }\r\n\r\n updateMouseLocation(offsetX, offsetY) {\r\n var prev_cell = this.cur_cell;\r\n var prev_org = this.cur_org;\r\n\r\n this.mouse_x = offsetX;\r\n this.mouse_y = offsetY;\r\n var colRow = this.env.grid_map.xyToColRow(this.mouse_x, this.mouse_y);\r\n this.mouse_c = colRow[0];\r\n this.mouse_r = colRow[1];\r\n this.cur_cell = this.env.grid_map.cellAt(this.mouse_c, this.mouse_r);\r\n this.cur_org = this.cur_cell.owner;\r\n\r\n if (this.cur_org != prev_org || this.cur_cell != prev_cell) {\r\n this.env.renderer.clearAllHighlights(true);\r\n if (this.cur_org != null && this.highlight_org) {\r\n this.env.renderer.highlightOrganism(this.cur_org);\r\n }\r\n else if (this.cur_cell != null) {\r\n this.env.renderer.highlightCell(this.cur_cell, true);\r\n }\r\n }\r\n }\r\n\r\n mouseMove() {\r\n alert(\"mouse move must be overriden\");\r\n }\r\n\r\n mouseDown() {\r\n alert(\"mouse down must be overriden\");\r\n }\r\n}\r\n\r\nmodule.exports = CanvasController;\n\n//# sourceURL=webpack:///./src/Controllers/CanvasController.js?"); + +/***/ }), + +/***/ "./src/Controllers/ControlModes.js": +/*!*****************************************!*\ + !*** ./src/Controllers/ControlModes.js ***! + \*****************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("const Modes = {\r\n None: 0,\r\n FoodDrop: 1,\r\n WallDrop: 2,\r\n ClickKill: 3,\r\n Select: 4,\r\n Edit: 5,\r\n Clone: 6,\r\n Drag: 7\r\n}\r\n\r\nmodule.exports = Modes;\n\n//# sourceURL=webpack:///./src/Controllers/ControlModes.js?"); + +/***/ }), + +/***/ "./src/Controllers/ControlPanel.js": +/*!*****************************************!*\ + !*** ./src/Controllers/ControlPanel.js ***! + \*****************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const Hyperparams = __webpack_require__(/*! ../Hyperparameters */ \"./src/Hyperparameters.js\");\r\nconst Modes = __webpack_require__(/*! ./ControlModes */ \"./src/Controllers/ControlModes.js\");\r\nconst CellTypes = __webpack_require__(/*! ../Organism/Cell/CellTypes */ \"./src/Organism/Cell/CellTypes.js\");\r\n\r\nclass ControlPanel {\r\n constructor(engine) {\r\n this.engine = engine;\r\n this.defineMinMaxControls();\r\n this.defineEngineSpeedControls();\r\n this.defineGridSizeControls();\r\n this.defineTabNavigation();\r\n this.defineHyperparameterControls();\r\n this.defineModeControls();\r\n this.fps = engine.fps;\r\n this.organism_record=0;\r\n this.env_controller = this.engine.env.controller;\r\n this.editor_controller = this.engine.organism_editor.controller;\r\n this.env_controller.setControlPanel(this);\r\n this.editor_controller.setControlPanel(this);\r\n }\r\n\r\n defineMinMaxControls(){\r\n $('#minimize').click ( function() {\r\n console.log('hello')\r\n $('.control-panel').css('display', 'none');\r\n $('#maximize').css('display', 'block');\r\n });\r\n $('#maximize').click ( function() {\r\n $('.control-panel').css('display', 'grid');\r\n $('#maximize').css('display', 'none');\r\n\r\n });\r\n }\r\n\r\n defineEngineSpeedControls(){\r\n this.slider = document.getElementById(\"slider\");\r\n this.slider.oninput = function() {\r\n this.fps = this.slider.value\r\n if (this.engine.running) {\r\n this.changeEngineSpeed(this.fps);\r\n \r\n }\r\n $('#fps').text(\"Target FPS: \"+this.fps);\r\n }.bind(this);\r\n $('#pause-button').click(function() {\r\n $('#pause-button').find(\"i\").toggleClass(\"fa fa-pause\");\r\n $('#pause-button').find(\"i\").toggleClass(\"fa fa-play\");\r\n if (this.engine.running) {\r\n this.engine.stop();\r\n }\r\n else if (!this.engine.running){\r\n this.engine.start(this.fps);\r\n }\r\n }.bind(this));\r\n }\r\n\r\n defineGridSizeControls() {\r\n $('#fill-window').change(function() {\r\n if (this.checked)\r\n $('.col-row-input').css('display' ,'none');\r\n else\r\n $('.col-row-input').css('display' ,'block');\r\n });\r\n\r\n $('#resize').click(function() {\r\n var cell_size = $('#cell-size').val();\r\n var fill_window = $('#fill-window').is(\":checked\");\r\n if (fill_window) {\r\n this.engine.env.resizeFillWindow(cell_size);\r\n }\r\n else {\r\n var cols = $('#col-input').val();\r\n var rows = $('#row-input').val();\r\n this.engine.env.resizeGridColRow(cell_size, cols, rows);\r\n }\r\n \r\n }.bind(this));\r\n }\r\n\r\n defineTabNavigation() {\r\n var self = this;\r\n $('.tabnav-item').click(function() {\r\n $('.tab').css('display', 'none');\r\n var tab = '#'+this.id+'.tab';\r\n self.engine.organism_editor.is_active = (this.id == 'editor');\r\n $(tab).css('display', 'grid');\r\n });\r\n }\r\n\r\n defineHyperparameterControls() {\r\n $('#food-prod-prob').change(function() {\r\n var food_prob = $('#food-prod-prob').val();\r\n if ($('#fixed-ratio').is(\":checked\")) {\r\n Hyperparams.foodProdProb = food_prob;\r\n Hyperparams.calcProducerFoodRatio(false);\r\n $('#lifespan-multiplier').val(Hyperparams.lifespanMultiplier);\r\n }\r\n else{\r\n Hyperparams.foodProdProb = food_prob;\r\n }\r\n }.bind(this));\r\n $('#lifespan-multiplier').change(function() {\r\n var lifespan = $('#lifespan-multiplier').val();\r\n if ($('#fixed-ratio').is(\":checked\")) {\r\n Hyperparams.lifespanMultiplier = lifespan;\r\n Hyperparams.calcProducerFoodRatio(true);\r\n $('#food-prod-prob').val(Hyperparams.foodProdProb);\r\n }\r\n else {\r\n Hyperparams.lifespanMultiplier = lifespan;\r\n }\r\n }.bind(this));\r\n\r\n $('#mover-rot').change(function() {\r\n Hyperparams.moversCanRotate = this.checked;\r\n });\r\n $('#offspring-rot').change(function() {\r\n Hyperparams.offspringRotate = this.checked;\r\n });\r\n $('#insta-kill').change(function() {\r\n Hyperparams.instaKill = this.checked;\r\n });\r\n\r\n $('#evolved-mutation').change( function() {\r\n if (this.checked) {\r\n $('.global-mutation-in').css('display', 'none');\r\n $('#avg-mut').css('display', 'block');\r\n }\r\n else {\r\n $('.global-mutation-in').css('display', 'block');\r\n $('#avg-mut').css('display', 'none');\r\n }\r\n Hyperparams.useGlobalMutability = !this.checked;\r\n });\r\n $('#global-mutation').change( function() {\r\n Hyperparams.globalMutability = $('#global-mutation').val();\r\n });\r\n $('.mut-prob').change( function() {\r\n switch(this.id){\r\n case \"add-prob\":\r\n Hyperparams.addProb = this.value;\r\n Hyperparams.balanceMutationProbs(1);\r\n break;\r\n case \"change-prob\":\r\n Hyperparams.changeProb = this.value;\r\n Hyperparams.balanceMutationProbs(2);\r\n break;\r\n case \"remove-prob\":\r\n Hyperparams.removeProb = this.value;\r\n Hyperparams.balanceMutationProbs(3);\r\n break;\r\n }\r\n $('#add-prob').val(Math.floor(Hyperparams.addProb));\r\n $('#change-prob').val(Math.floor(Hyperparams.changeProb));\r\n $('#remove-prob').val(Math.floor(Hyperparams.removeProb));\r\n });\r\n $('#movers-produce').change( function() {\r\n Hyperparams.moversCanProduce = this.checked;\r\n });\r\n $('#food-blocks').change( function() {\r\n Hyperparams.foodBlocksReproduction = this.checked; \r\n });\r\n $('#reset-rules').click( function() {\r\n Hyperparams.setDefaults();\r\n $('#food-prod-prob').val(Hyperparams.foodProdProb);\r\n $('#lifespan-multiplier').val(Hyperparams.lifespanMultiplier);\r\n $('#fixed-ratio').prop('checked', true);\r\n $('#mover-rot').prop('checked', Hyperparams.moversCanRotate);\r\n $('#offspring-rot').prop('checked', Hyperparams.offspringRotate);\r\n $('#insta-kill').prop('checked', Hyperparams.instaKill);\r\n $('#evolved-mutation').prop('checked', !Hyperparams.useGlobalMutability);\r\n $('#add-prob').val(Hyperparams.addProb);\r\n $('#change-prob').val(Hyperparams.changeProb);\r\n $('#remove-prob').val(Hyperparams.removeProb);\r\n $('#movers-produce').prop('checked', Hyperparams.moversCanProduce);\r\n $('#food-blocks').prop('checked', Hyperparams.foodBlocksReproduction);\r\n if (!Hyperparams.useGlobalMutability) {\r\n $('.global-mutation-in').css('display', 'none');\r\n $('#avg-mut').css('display', 'block');\r\n }\r\n else {\r\n $('.global-mutation-in').css('display', 'block');\r\n $('#avg-mut').css('display', 'none');\r\n }\r\n });\r\n }\r\n\r\n defineModeControls() {\r\n var self = this;\r\n $('.edit-mode-btn').click( function() {\r\n var prev_mode = self.env_controller.mode;\r\n $('#cell-selections').css('display', 'none');\r\n switch(this.id){\r\n case \"food-drop\":\r\n self.setMode(Modes.FoodDrop);\r\n break;\r\n case \"wall-drop\":\r\n self.setMode(Modes.WallDrop);\r\n break;\r\n case \"click-kill\":\r\n self.setMode(Modes.ClickKill);\r\n break;\r\n case \"select\":\r\n self.setMode(Modes.Select);\r\n break;\r\n case \"edit\":\r\n self.setMode(Modes.Edit);\r\n $('#cell-selections').css('display', 'block');\r\n break;\r\n case \"drop-org\":\r\n self.setMode(Modes.Clone);\r\n self.env_controller.org_to_clone = self.engine.organism_editor.getCopyOfOrg();\r\n break;\r\n case \"drag-view\":\r\n self.setMode(Modes.Drag);\r\n }\r\n $('.edit-mode-btn').css('background-color', '#9099c2');\r\n $('#'+this.id).css('background-color', '#81d2c7');\r\n\r\n });\r\n\r\n $('#reset-view').click( function(){\r\n this.env_controller.resetView();\r\n }.bind(this));\r\n\r\n var env = this.engine.env;\r\n $('#reset-env').click( function() {\r\n this.engine.env.reset();\r\n }.bind(this));\r\n $('#auto-reset').change(function() {\r\n env.auto_reset = this.checked;\r\n });\r\n $('#clear-walls').click( function() {\r\n if (confirm(\"Are you sure you want to clear all the walls?\")) {\r\n this.engine.env.clearWalls();\r\n }\r\n }.bind(this));\r\n $('#clear-editor').click( function() {\r\n this.engine.organism_editor.clear();\r\n }.bind(this));\r\n }\r\n\r\n setMode(mode) {\r\n this.env_controller.mode = mode;\r\n this.editor_controller.mode = mode;\r\n }\r\n\r\n setEditorOrganism(org) {\r\n this.engine.organism_editor.setOrganismToCopyOf(org);\r\n }\r\n\r\n changeEngineSpeed(change_val) {\r\n this.engine.stop();\r\n this.engine.start(change_val)\r\n this.fps = this.engine.fps;\r\n }\r\n\r\n update() {\r\n $('#fps-actual').text(\"Actual FPS: \" + Math.floor(this.engine.actual_fps));\r\n var org_count = this.engine.env.organisms.length;\r\n $('#org-count').text(\"Organism count: \" + org_count);\r\n if (org_count > this.organism_record) \r\n this.organism_record = org_count;\r\n $('#org-record').text(\"Highest count: \" + this.organism_record);\r\n $('#avg-mut').text(\"Average Mutation Rate: \" + Math.round(this.engine.env.averageMutability() * 100) / 100);\r\n $('#largest-org').text(\"Largest Organism: \" + this.engine.env.largest_cell_count + \" cells\");\r\n $('#reset-count').text(\"Auto reset count: \" + this.engine.env.reset_count);\r\n }\r\n\r\n}\r\n\r\n\r\nmodule.exports = ControlPanel;\n\n//# sourceURL=webpack:///./src/Controllers/ControlPanel.js?"); + +/***/ }), + +/***/ "./src/Controllers/EditorController.js": +/*!*********************************************!*\ + !*** ./src/Controllers/EditorController.js ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const CanvasController = __webpack_require__(/*! ./CanvasController */ \"./src/Controllers/CanvasController.js\");\r\nconst Modes = __webpack_require__(/*! ./ControlModes */ \"./src/Controllers/ControlModes.js\");\r\nconst CellTypes = __webpack_require__(/*! ../Organism/Cell/CellTypes */ \"./src/Organism/Cell/CellTypes.js\");\r\n\r\nclass EditorController extends CanvasController{\r\n constructor(env, canvas) {\r\n super(env, canvas);\r\n this.mode = Modes.None;\r\n this.edit_cell_type = null;\r\n this.highlight_org = false;\r\n this.defineCellTypeSelection();\r\n }\r\n\r\n mouseMove() {\r\n if (this.right_click || this.left_click)\r\n this.editOrganism();\r\n }\r\n\r\n mouseDown() {\r\n this.editOrganism();\r\n }\r\n\r\n editOrganism() {\r\n if (this.edit_cell_type == null || this.mode != Modes.Edit)\r\n return;\r\n if (this.left_click)\r\n this.env.addCellToOrg(this.mouse_c, this.mouse_r, this.edit_cell_type);\r\n if (this.right_click)\r\n this.env.removeCellFromOrg(this.mouse_c, this.mouse_r);\r\n }\r\n\r\n defineCellTypeSelection() {\r\n var self = this;\r\n $('.cell-type').click( function() {\r\n switch(this.id){\r\n case \"mouth\":\r\n self.edit_cell_type = CellTypes.mouth;\r\n break;\r\n case \"producer\":\r\n self.edit_cell_type = CellTypes.producer;\r\n break;\r\n case \"mover\":\r\n self.edit_cell_type = CellTypes.mover;\r\n break;\r\n case \"killer\":\r\n self.edit_cell_type = CellTypes.killer;\r\n break;\r\n case \"armor\":\r\n self.edit_cell_type = CellTypes.armor;\r\n break;\r\n }\r\n $(\".cell-type\" ).css( \"border-color\", \"black\" );\r\n var selected = '#'+this.id+'.cell-type';\r\n $(selected).css(\"border-color\", \"yellow\");\r\n });\r\n }\r\n}\r\n\r\nmodule.exports = EditorController;\r\n\n\n//# sourceURL=webpack:///./src/Controllers/EditorController.js?"); + +/***/ }), + +/***/ "./src/Controllers/EnvironmentController.js": +/*!**************************************************!*\ + !*** ./src/Controllers/EnvironmentController.js ***! + \**************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const CanvasController = __webpack_require__(/*! ./CanvasController */ \"./src/Controllers/CanvasController.js\");\r\nconst Organism = __webpack_require__(/*! ../Organism/Organism */ \"./src/Organism/Organism.js\");\r\nconst Modes = __webpack_require__(/*! ./ControlModes */ \"./src/Controllers/ControlModes.js\");\r\nconst CellTypes = __webpack_require__(/*! ../Organism/Cell/CellTypes */ \"./src/Organism/Cell/CellTypes.js\");\r\nconst Neighbors = __webpack_require__(/*! ../Grid/Neighbors */ \"./src/Grid/Neighbors.js\");\r\nconst Cell = __webpack_require__(/*! ../Organism/Cell/Cell */ \"./src/Organism/Cell/Cell.js\");\r\n\r\nclass EnvironmentController extends CanvasController{\r\n constructor(env, canvas) {\r\n super(env, canvas);\r\n this.mode = Modes.Drag;\r\n this.org_to_clone = null;\r\n this.defineZoomControls();\r\n this.prev_x;\r\n this.prev_y;\r\n this.scale = 1;\r\n }\r\n\r\n defineZoomControls() {\r\n var scale = 1;\r\n var zoom_speed = 0.5;\r\n const el = document.querySelector('#env-canvas');\r\n el.onwheel = function zoom(event) {\r\n event.preventDefault();\r\n var sign = -1*Math.sign(event.deltaY);\r\n \r\n // Restrict scale\r\n scale = Math.max(0.5, scale+(sign*zoom_speed));\r\n \r\n // Apply scale transform\r\n el.style.transform = `scale(${scale})`;\r\n this.scale = scale;\r\n }.bind(this);\r\n }\r\n\r\n resetView() {\r\n $('#env-canvas').css('transform', 'scale(1)');\r\n $('#env-canvas').css('top', '0px');\r\n $('#env-canvas').css('left', '0px');\r\n this.scale = 1;\r\n }\r\n\r\n updateMouseLocation(offsetX, offsetY){\r\n this.prev_x = this.mouse_x;\r\n this.prev_y = this.mouse_y;\r\n super.updateMouseLocation(offsetX, offsetY);\r\n }\r\n\r\n mouseMove() {\r\n this.performModeAction();\r\n }\r\n\r\n mouseDown() {\r\n this.performModeAction();\r\n }\r\n\r\n performModeAction() {\r\n var mode = this.mode;\r\n var right_click = this.right_click;\r\n var left_click = this.left_click;\r\n if (mode != Modes.None && (right_click || left_click)) {\r\n var cell = this.cur_cell;\r\n if (cell == null){\r\n return;\r\n }\r\n switch(mode) {\r\n case Modes.FoodDrop:\r\n if (left_click){\r\n this.dropCellType(cell.col, cell.row, CellTypes.food, false);\r\n }\r\n else if (right_click){\r\n this.dropCellType(cell.col, cell.row, CellTypes.empty, false);\r\n }\r\n break;\r\n case Modes.WallDrop:\r\n if (left_click){\r\n this.dropCellType(cell.col, cell.row, CellTypes.wall, true);\r\n\r\n }\r\n else if (right_click){\r\n this.dropCellType(cell.col, cell.row, CellTypes.empty, false);\r\n }\r\n break;\r\n case Modes.ClickKill:\r\n this.killNearOrganisms();\r\n break;\r\n\r\n case Modes.Select:\r\n if (this.cur_org == null) {\r\n this.cur_org = this.findNearOrganism();\r\n }\r\n if (this.cur_org != null){\r\n this.control_panel.setEditorOrganism(this.cur_org);\r\n }\r\n break;\r\n\r\n case Modes.Clone:\r\n if (this.org_to_clone != null){\r\n var new_org = new Organism(this.mouse_c, this.mouse_r, this.env, this.org_to_clone);\r\n if (new_org.isClear(this.mouse_c, this.mouse_r)){\r\n this.env.addOrganism(new_org)\r\n }\r\n }\r\n break;\r\n case Modes.Drag:\r\n var cur_top = parseInt($('#env-canvas').css('top'), 10);\r\n var cur_left = parseInt($('#env-canvas').css('left'), 10);\r\n var new_top = (cur_top + (this.mouse_y - this.prev_y)*this.scale);\r\n var new_left = (cur_left + (this.mouse_x - this.prev_x)*this.scale);\r\n $('#env-canvas').css('top', new_top+'px');\r\n $('#env-canvas').css('left', new_left+'px');\r\n break;\r\n }\r\n }\r\n }\r\n\r\n dropCellType(col, row, type, killBlocking=false) {\r\n for (var loc of Neighbors.allSelf){\r\n var c=col + loc[0];\r\n var r=row + loc[1];\r\n var cell = this.env.grid_map.cellAt(c, r);\r\n if (cell == null)\r\n continue;\r\n if (killBlocking && cell.owner != null){\r\n cell.owner.die();\r\n }\r\n else if (cell.owner != null) {\r\n continue;\r\n }\r\n this.env.changeCell(c, r, type, null);\r\n }\r\n }\r\n\r\n findNearOrganism() {\r\n for (var loc of Neighbors.all){\r\n var c = this.cur_cell.col + loc[0];\r\n var r = this.cur_cell.row + loc[1];\r\n var cell = this.env.grid_map.cellAt(c, r);\r\n if (cell.owner != null)\r\n return cell.owner;\r\n }\r\n return null;\r\n }\r\n\r\n killNearOrganisms() {\r\n for (var loc of Neighbors.allSelf){\r\n var c = this.cur_cell.col + loc[0];\r\n var r = this.cur_cell.row + loc[1];\r\n var cell = this.env.grid_map.cellAt(c, r);\r\n if (cell.owner != null)\r\n cell.owner.die();\r\n }\r\n }\r\n\r\n\r\n}\r\n\r\nmodule.exports = EnvironmentController;\r\n\n\n//# sourceURL=webpack:///./src/Controllers/EnvironmentController.js?"); + +/***/ }), + +/***/ "./src/Engine.js": +/*!***********************!*\ + !*** ./src/Engine.js ***! + \***********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const Environment = __webpack_require__(/*! ./Environments/Environment */ \"./src/Environments/Environment.js\");\r\nconst ControlPanel = __webpack_require__(/*! ./Controllers/ControlPanel */ \"./src/Controllers/ControlPanel.js\");\r\nconst OrganismEditor = __webpack_require__(/*! ./Environments/OrganismEditor */ \"./src/Environments/OrganismEditor.js\");\r\n\r\nconst render_speed = 60;\r\n\r\nclass Engine{\r\n constructor(){\r\n this.fps = 60;\r\n this.env = new Environment(4);\r\n this.organism_editor = new OrganismEditor();\r\n this.controlpanel = new ControlPanel(this);\r\n this.env.OriginOfLife();\r\n this.last_update = Date.now();\r\n this.delta_time = 0;\r\n this.actual_fps = 0;\r\n this.running = false;\r\n }\r\n\r\n start(fps=60) {\r\n if (fps <= 0)\r\n fps = 1;\r\n if (fps > 300)\r\n fps = 300;\r\n this.fps = fps;\r\n this.game_loop = setInterval(function(){this.environmentUpdate();}.bind(this), 1000/fps);\r\n this.running = true;\r\n if (this.fps >= render_speed) {\r\n if (this.render_loop != null) {\r\n clearInterval(this.render_loop);\r\n this.render_loop = null;\r\n }\r\n }\r\n else\r\n this.setRenderLoop();\r\n }\r\n \r\n stop() {\r\n clearInterval(this.game_loop);\r\n this.running = false;\r\n this.setRenderLoop();\r\n }\r\n\r\n setRenderLoop() {\r\n if (this.render_loop == null) {\r\n this.render_loop = setInterval(function(){this.necessaryUpdate();}.bind(this), 1000/render_speed);\r\n }\r\n }\r\n\r\n\r\n environmentUpdate() {\r\n this.delta_time = Date.now() - this.last_update;\r\n this.last_update = Date.now();\r\n this.env.update(this.delta_time);\r\n this.actual_fps = 1/this.delta_time*1000;\r\n if(this.render_loop == null){\r\n this.necessaryUpdate();\r\n }\r\n \r\n }\r\n\r\n necessaryUpdate() {\r\n this.env.render();\r\n this.controlpanel.update();\r\n this.organism_editor.update();\r\n }\r\n\r\n}\r\n\r\nmodule.exports = Engine;\r\n\n\n//# sourceURL=webpack:///./src/Engine.js?"); + +/***/ }), + +/***/ "./src/Environments/Environment.js": +/*!*****************************************!*\ + !*** ./src/Environments/Environment.js ***! + \*****************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const Grid = __webpack_require__(/*! ../Grid/GridMap */ \"./src/Grid/GridMap.js\");\r\nconst Renderer = __webpack_require__(/*! ../Rendering/Renderer */ \"./src/Rendering/Renderer.js\");\r\nconst GridMap = __webpack_require__(/*! ../Grid/GridMap */ \"./src/Grid/GridMap.js\");\r\nconst Organism = __webpack_require__(/*! ../Organism/Organism */ \"./src/Organism/Organism.js\");\r\nconst CellTypes = __webpack_require__(/*! ../Organism/Cell/CellTypes */ \"./src/Organism/Cell/CellTypes.js\");\r\nconst Cell = __webpack_require__(/*! ../Organism/Cell/Cell */ \"./src/Organism/Cell/Cell.js\");\r\nconst EnvironmentController = __webpack_require__(/*! ../Controllers/EnvironmentController */ \"./src/Controllers/EnvironmentController.js\");\r\n\r\nclass Environment{\r\n constructor(cell_size) {\r\n this.renderer = new Renderer('env-canvas', 'env', cell_size);\r\n this.controller = new EnvironmentController(this, this.renderer.canvas);\r\n this.grid_rows = Math.floor(this.renderer.height / cell_size);\r\n this.grid_cols = Math.floor(this.renderer.width / cell_size);\r\n this.grid_map = new GridMap(this.grid_cols, this.grid_rows, cell_size);\r\n this.renderer.renderFullGrid(this.grid_map.grid);\r\n this.organisms = [];\r\n this.walls = [];\r\n this.total_mutability = 0;\r\n this.auto_reset = true;\r\n this.largest_cell_count = 0;\r\n this.reset_count = 0;\r\n }\r\n\r\n update(delta_time) {\r\n var to_remove = [];\r\n for (var i in this.organisms) {\r\n var org = this.organisms[i];\r\n if (!org.living || !org.update()) {\r\n to_remove.push(i);\r\n }\r\n }\r\n this.removeOrganisms(to_remove);\r\n }\r\n\r\n render() {\r\n this.renderer.renderCells();\r\n this.renderer.renderHighlights();\r\n }\r\n\r\n removeOrganisms(org_indeces) {\r\n for (var i of org_indeces.reverse()){\r\n this.total_mutability -= this.organisms[i].mutability;\r\n this.organisms.splice(i, 1);\r\n }\r\n if (this.organisms.length == 0 && this.auto_reset){\r\n this.reset_count++;\r\n this.reset();\r\n }\r\n }\r\n\r\n OriginOfLife() {\r\n var center = this.grid_map.getCenter();\r\n var org = new Organism(center[0], center[1], this);\r\n org.addCell(CellTypes.mouth, 0, 0);\r\n org.addCell(CellTypes.producer, -1, -1);\r\n org.addCell(CellTypes.producer, 1, 1);\r\n this.addOrganism(org);\r\n }\r\n\r\n addOrganism(organism) {\r\n organism.updateGrid();\r\n this.total_mutability += organism.mutability;\r\n this.organisms.push(organism);\r\n if (organism.cells.length > this.largest_cell_count) \r\n this.largest_cell_count = organism.cells.length;\r\n }\r\n\r\n averageMutability() {\r\n if (this.organisms.length < 1)\r\n return 0;\r\n return this.total_mutability / this.organisms.length;\r\n }\r\n\r\n changeCell(c, r, type, owner) {\r\n this.grid_map.setCellType(c, r, type);\r\n this.grid_map.setCellOwner(c, r, owner);\r\n this.renderer.addToRender(this.grid_map.cellAt(c, r));\r\n if(type == CellTypes.wall)\r\n this.walls.push(this.grid_map.cellAt(c, r));\r\n }\r\n\r\n clearWalls() {\r\n for(var wall of this.walls){\r\n if (this.grid_map.cellAt(wall.col, wall.row).type == CellTypes.wall)\r\n this.changeCell(wall.col, wall.row, CellTypes.empty, null);\r\n }\r\n }\r\n\r\n clearOrganisms() {\r\n for (var org of this.organisms)\r\n org.die();\r\n this.organisms = [];\r\n }\r\n\r\n reset(clear_walls=true) {\r\n this.organisms = [];\r\n this.grid_map.fillGrid(CellTypes.empty);\r\n this.renderer.renderFullGrid(this.grid_map.grid);\r\n this.total_mutability = 0;\r\n this.OriginOfLife();\r\n }\r\n\r\n resizeGridColRow(cell_size, cols, rows) {\r\n this.renderer.cell_size = cell_size;\r\n this.renderer.fillShape(rows*cell_size, cols*cell_size);\r\n this.grid_map.resize(cols, rows, cell_size);\r\n this.reset();\r\n }\r\n\r\n resizeFillWindow(cell_size) {\r\n this.renderer.cell_size = cell_size;\r\n this.renderer.fillWindow('env');\r\n var cols = Math.floor(this.renderer.width / cell_size);\r\n var rows = Math.floor(this.renderer.height / cell_size);\r\n this.grid_map.resize(cols, rows, cell_size);\r\n this.reset();\r\n }\r\n}\r\n\r\nmodule.exports = Environment;\r\n\r\n\n\n//# sourceURL=webpack:///./src/Environments/Environment.js?"); + +/***/ }), + +/***/ "./src/Environments/OrganismEditor.js": +/*!********************************************!*\ + !*** ./src/Environments/OrganismEditor.js ***! + \********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const Organism = __webpack_require__(/*! ../Organism/Organism */ \"./src/Organism/Organism.js\");\r\nconst GridMap = __webpack_require__(/*! ../Grid/GridMap */ \"./src/Grid/GridMap.js\");\r\nconst Renderer = __webpack_require__(/*! ../Rendering/Renderer */ \"./src/Rendering/Renderer.js\");\r\nconst CellTypes = __webpack_require__(/*! ../Organism/Cell/CellTypes */ \"./src/Organism/Cell/CellTypes.js\");\r\nconst EditorController = __webpack_require__(/*! ../Controllers/EditorController */ \"./src/Controllers/EditorController.js\");\r\nconst Cell = __webpack_require__(/*! ../Organism/Cell/Cell */ \"./src/Organism/Cell/Cell.js\");\r\n\r\nclass OrganismEditor {\r\n constructor() {\r\n this.is_active = true;\r\n var cell_size = 13;\r\n this.grid_map = new GridMap(15, 15, cell_size);\r\n this.renderer = new Renderer('editor-canvas', 'editor-env', cell_size);\r\n this.controller = new EditorController(this, this.renderer.canvas);\r\n this.clear();\r\n\r\n this.renderer.renderFullGrid(this.grid_map.grid);\r\n }\r\n\r\n update() {\r\n if (this.is_active){\r\n this.renderer.renderHighlights();\r\n }\r\n }\r\n\r\n changeCell(c, r, type, owner) {\r\n this.grid_map.setCellType(c, r, type);\r\n this.grid_map.setCellOwner(c, r, owner);\r\n this.renderer.renderFullGrid(this.grid_map.grid);\r\n }\r\n\r\n // absolute c r, not local\r\n addCellToOrg(c, r, type) {\r\n var center = this.grid_map.getCenter();\r\n var loc_c = c - center[0];\r\n var loc_r = r - center[1];\r\n var prev_cell = this.organism.getLocalCell(loc_c, loc_r)\r\n if (prev_cell != null) {\r\n prev_cell.type = type;\r\n this.changeCell(c, r, type, this.organism);\r\n }\r\n else if (this.organism.addCell(type, loc_c, loc_r)){\r\n this.changeCell(c, r, type, this.organism);\r\n }\r\n }\r\n\r\n removeCellFromOrg(c, r) {\r\n var center = this.grid_map.getCenter();\r\n var loc_c = c - center[0];\r\n var loc_r = r - center[1];\r\n if (loc_c == 0 && loc_r == 0){\r\n alert(\"Cannot remove center cell\");\r\n return;\r\n }\r\n var prev_cell = this.organism.getLocalCell(loc_c, loc_r)\r\n if (prev_cell != null) {\r\n if (this.organism.removeCell(loc_c, loc_r)) {\r\n this.changeCell(c, r, CellTypes.empty, null);\r\n }\r\n }\r\n }\r\n\r\n setOrganismToCopyOf(orig_org){\r\n this.grid_map.fillGrid(CellTypes.empty);\r\n var center = this.grid_map.getCenter();\r\n this.organism = new Organism(center[0], center[1], this, orig_org);\r\n this.organism.updateGrid();\r\n }\r\n\r\n getCopyOfOrg() {\r\n var new_org = new Organism(0, 0, null, this.organism);\r\n return new_org;\r\n }\r\n\r\n clear() {\r\n this.grid_map.fillGrid(CellTypes.empty);\r\n var center = this.grid_map.getCenter();\r\n this.organism = new Organism(center[0], center[1], this, null);\r\n this.organism.addCell(CellTypes.mouth, 0, 0);\r\n this.organism.updateGrid();\r\n }\r\n}\r\n\r\nmodule.exports = OrganismEditor;\n\n//# sourceURL=webpack:///./src/Environments/OrganismEditor.js?"); + +/***/ }), + +/***/ "./src/Grid/GridMap.js": +/*!*****************************!*\ + !*** ./src/Grid/GridMap.js ***! + \*****************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const Cell = __webpack_require__(/*! ../Organism/Cell/Cell */ \"./src/Organism/Cell/Cell.js\");\r\nconst CellTypes = __webpack_require__(/*! ../Organism/Cell/CellTypes */ \"./src/Organism/Cell/CellTypes.js\");\r\n\r\nclass GridMap {\r\n constructor(cols, rows, cell_size) {\r\n this.resize(cols, rows, cell_size);\r\n }\r\n\r\n resize(cols, rows, cell_size) {\r\n this.grid = [];\r\n this.cols = cols;\r\n this.rows = rows;\r\n this.cell_size = cell_size;\r\n for(var c=0; c=0 && row>=0;\r\n }\r\n\r\n getCenter(){\r\n return [Math.floor(this.cols/2), Math.floor(this.rows/2)]\r\n }\r\n\r\n xyToColRow(x, y) {\r\n var c = Math.floor(x/this.cell_size);\r\n var r = Math.floor(y/this.cell_size);\r\n if (c >= this.cols)\r\n c = this.cols-1;\r\n else if (c < 0)\r\n c = 0;\r\n if (r >= this.rows)\r\n r = this.rows-1;\r\n else if (r < 0)\r\n r = 0;\r\n return [c, r];\r\n }\r\n}\r\n\r\nmodule.exports = GridMap;\r\n\n\n//# sourceURL=webpack:///./src/Grid/GridMap.js?"); + +/***/ }), + +/***/ "./src/Grid/Neighbors.js": +/*!*******************************!*\ + !*** ./src/Grid/Neighbors.js ***! + \*******************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("// contains local cell values for the following:\r\n\r\n//all ...\r\n// .x.\r\n// ...\r\n\r\n//adjacent .\r\n// .x.\r\n// .\r\n\r\n//corners . .\r\n// x\r\n// . .\r\n\r\n//allSelf ...\r\n// ...\r\n// ...\r\n\r\nconst Neighbors = {\r\n all: [[0, 1],[0, -1],[1, 0],[-1, 0],[-1, -1],[1, 1],[-1, 1],[1, -1]],\r\n adjacent: [[0, 1],[0, -1],[1, 0],[-1, 0]],\r\n corners: [[-1, -1],[1, 1],[-1, 1],[1, -1]],\r\n allSelf: [[0, 0],[0, 1],[0, -1],[1, 0],[-1, 0],[-1, -1],[1, 1],[-1, 1],[1, -1]]\r\n}\r\n\r\nmodule.exports = Neighbors;\n\n//# sourceURL=webpack:///./src/Grid/Neighbors.js?"); + +/***/ }), + +/***/ "./src/Hyperparameters.js": +/*!********************************!*\ + !*** ./src/Hyperparameters.js ***! + \********************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const Neighbors = __webpack_require__(/*! ./Grid/Neighbors */ \"./src/Grid/Neighbors.js\");\r\n\r\nconst Hyperparams = {\r\n setDefaults: function() {\r\n this.lifespanMultiplier= 100;\r\n this.foodProdProb= 4;\r\n this.foodProdProbScalar= 4;\r\n this.killableNeighbors= Neighbors.adjacent;\r\n this.edibleNeighbors= Neighbors.adjacent;\r\n this.growableNeighbors= Neighbors.adjacent;\r\n\r\n this.useGlobalMutability= false;\r\n this.globalMutability= 5;\r\n this.addProb= 33;\r\n this.changeProb= 33;\r\n this.removeProb= 33;\r\n \r\n this.moversCanRotate= true;\r\n this.offspringRotate= true;\r\n\r\n this.foodBlocksReproduction= true;\r\n this.moversCanProduce= false;\r\n\r\n this.instaKill= false;\r\n },\r\n\r\n // calculates the optimal ratio where a producer cell is most likely to produce 1 food in its lifespan * a scalar of my choice :)\r\n calcProducerFoodRatio : function(lifespan_fixed=true) {\r\n if (lifespan_fixed) {\r\n // change the foodProdProb\r\n this.foodProdProb = (100 / this.lifespanMultiplier) * this.foodProdProbScalar;\r\n }\r\n else {\r\n // change the lifespanMultiplier\r\n this.lifespanMultiplier = Math.floor(100 / (this.foodProdProb/this.foodProdProbScalar));\r\n }\r\n },\r\n\r\n balanceMutationProbs : function(choice) {\r\n if (choice == 1) {\r\n var remaining = 100 - this.addProb;\r\n this.changeProb = remaining/2;\r\n this.removeProb = remaining/2;\r\n }\r\n else if (choice == 2) {\r\n var remaining = 100 - this.changeProb;\r\n this.addProb = remaining/2;\r\n this.removeProb = remaining/2;\r\n }\r\n else {\r\n var remaining = 100 - this.removeProb;\r\n this.changeProb = remaining/2;\r\n this.addProb = remaining/2;\r\n }\r\n }\r\n}\r\n\r\nHyperparams.setDefaults();\r\n\r\nmodule.exports = Hyperparams;\n\n//# sourceURL=webpack:///./src/Hyperparameters.js?"); + +/***/ }), + +/***/ "./src/Organism/Cell/Cell.js": +/*!***********************************!*\ + !*** ./src/Organism/Cell/Cell.js ***! + \***********************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const CellTypes = __webpack_require__(/*! ./CellTypes */ \"./src/Organism/Cell/CellTypes.js\");\r\nconst Hyperparams = __webpack_require__(/*! ../../Hyperparameters */ \"./src/Hyperparameters.js\");\r\n\r\n// A cell exists in a grid system.\r\nclass Cell{\r\n constructor(type, col, row, x, y){\r\n this.owner = null;\r\n this.setType(type);\r\n this.col = col;\r\n this.row = row;\r\n this.x = x;\r\n this.y = y;\r\n }\r\n\r\n setType(type) {\r\n this.type = type;\r\n }\r\n\r\n performFunction(env) {\r\n switch(this.type){\r\n case CellTypes.mouth:\r\n eatFood(this, env);\r\n break;\r\n case CellTypes.producer:\r\n growFood(this, env);\r\n break;\r\n case CellTypes.killer:\r\n killNeighbors(this, env);\r\n break;\r\n }\r\n }\r\n\r\n getColor() {\r\n return CellTypes.colors[this.type];\r\n }\r\n\r\n isLiving() {\r\n return this.type != CellTypes.empty && \r\n this.type != CellTypes.food && \r\n this.type != CellTypes.wall;\r\n }\r\n}\r\n\r\nfunction eatFood(self, env){\r\n for (var loc of Hyperparams.edibleNeighbors){\r\n var cell = env.grid_map.cellAt(self.col+loc[0], self.row+loc[1]);\r\n eatNeighborFood(self, cell, env);\r\n }\r\n}\r\n\r\nfunction eatNeighborFood(self, n_cell, env){\r\n if (n_cell == null)\r\n return;\r\n if (n_cell.type == CellTypes.food){\r\n env.changeCell(n_cell.col, n_cell.row, CellTypes.empty, null);\r\n self.owner.food_collected++;\r\n }\r\n}\r\n\r\nfunction growFood(self, env){\r\n if (self.owner.is_mover && !Hyperparams.moversCanProduce)\r\n return;\r\n var prob = Hyperparams.foodProdProb;\r\n if (Math.random() * 100 <= prob){\r\n var loc = Hyperparams.growableNeighbors[Math.floor(Math.random() * Hyperparams.growableNeighbors.length)]\r\n var c=loc[0];\r\n var r=loc[1];\r\n var cell = env.grid_map.cellAt(self.col+c, self.row+r);\r\n if (cell != null && cell.type == CellTypes.empty){\r\n env.changeCell(self.col+c, self.row+r, CellTypes.food, null);\r\n return;\r\n }\r\n }\r\n}\r\n\r\nfunction killNeighbors(self, env) {\r\n for (var loc of Hyperparams.killableNeighbors){\r\n var cell = env.grid_map.cellAt(self.col+loc[0], self.row+loc[1]);\r\n killNeighbor(self, cell);\r\n }\r\n}\r\n\r\nfunction killNeighbor(self, n_cell) {\r\n 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) \r\n return;\r\n var is_hit = n_cell.type == CellTypes.killer; // has to be calculated before death\r\n n_cell.owner.harm();\r\n if (is_hit){\r\n self.owner.harm();\r\n }\r\n}\r\n\r\nmodule.exports = Cell;\r\n\n\n//# sourceURL=webpack:///./src/Organism/Cell/Cell.js?"); + +/***/ }), + +/***/ "./src/Organism/Cell/CellTypes.js": +/*!****************************************!*\ + !*** ./src/Organism/Cell/CellTypes.js ***! + \****************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("const CellTypes = {\r\n empty: 0,\r\n food: 1,\r\n wall: 2,\r\n mouth: 3,\r\n producer: 4,\r\n mover: 5,\r\n killer: 6,\r\n armor: 7,\r\n colors: ['#121D29', 'green', 'gray', 'orange', 'white', '#3493eb', 'red', 'purple'],\r\n getRandomLivingType: function() {\r\n return Math.floor(Math.random() * 5) + 3;\r\n }\r\n}\r\n\r\nmodule.exports = CellTypes;\r\n\n\n//# sourceURL=webpack:///./src/Organism/Cell/CellTypes.js?"); + +/***/ }), + +/***/ "./src/Organism/Cell/LocalCell.js": +/*!****************************************!*\ + !*** ./src/Organism/Cell/LocalCell.js ***! + \****************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const CellTypes = __webpack_require__(/*! ./CellTypes */ \"./src/Organism/Cell/CellTypes.js\");\r\nconst Directions = __webpack_require__(/*! ../Directions */ \"./src/Organism/Directions.js\");\r\nconst Hyperparams = __webpack_require__(/*! ../../Hyperparameters */ \"./src/Hyperparameters.js\");\r\n\r\n// A local cell is a lightweight container for a cell in an organism. It does not directly exist in the grid \r\nclass LocalCell{\r\n constructor(type, loc_col, loc_row){\r\n this.type = type;\r\n this.loc_col = loc_col;\r\n this.loc_row = loc_row;\r\n }\r\n\r\n rotatedCol(dir){\r\n switch(dir){\r\n case Directions.up:\r\n return this.loc_col;\r\n case Directions.down:\r\n return this.loc_col * -1;\r\n case Directions.left:\r\n return this.loc_row;\r\n case Directions.right:\r\n return this.loc_row * -1;\r\n }\r\n }\r\n\r\n rotatedRow(dir){\r\n switch(dir){\r\n case Directions.up:\r\n return this.loc_row;\r\n case Directions.down:\r\n return this.loc_row * -1;\r\n case Directions.left:\r\n return this.loc_col * -1;\r\n case Directions.right:\r\n return this.loc_col;\r\n }\r\n }\r\n}\r\n\r\nmodule.exports = LocalCell;\r\n\n\n//# sourceURL=webpack:///./src/Organism/Cell/LocalCell.js?"); + +/***/ }), + +/***/ "./src/Organism/Directions.js": +/*!************************************!*\ + !*** ./src/Organism/Directions.js ***! + \************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("const Directions = {\r\n up:0,\r\n down:1,\r\n left:2,\r\n right:3,\r\n scalars:[[0,-1],[0,1],[-1,0],[1,0]],\r\n getRandomDirection: function() {\r\n return Math.floor(Math.random() * 4);\r\n },\r\n getRandomScalar: function() {\r\n return this.scalars[Math.floor(Math.random() * this.scalars.length)];\r\n }\r\n}\r\n\r\nmodule.exports = Directions;\n\n//# sourceURL=webpack:///./src/Organism/Directions.js?"); + +/***/ }), + +/***/ "./src/Organism/Organism.js": +/*!**********************************!*\ + !*** ./src/Organism/Organism.js ***! + \**********************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("const CellTypes = __webpack_require__(/*! ./Cell/CellTypes */ \"./src/Organism/Cell/CellTypes.js\");\r\nconst Cell = __webpack_require__(/*! ./Cell/Cell */ \"./src/Organism/Cell/Cell.js\");\r\nconst GridMap = __webpack_require__(/*! ../Grid/GridMap */ \"./src/Grid/GridMap.js\");\r\nconst LocalCell = __webpack_require__(/*! ./Cell/LocalCell */ \"./src/Organism/Cell/LocalCell.js\");\r\nconst Neighbors = __webpack_require__(/*! ../Grid/Neighbors */ \"./src/Grid/Neighbors.js\");\r\nconst Hyperparams = __webpack_require__(/*! ../Hyperparameters */ \"./src/Hyperparameters.js\");\r\nconst Directions = __webpack_require__(/*! ./Directions */ \"./src/Organism/Directions.js\");\r\n\r\nconst directions = [[0,1],[0,-1],[1,0],[-1,0]]\r\n\r\nclass Organism {\r\n constructor(col, row, env, parent=null) {\r\n this.c = col;\r\n this.r = row;\r\n this.env = env;\r\n this.lifetime = 0;\r\n this.food_collected = 0;\r\n this.living = true;\r\n this.cells = [];\r\n this.is_producer = false;\r\n this.is_mover = false;\r\n this.direction = Directions.up;\r\n this.rotation = Directions.up;\r\n this.can_rotate = Hyperparams.moversCanRotate;\r\n this.move_count = 0;\r\n this.move_range = 4;\r\n this.mutability = 5;\r\n this.damage = 0;\r\n if (parent != null) {\r\n this.inherit(parent);\r\n }\r\n }\r\n\r\n addCell(type, c, r) {\r\n for (var cell of this.cells) {\r\n if (cell.loc_col == c && cell.loc_row == r){\r\n return false;\r\n }\r\n }\r\n\r\n this.checkProducerMover(type);\r\n this.cells.push(new LocalCell(type, c, r));\r\n return true;\r\n }\r\n\r\n removeCell(c, r) {\r\n if (c == 0 && r == 0)\r\n return false;\r\n var check_change = false;\r\n for (var i=0; i 1) {\r\n cell = this.cells[Math.floor(Math.random() * this.cells.length)];\r\n mutated = this.removeCell(cell.loc_col, cell.loc_row);\r\n }\r\n }\r\n\r\n if (this.is_mover) {\r\n this.move_range += Math.floor(Math.random() * 4) - 2;\r\n if (this.move_range <= 0){\r\n this.move_range = 1;\r\n }\r\n }\r\n return mutated;\r\n }\r\n\r\n attemptMove() {\r\n var direction = Directions.scalars[this.direction];\r\n var direction_c = direction[0];\r\n var direction_r = direction[1];\r\n var new_c = this.c + direction_c;\r\n var new_r = this.r + direction_r;\r\n if (this.isClear(new_c, new_r)) {\r\n for (var cell of this.cells) {\r\n var real_c = this.c + cell.rotatedCol(this.rotation);\r\n var real_r = this.r + cell.rotatedRow(this.rotation);\r\n this.env.changeCell(real_c, real_r, CellTypes.empty, null);\r\n }\r\n this.c = new_c;\r\n this.r = new_r;\r\n this.updateGrid();\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n attemptRotate() {\r\n if(!this.can_rotate){\r\n this.direction = Directions.getRandomDirection();\r\n this.move_count = 0;\r\n return true;\r\n }\r\n var new_rotation = Directions.getRandomDirection();\r\n if(this.isClear(this.c, this.r, new_rotation)){\r\n for (var cell of this.cells) {\r\n var real_c = this.c + cell.rotatedCol(this.rotation);\r\n var real_r = this.r + cell.rotatedRow(this.rotation);\r\n this.env.changeCell(real_c, real_r, CellTypes.empty, null);\r\n }\r\n this.rotation = new_rotation;\r\n this.direction = Directions.getRandomDirection();\r\n this.updateGrid();\r\n this.move_count = 0;\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n // assumes either c1==c2 or r1==r2, returns true if there is a clear path from point a to b\r\n isStraightPath(c1, r1, c2, r2, parent){\r\n if (c1 == c2) {\r\n if (r1 > r2){\r\n var temp = r2;\r\n r2 = r1;\r\n r1 = temp;\r\n }\r\n for (var i=r1; i!=r2; i++) {\r\n var cell = this.env.grid_map.cellAt(c1, i)\r\n if (!this.isPassableCell(cell, parent)){\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n else {\r\n if (c1 > c2){\r\n var temp = c2;\r\n c2 = c1;\r\n c1 = temp;\r\n }\r\n for (var i=c1; i!=c2; i++) {\r\n var cell = this.env.grid_map.cellAt(i, r1);\r\n if (!this.isPassableCell(cell, parent)){\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n }\r\n\r\n isPassableCell(cell, parent){\r\n return cell != null && (cell.type == CellTypes.empty || cell.owner == this || cell.owner == parent || cell.type == CellTypes.food);\r\n }\r\n\r\n isClear(col, row, rotation=this.rotation) {\r\n for(var loccell of this.cells) {\r\n var cell = this.getRealCell(loccell, col, row, rotation);\r\n if(cell==null) {\r\n return false;\r\n }\r\n if (cell.owner==this || cell.type==CellTypes.empty || (!Hyperparams.foodBlocksReproduction && cell.type==CellTypes.food)){\r\n continue;\r\n }\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n harm() {\r\n this.damage++;\r\n if (this.damage >= this.maxHealth() || Hyperparams.instaKill) {\r\n this.die();\r\n }\r\n }\r\n\r\n die() {\r\n for (var cell of this.cells) {\r\n var real_c = this.c + cell.rotatedCol(this.rotation);\r\n var real_r = this.r + cell.rotatedRow(this.rotation);\r\n this.env.changeCell(real_c, real_r, CellTypes.food, null);\r\n }\r\n this.living = false;\r\n }\r\n\r\n updateGrid() {\r\n for (var cell of this.cells) {\r\n var real_c = this.c + cell.rotatedCol(this.rotation);\r\n var real_r = this.r + cell.rotatedRow(this.rotation);\r\n this.env.changeCell(real_c, real_r, cell.type, this);\r\n }\r\n }\r\n\r\n update() {\r\n this.lifetime++;\r\n if (this.lifetime > this.lifespan()) {\r\n this.die();\r\n return this.living;\r\n }\r\n if (this.food_collected >= this.foodNeeded()) {\r\n this.reproduce();\r\n }\r\n for (var cell of this.cells) {\r\n this.getRealCell(cell).performFunction(this.env);\r\n }\r\n if (!this.living){\r\n return this.living\r\n }\r\n if (this.is_mover) {\r\n this.move_count++;\r\n var moved = this.attemptMove();\r\n if (this.move_count > this.move_range){\r\n this.attemptRotate();\r\n }\r\n }\r\n\r\n return this.living;\r\n }\r\n\r\n getRealCell(local_cell, c=this.c, r=this.r, rotation=this.rotation){\r\n var real_c = c + local_cell.rotatedCol(rotation);\r\n var real_r = r + local_cell.rotatedRow(rotation);\r\n return this.env.grid_map.cellAt(real_c, real_r);\r\n }\r\n\r\n}\r\n\r\nmodule.exports = Organism;\r\n\n\n//# sourceURL=webpack:///./src/Organism/Organism.js?"); + +/***/ }), + +/***/ "./src/Rendering/Renderer.js": +/*!***********************************!*\ + !*** ./src/Rendering/Renderer.js ***! + \***********************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("\r\n// Renderer controls access to a canvas. There is one renderer for each canvas\r\nclass Renderer {\r\n constructor(canvas_id, container_id, cell_size) {\r\n this.cell_size = cell_size;\r\n this.canvas = document.getElementById(canvas_id);\r\n this.ctx = this.canvas.getContext(\"2d\");\r\n this.fillWindow(container_id)\r\n\t\tthis.height = this.canvas.height;\r\n this.width = this.canvas.width;\r\n this.cells_to_render = new Set();\r\n this.cells_to_highlight = new Set();\r\n this.highlighted_cells = new Set();\r\n }\r\n\r\n fillWindow(container_id) {\r\n this.fillShape($('#'+container_id).height(), $('#'+container_id).width());\r\n }\r\n\r\n fillShape(height, width) {\r\n this.canvas.width = width;\r\n this.canvas.height = height;\r\n this.height = this.canvas.height;\r\n this.width = this.canvas.width;\r\n }\r\n\r\n clear() {\r\n this.ctx.fillStyle = 'white';\r\n this.ctx.fillRect(0, 0, this.height, this.width);\r\n }\r\n\r\n renderFullGrid(grid) {\r\n for (var col of grid) {\r\n for (var cell of col){\r\n this.ctx.fillStyle = cell.getColor();\r\n this.ctx.fillRect(cell.x, cell.y, this.cell_size, this.cell_size);\r\n }\r\n }\r\n }\r\n\r\n renderCells() {\r\n for (var cell of this.cells_to_render) {\r\n this.renderCell(cell);\r\n }\r\n this.cells_to_render.clear();\r\n }\r\n\r\n renderCell(cell) {\r\n this.ctx.fillStyle = cell.getColor();\r\n this.ctx.fillRect(cell.x, cell.y, this.cell_size, this.cell_size);\r\n }\r\n\r\n renderOrganism(org) {\r\n for(var org_cell of org.cells) {\r\n var cell = org.getRealCell(org_cell);\r\n this.renderCell(cell);\r\n }\r\n }\r\n\r\n addToRender(cell) {\r\n if (this.highlighted_cells.has(cell)){\r\n this.cells_to_highlight.add(cell);\r\n }\r\n this.cells_to_render.add(cell);\r\n }\r\n\r\n renderHighlights() {\r\n for (var cell of this.cells_to_highlight) {\r\n this.renderCellHighlight(cell);\r\n this.highlighted_cells.add(cell);\r\n }\r\n this.cells_to_highlight.clear();\r\n \r\n }\r\n\r\n highlightOrganism(org) {\r\n for(var org_cell of org.cells) {\r\n var cell = org.getRealCell(org_cell);\r\n this.cells_to_highlight.add(cell);\r\n }\r\n }\r\n\r\n highlightCell(cell) {\r\n this.cells_to_highlight.add(cell);\r\n }\r\n\r\n renderCellHighlight(cell, color=\"yellow\") {\r\n this.renderCell(cell);\r\n this.ctx.fillStyle = color;\r\n this.ctx.globalAlpha = 0.5;\r\n this.ctx.fillRect(cell.x, cell.y, this.cell_size, this.cell_size);\r\n this.ctx.globalAlpha = 1;\r\n this.highlighted_cells.add(cell);\r\n }\r\n\r\n clearAllHighlights(clear_to_highlight=false) {\r\n for (var cell of this.highlighted_cells) {\r\n this.renderCell(cell);\r\n }\r\n this.highlighted_cells.clear();\r\n if (clear_to_highlight) {\r\n this.cells_to_highlight.clear();\r\n }\r\n }\r\n}\r\n\r\n// $(\"body\").mousemove(function(e) {\r\n// console.log(\"hello\");\r\n// });\r\n\r\nmodule.exports = Renderer;\r\n\n\n//# sourceURL=webpack:///./src/Rendering/Renderer.js?"); + +/***/ }), + +/***/ "./src/index.js": +/*!**********************!*\ + !*** ./src/index.js ***! + \**********************/ +/*! no exports provided */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _Engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Engine */ \"./src/Engine.js\");\n/* harmony import */ var _Engine__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_Engine__WEBPACK_IMPORTED_MODULE_0__);\n\r\n\r\n\r\n\r\n$('document').ready(function(){\r\n let isMobile = window.matchMedia(\"only screen and (max-width: 760px)\").matches;\r\n\r\n console.log(isMobile)\r\n if (isMobile) {\r\n alert(\"Though the simulation still works on mobile, most features are disabled. Try it on desktop for the full experience!\");\r\n $('.control-panel').css('display', 'none');\r\n }\r\n var engine = new _Engine__WEBPACK_IMPORTED_MODULE_0___default.a();\r\n engine.start(60);\r\n});\r\n\n\n//# sourceURL=webpack:///./src/index.js?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/src/index.js b/src/index.js index ec13089..6081402 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,13 @@ import Engine from './Engine'; $('document').ready(function(){ + let isMobile = window.matchMedia("only screen and (max-width: 760px)").matches; + + console.log(isMobile) + if (isMobile) { + 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'); + } var engine = new Engine(); engine.start(60); });