diff --git a/dist/css/style.css b/dist/css/style.css index 76f3252..999f1a9 100644 --- a/dist/css/style.css +++ b/dist/css/style.css @@ -20,9 +20,9 @@ body{ text-align: center; transform: scale(1); image-rendering: -moz-crisp-edges; - image-rendering: -webkit-crisp-edges; - image-rendering: pixelated; - image-rendering: crisp-edges; + image-rendering: -webkit-crisp-edges; + image-rendering: pixelated; + image-rendering: crisp-edges; } #env-canvas { @@ -91,9 +91,14 @@ button:hover{ grid-column: 1; } -#view-controls { +.vertical-buttons { float:right; - padding: 10px; + display: grid; + grid-template-rows: 2; + grid-template-columns: 1; +} +.editor-buttons { + display: block; } .col-row-input { @@ -154,6 +159,9 @@ button:hover{ width: 30px; height: 30px; } +.edit-mode-btn:hover{ + background-color: #81d2c7; +} .edit-mode-btn#drag-view { background-color: #81d2c7; } @@ -213,6 +221,9 @@ button:hover{ #armor{ background-color: purple; } +#eye{ + background-color: #d4bb3f; +} #food{ background-color: green; } diff --git a/dist/index.html b/dist/index.html index 52789ed..6f46b7c 100644 --- a/dist/index.html +++ b/dist/index.html @@ -17,9 +17,13 @@
-
+
+ + + +

Simulation Speed

@@ -89,21 +93,12 @@
-
-

Editor

- - - - - -

- - -
-
- - - +
+
+ + + +
@@ -113,8 +108,12 @@
+
+ +
+

1 cell

@@ -136,22 +135,21 @@
- - -

Organism Rotation



-

Killer Cell Effects

+
+ +
-

+

Mutation Rate


@@ -171,7 +169,7 @@
- +
diff --git a/dist/js/bundle.js b/dist/js/bundle.js index 77eac25..14b0244 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){const i={empty:0,food:1,wall:2,mouth:3,producer:4,mover:5,killer:6,armor:7,eye:8,colors:["#121D29","green","gray","orange","white","#3493EB","red","purple","#8D73A3"],getRandomLivingType:function(){return Math.floor(6*Math.random())+3}};e.exports=i},function(e,t,i){const s=i(5),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=5},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,i){const s=i(0),r=i(1);function o(e,t){for(var i of r.edibleNeighbors){l(e,t.grid_map.cellAt(e.col+i[0],e.row+i[1]),t)}}function l(e,t,i){null!=t&&t.type==s.food&&(i.changeCell(t.col,t.row,s.empty,null),e.owner.food_collected++)}function n(e,t){if(!e.owner.is_mover||r.moversCanProduce){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)return void t.changeCell(e.col+l,e.row+n,s.food,null)}}}function a(e,t){for(var i of r.killableNeighbors){h(e,t.grid_map.cellAt(e.col+i[0],e.row+i[1]))}}function h(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,this.func=null}setType(e){switch(this.type=e,this.type){case s.mouth:this.func=o;break;case s.producer:this.func=n;break;case s.killer:this.func=a;break;default:this.func=null}}performFunction(e){null!=this.func&&this.func(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){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}}};e.exports=i},function(e,t,i){const s=i(2),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){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(2),i(4),i(15)),o=i(5),l=i(1),n=i(3),a=i(10),h=i(17);class c{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.down,this.rotation=n.up,this.can_rotate=l.moversCanRotate,this.move_count=0,this.move_range=4,this.mutability=5,this.damage=0,this.birth_distance=4,this.brain=new h(this),null!=s&&this.inherit(s)}addCell(e,t,i,s=null){for(var o of this.cells)if(o.loc_col==t&&o.loc_row==i)return!1;return this.checkProducerMover(e),this.cells.push(new r(e,t,i,s)),!0}removeCell(e,t){if(0==e&&0==t)return!1;for(var i=!1,r=0;r1){var d=this.cells[Math.floor(Math.random()*this.cells.length)];t=this.removeCell(d.loc_col,d.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)),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),e.type==s.eye&&(this.getRealCell(e).direction=e.eye.getAbsoluteDirection(this.rotation))}}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.type==s.eye){var t=e.eye.look(this.getRealCol(e),this.getRealRow(e),this.rotation,this.env);this.brain.observe(t)}else if(this.getRealCell(e).performFunction(this.env),!this.living)return this.living;if(this.is_mover){this.move_count++;var i=this.brain.decide(),r=this.attemptMove();(this.move_count>this.move_range&&!i||!r)&&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)}getRealCol(e){return this.c+e.rotatedCol(this.rotation)}getRealRow(e){return this.r+e.rotatedRow(this.rotation)}}e.exports=c},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){const s=i(0);i(3);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),e.type==s.eye&&this.renderEyeCell(e)}renderEyeCell(e){if(1!=this.cell_size){if(this.cell_size%2==0)var t=2;else t=1;Math.floor(this.cell_size/2);var i=this.cell_size/2,s=this.cell_size/3;e.x,Math.floor(t/2),e.y;this.ctx.translate(e.x+i,e.y+i),this.ctx.rotate(90*e.direction*Math.PI/180),this.ctx.fillStyle="#FFFC5E",this.ctx.fillRect(-i,-i,this.cell_size,s),this.ctx.setTransform(1,0,0,1,0,0)}}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(3),r=i(1),o=i(0),l=i(16);e.exports=class{constructor(e,t=-1){this.direction=t,-1==t&&(this.direction=s.getRandomDirection()),this.loc_cell=e}getAbsoluteDirection(e){var t=e+this.direction;return t>3&&(t-=4),t}look(e,t,i,n){var a=this.getAbsoluteDirection(i),h=0,c=0;switch(a){case s.up:c=-1;break;case s.down:c=1;break;case s.right:h=1;break;case s.left:h=-1}for(var d=e,u=t,g=null,p=0;p{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(19),o=i(20);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(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(8),r=(i(4),i(9)),o=i(4),l=i(6),n=i(0),a=(i(2),i(18));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 l(e[0],e[1],this);t.addCell(n.mouth,0,0),t.addCell(n.producer,-1,-1),t.addCell(n.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==n.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==n.wall&&this.changeCell(e.col,e.row,n.empty,null)}clearOrganisms(){for(var e of this.organisms)e.die();this.organisms=[]}reset(e=!0){this.organisms=[],this.grid_map.fillGrid(n.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(0),r=i(3),o=(i(1),i(10));e.exports=class{constructor(e,t,i,r=null){this.type=e,this.loc_col=t,this.loc_row=i,this.type==s.eye&&(this.eye=new o(this),null!=r&&(this.eye.direction=r.direction))}rotatedCol(e){switch(e){case r.up:return this.loc_col;case r.down:return-1*this.loc_col;case r.left:return this.loc_row;case r.right:return-1*this.loc_row}}rotatedRow(e){switch(e){case r.up:return this.loc_row;case r.down:return-1*this.loc_row;case r.left:return-1*this.loc_col;case r.right:return this.loc_col}}}},function(e,t){e.exports=class{constructor(e,t,i){this.cell=e,this.distance=t,this.direction=i}}},function(e,t,i){i(0);const s=i(1),r=i(3),o=0,l=1,n=2;e.exports=class{constructor(e){this.owner=e,this.observations=[],this.decisions=[o,n,o,o,o,o,l,o,o]}observe(e){this.observations.push(e)}decide(){var e=o,t=s.lookRange+1,i=0;for(var a of this.observations)null!=a.cell&&a.cell.owner!=this.owner&&a.distancethis.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(8),r=i(6),o=i(4),l=i(9),n=i(0),a=i(21);i(2);e.exports=class extends s{constructor(){super(),this.is_active=!0;this.renderer=new l("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.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,n.empty,null):alert("Cannot remove center cell")}setOrganismToCopyOf(e){this.grid_map.fillGrid(n.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(n.empty);var e=this.grid_map.getCenter();this.organism=new r(e[0],e[1],this,null),this.organism.addCell(n.mouth,0,0),this.organism.updateGrid()}}},function(e,t,i){const s=i(11),r=i(7),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(),this.defineEditorOptions()}mouseMove(){(this.right_click||this.left_click)&&this.editOrganism()}mouseDown(){this.editOrganism()}mouseUp(){}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))}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}$(".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){const i={empty:0,food:1,wall:2,mouth:3,producer:4,mover:5,killer:6,armor:7,eye:8,colors:["#121D29","green","gray","orange","white","#3493EB","red","purple","#d4bb3f"],names:["Empty","Food","Wall","Mouth","Producer","Mover","Killer","Armor","Eye"],getRandomLivingType:function(){return Math.floor(6*Math.random())+3}};e.exports=i},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){const s=i(5),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,i){const s=i(0),r=i(2);function o(e,t){for(var i of r.edibleNeighbors){l(e,t.grid_map.cellAt(e.col+i[0],e.row+i[1]),t)}}function l(e,t,i){null!=t&&t.type==s.food&&(i.changeCell(t.col,t.row,s.empty,null),e.owner.food_collected++)}function n(e,t){if(!e.owner.is_mover||r.moversCanProduce){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)return void t.changeCell(e.col+l,e.row+n,s.food,null)}}}function a(e,t){for(var i of r.killableNeighbors){h(e,t.grid_map.cellAt(e.col+i[0],e.row+i[1]))}}function h(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,this.func=null}setType(e){switch(this.type=e,this.type){case s.mouth:this.func=o;break;case s.producer:this.func=n;break;case s.killer:this.func=a;break;default:this.func=null}}performFunction(e){null!=this.func&&this.func(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(3),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){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(3),i(4),i(15)),o=i(5),l=i(2),n=i(1),a=i(7),h=i(17);class c{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=n.down,this.rotation=n.up,this.can_rotate=l.moversCanRotate,this.move_count=0,this.move_range=4,this.mutability=5,this.damage=0,this.birth_distance=4,this.brain=new h(this),null!=s&&this.inherit(s)}addCell(e,t,i,s=null){for(var o of this.cells)if(o.loc_col==t&&o.loc_row==i)return!1;return this.checkTypeChange(e),this.cells.push(new r(e,t,i,s)),!0}removeCell(e,t){if(0==e&&0==t)return!1;for(var i=!1,r=0;r1){var d=this.cells[Math.floor(Math.random()*this.cells.length)];t=this.removeCell(d.loc_col,d.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=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}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 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),e.type==s.eye&&(this.getRealCell(e).direction=e.eye.getAbsoluteDirection(this.rotation))}}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.type==s.eye){var t=e.eye.look(this.getRealCol(e),this.getRealRow(e),this.rotation,this.env);this.brain.observe(t)}else if(this.getRealCell(e).performFunction(this.env),!this.living)return this.living;if(this.is_mover){this.move_count++;var i=this.brain.decide(),r=this.attemptMove();(this.move_count>this.move_range&&!i||!r)&&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)}getRealCol(e){return this.c+e.rotatedCol(this.rotation)}getRealRow(e){return this.r+e.rotatedRow(this.rotation)}}e.exports=c},function(e,t,i){const s=i(1),r=i(2),o=i(0),l=i(16);e.exports=class{constructor(e=-1){this.direction=e,-1==e&&(this.direction=s.getRandomDirection())}getAbsoluteDirection(e){var t=e+this.direction;return t>3&&(t-=4),t}look(e,t,i,n){var a=this.getAbsoluteDirection(i),h=0,c=0;switch(a){case s.up:c=-1;break;case s.down:c=1;break;case s.right:h=1;break;case s.left:h=-1}for(var d=e,u=t,g=null,p=0;p{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(19),o=i(20);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(9),r=(i(4),i(10)),o=i(4),l=i(6),n=i(0),a=(i(3),i(18));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 l(e[0],e[1],this);t.addCell(n.mouth,0,0),t.addCell(n.producer,1,1),t.addCell(n.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==n.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==n.wall&&this.changeCell(e.col,e.row,n.empty,null)}clearOrganisms(){for(var e of this.organisms)e.die();this.organisms=[]}reset(e=!0){this.organisms=[],this.grid_map.fillGrid(n.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(0),r=i(1),o=(i(2),i(7));e.exports=class{constructor(e,t,i,r=null){this.type=e,this.loc_col=t,this.loc_row=i,this.type==s.eye&&(this.eye=new o,null!=r&&(this.eye.direction=r.direction))}rotatedCol(e){switch(e){case r.up:return this.loc_col;case r.down:return-1*this.loc_col;case r.left:return this.loc_row;case r.right:return-1*this.loc_row}}rotatedRow(e){switch(e){case r.up:return this.loc_row;case r.down:return-1*this.loc_row;case r.left:return-1*this.loc_col;case r.right:return this.loc_col}}}},function(e,t){e.exports=class{constructor(e,t,i){this.cell=e,this.distance=t,this.direction=i}}},function(e,t,i){i(0);const s=i(2),r=i(1),o=0,l=1,n=2,a=function(){return Math.floor(3*Math.random())};e.exports=class{constructor(e){this.owner=e,this.observations=[],this.decisions=[o,n,o,o,o,o,l,o,o]}observe(e){this.observations.push(e)}decide(){var e=o,t=s.lookRange+1,i=0;for(var a of this.observations)null!=a.cell&&a.cell.owner!=this.owner&&a.distancethis.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(9),r=i(6),o=i(4),l=i(10),n=i(0),a=i(21),h=(i(3),i(7)),c=i(1);e.exports=class extends s{constructor(){super(),this.is_active=!0;this.renderer=new l("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.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?(console.log(l.type),i==n.eye&&l.type!=n.eye&&(l.eye=new h(c.up)),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,n.empty,null):alert("Cannot remove center cell")}setOrganismToCopyOf(e){this.grid_map.fillGrid(n.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(n.empty);var e=this.grid_map.getCenter();this.organism=new r(e[0],e[1],this,null),this.organism.addCell(n.mouth,0,0),this.organism.updateGrid()}}},function(e,t,i){const s=i(11),r=i(8),o=i(0),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.defineEditorOptions()}mouseMove(){(this.right_click||this.left_click)&&this.editOrganism()}mouseDown(){this.editOrganism()}mouseUp(){}getCurLocalCell(){return console.log(this.env.organism.getLocalCell(this.mouse_c-this.env.organism.c,this.mouse_r-this.env.organism.r)),this.env.organism.getLocalCell(this.mouse_c-this.env.organism.c,this.mouse_r-this.env.organism.r)}setEyeDirection(){}editOrganism(){if(null!=this.edit_cell_type&&this.mode==r.Edit){if(this.left_click)if(this.edit_cell_type==o.eye)if(this.cur_cell.type==o.eye){var e=(t=this.getCurLocalCell()).eye.direction;e=l.rotateRight(e),t.eye.direction=e,this.cur_cell.direction=e,this.env.addCellToOrg(this.mouse_c,this.mouse_r,this.edit_cell_type)}else{var t;this.env.addCellToOrg(this.mouse_c,this.mouse_r,this.edit_cell_type),(t=this.getCurLocalCell()).eye.direction=l.up,this.env.addCellToOrg(this.mouse_c,this.mouse_r,this.edit_cell_type)}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 diff --git a/src/Controllers/ControlPanel.js b/src/Controllers/ControlPanel.js index 99509fb..23c7f76 100644 --- a/src/Controllers/ControlPanel.js +++ b/src/Controllers/ControlPanel.js @@ -28,7 +28,6 @@ class ControlPanel { $('#maximize').click ( function() { $('.control-panel').css('display', 'grid'); $('.hot-controls').css('display', 'none'); - }); } @@ -89,26 +88,11 @@ class ControlPanel { defineHyperparameterControls() { $('#food-prod-prob').change(function() { - var food_prob = $('#food-prod-prob').val(); - if ($('#fixed-ratio').is(":checked")) { - Hyperparams.foodProdProb = food_prob; - Hyperparams.calcProducerFoodRatio(false); - $('#lifespan-multiplier').val(Hyperparams.lifespanMultiplier); - } - else{ - Hyperparams.foodProdProb = food_prob; - } + var food_prob = + Hyperparams.foodProdProb = $('#food-prod-prob').val();; }.bind(this)); $('#lifespan-multiplier').change(function() { - var lifespan = $('#lifespan-multiplier').val(); - if ($('#fixed-ratio').is(":checked")) { - Hyperparams.lifespanMultiplier = lifespan; - Hyperparams.calcProducerFoodRatio(true); - $('#food-prod-prob').val(Hyperparams.foodProdProb); - } - else { - Hyperparams.lifespanMultiplier = lifespan; - } + Hyperparams.lifespanMultiplier = $('#lifespan-multiplier').val(); }.bind(this)); $('#mover-rot').change(function() { @@ -120,6 +104,9 @@ class ControlPanel { $('#insta-kill').change(function() { Hyperparams.instaKill = this.checked; }); + $('#look-range').change(function() { + Hyperparams.lookRange = $('#look-range').val(); + }); $('#evolved-mutation').change( function() { if (this.checked) { @@ -164,7 +151,6 @@ class ControlPanel { Hyperparams.setDefaults(); $('#food-prod-prob').val(Hyperparams.foodProdProb); $('#lifespan-multiplier').val(Hyperparams.lifespanMultiplier); - $('#fixed-ratio').prop('checked', true); $('#mover-rot').prop('checked', Hyperparams.moversCanRotate); $('#offspring-rot').prop('checked', Hyperparams.offspringRotate); $('#insta-kill').prop('checked', Hyperparams.instaKill); diff --git a/src/Controllers/EditorController.js b/src/Controllers/EditorController.js index 5ed4127..1ef6fb4 100644 --- a/src/Controllers/EditorController.js +++ b/src/Controllers/EditorController.js @@ -1,6 +1,7 @@ const CanvasController = require("./CanvasController"); const Modes = require("./ControlModes"); const CellTypes = require("../Organism/Cell/CellTypes"); +const Directions = require("../Organism/Directions"); class EditorController extends CanvasController{ constructor(env, canvas) { @@ -23,11 +24,39 @@ class EditorController extends CanvasController{ mouseUp(){} + getCurLocalCell(){ + console.log(this.env.organism.getLocalCell(this.mouse_c-this.env.organism.c, this.mouse_r-this.env.organism.r)) + return this.env.organism.getLocalCell(this.mouse_c-this.env.organism.c, this.mouse_r-this.env.organism.r); + } + + setEyeDirection(){ + + } + editOrganism() { if (this.edit_cell_type == null || this.mode != Modes.Edit) return; - if (this.left_click) - this.env.addCellToOrg(this.mouse_c, this.mouse_r, this.edit_cell_type); + if (this.left_click){ + if(this.edit_cell_type == CellTypes.eye) { + if (this.cur_cell.type == CellTypes.eye){ + var loc_cell = this.getCurLocalCell(); + var dir = loc_cell.eye.direction; + dir = Directions.rotateRight(dir); + loc_cell.eye.direction = dir; + this.cur_cell.direction = dir; + this.env.addCellToOrg(this.mouse_c, this.mouse_r, this.edit_cell_type); + } + else { + this.env.addCellToOrg(this.mouse_c, this.mouse_r, this.edit_cell_type); + var loc_cell = this.getCurLocalCell(); + loc_cell.eye.direction = Directions.up; + this.env.addCellToOrg(this.mouse_c, this.mouse_r, this.edit_cell_type); + } + } + else{ + this.env.addCellToOrg(this.mouse_c, this.mouse_r, this.edit_cell_type); + } + } if (this.right_click) this.env.removeCellFromOrg(this.mouse_c, this.mouse_r); } @@ -55,6 +84,9 @@ class EditorController extends CanvasController{ case "armor": self.edit_cell_type = CellTypes.armor; break; + case "eye": + self.edit_cell_type = CellTypes.eye; + break; } $(".cell-type" ).css( "border-color", "black" ); var selected = '#'+this.id+'.cell-type'; diff --git a/src/Controllers/EnvironmentController.js b/src/Controllers/EnvironmentController.js index a070eb5..880645b 100644 --- a/src/Controllers/EnvironmentController.js +++ b/src/Controllers/EnvironmentController.js @@ -94,6 +94,7 @@ class EnvironmentController extends CanvasController{ } if (this.cur_org != null){ this.control_panel.setEditorOrganism(this.cur_org); + console.log(this.cur_org) } break; @@ -139,7 +140,7 @@ class EnvironmentController extends CanvasController{ var c = this.cur_cell.col + loc[0]; var r = this.cur_cell.row + loc[1]; var cell = this.env.grid_map.cellAt(c, r); - if (cell.owner != null) + if (cell != null && cell.owner != null) return cell.owner; } return null; @@ -150,7 +151,7 @@ class EnvironmentController extends CanvasController{ var c = this.cur_cell.col + loc[0]; var r = this.cur_cell.row + loc[1]; var cell = this.env.grid_map.cellAt(c, r); - if (cell.owner != null) + if (cell != null && cell.owner != null) cell.owner.die(); } } diff --git a/src/Engine.js b/src/Engine.js index ec5ac7b..66ca4ce 100644 --- a/src/Engine.js +++ b/src/Engine.js @@ -7,7 +7,7 @@ const render_speed = 60; class Engine{ constructor(){ this.fps = 60; - this.env = new WorldEnvironment(4); + this.env = new WorldEnvironment(5); this.organism_editor = new OrganismEditor(); this.controlpanel = new ControlPanel(this); this.env.OriginOfLife(); diff --git a/src/Environments/OrganismEditor.js b/src/Environments/OrganismEditor.js index be04d82..351f10f 100644 --- a/src/Environments/OrganismEditor.js +++ b/src/Environments/OrganismEditor.js @@ -5,6 +5,8 @@ const Renderer = require('../Rendering/Renderer'); const CellTypes = require('../Organism/Cell/CellTypes'); const EditorController = require("../Controllers/EditorController"); const Cell = require("../Organism/Cell/Cell"); +const Eye = require('../Organism/Perception/Eye'); +const Directions = require('../Organism/Directions'); class OrganismEditor extends Environment{ constructor() { @@ -37,6 +39,11 @@ class OrganismEditor extends Environment{ var loc_r = r - center[1]; var prev_cell = this.organism.getLocalCell(loc_c, loc_r) if (prev_cell != null) { + console.log(prev_cell.type) + if (type == CellTypes.eye && prev_cell.type != CellTypes.eye){ + prev_cell.eye = new Eye(Directions.up); + + } prev_cell.type = type; this.changeCell(c, r, type, this.organism); } diff --git a/src/Environments/WorldEnvironment.js b/src/Environments/WorldEnvironment.js index 25b67ed..5418aba 100644 --- a/src/Environments/WorldEnvironment.js +++ b/src/Environments/WorldEnvironment.js @@ -54,10 +54,12 @@ class WorldEnvironment extends Environment{ OriginOfLife() { var center = this.grid_map.getCenter(); var org = new Organism(center[0], center[1], this); + // org.addCell(CellTypes.eye, 0, 0); + // org.addCell(CellTypes.mouth, 1, 1); + // org.addCell(CellTypes.mover, -1, -1); org.addCell(CellTypes.mouth, 0, 0); - // org.addCell(CellTypes.eye, 2, 2); - org.addCell(CellTypes.producer, -1, -1); org.addCell(CellTypes.producer, 1, 1); + org.addCell(CellTypes.producer, -1, -1); this.addOrganism(org); } diff --git a/src/Hyperparameters.js b/src/Hyperparameters.js index fad5cd8..a2c1cdc 100644 --- a/src/Hyperparameters.js +++ b/src/Hyperparameters.js @@ -23,19 +23,7 @@ const Hyperparams = { this.instaKill = false; - this.lookRange = 5; - }, - - // calculates the optimal ratio where a producer cell is most likely to produce 1 food in its lifespan * a scalar of my choice :) - calcProducerFoodRatio : function(lifespan_fixed=true) { - if (lifespan_fixed) { - // change the foodProdProb - this.foodProdProb = (100 / this.lifespanMultiplier) * this.foodProdProbScalar; - } - else { - // change the lifespanMultiplier - this.lifespanMultiplier = Math.floor(100 / (this.foodProdProb/this.foodProdProbScalar)); - } + this.lookRange = 15; }, balanceMutationProbs : function(choice) { diff --git a/src/Organism/Cell/CellTypes.js b/src/Organism/Cell/CellTypes.js index d1cdfa5..4726c2b 100644 --- a/src/Organism/Cell/CellTypes.js +++ b/src/Organism/Cell/CellTypes.js @@ -8,7 +8,8 @@ const CellTypes = { killer: 6, armor: 7, eye: 8, - colors: ['#121D29', 'green', 'gray', 'orange', 'white', '#3493EB', 'red', 'purple', '#8D73A3'], + colors: ['#121D29', 'green', 'gray', 'orange', 'white', '#3493EB', 'red', 'purple', '#d4bb3f'], + names: ['Empty', 'Food', 'Wall', 'Mouth', 'Producer', 'Mover', 'Killer', 'Armor', 'Eye'], getRandomLivingType: function() { return Math.floor(Math.random() * 6) + 3; } diff --git a/src/Organism/Cell/LocalCell.js b/src/Organism/Cell/LocalCell.js index 7c09e26..c92e95a 100644 --- a/src/Organism/Cell/LocalCell.js +++ b/src/Organism/Cell/LocalCell.js @@ -10,7 +10,7 @@ class LocalCell{ this.loc_col = loc_col; this.loc_row = loc_row; if (this.type == CellTypes.eye){ - this.eye = new Eye(this); + this.eye = new Eye(); if (eye != null) { this.eye.direction = eye.direction; } diff --git a/src/Organism/Directions.js b/src/Organism/Directions.js index 331c11a..57128be 100644 --- a/src/Organism/Directions.js +++ b/src/Organism/Directions.js @@ -21,6 +21,13 @@ const Directions = { case this.right: return this.left; } + }, + rotateRight: function(dir) { + dir++; + if (dir > 3){ + dir = 0; + } + return dir; } } diff --git a/src/Organism/Organism.js b/src/Organism/Organism.js index d734041..7a728dc 100644 --- a/src/Organism/Organism.js +++ b/src/Organism/Organism.js @@ -21,6 +21,7 @@ class Organism { this.cells = []; this.is_producer = false; this.is_mover = false; + this.has_eyes = false; this.direction = Directions.down; this.rotation = Directions.up; this.can_rotate = Hyperparams.moversCanRotate; @@ -42,7 +43,7 @@ class Organism { } } - this.checkProducerMover(type); + this.checkTypeChange(type); this.cells.push(new LocalCell(type, c, r, eye)); return true; } @@ -65,7 +66,7 @@ class Organism { this.is_producer = false; this.is_producer = false; for (var cell of this.cells) { - this.checkProducerMover(cell.type); + this.checkTypeChange(cell.type); } } return true; @@ -80,11 +81,13 @@ class Organism { return null; } - checkProducerMover(type) { + checkTypeChange(type) { if (type == CellTypes.producer) this.is_producer = true; if (type == CellTypes.mover) this.is_mover = true; + if (type == CellTypes.eye) + this.has_eyes = true; } inherit(parent) { @@ -93,11 +96,17 @@ class Organism { this.birth_distance = parent.birth_distance; for (var c of parent.cells){ //deep copy parent cells - if (c.type == CellTypes.eye) + if (c.type == CellTypes.eye){ this.addCell(c.type, c.loc_col, c.loc_row, c.eye); + } else this.addCell(c.type, c.loc_col, c.loc_row); } + if(parent.is_mover) { + for (var i in parent.brain.decisions) { + this.brain.decisions[i] = parent.brain.decisions[i]; + } + } } // amount of food required before it can reproduce @@ -180,9 +189,9 @@ class Organism { } cell.type = CellTypes.getRandomLivingType(); if (cell.type == CellTypes.eye) { - cell.eye = new Eye(cell); + cell.eye = new Eye(); } - this.checkProducerMover(cell.type); + this.checkTypeChange(cell.type); mutated = true; } else if (choice <= Hyperparams.addProb + Hyperparams.changeProb + Hyperparams.removeProb){ @@ -204,6 +213,9 @@ class Organism { if (this.birth_distance < 1) this.birth_distance = 1; } + if (this.is_mover && this.has_eyes && Math.random() * 100 <= 10) { + this.brain.mutate(); + } return mutated; } @@ -249,6 +261,11 @@ class Organism { return false; } + changeDirection(dir) { + this.direction = dir; + this.move_count = 0; + } + // assumes either c1==c2 or r1==r2, returns true if there is a clear path from point a to b isStraightPath(c1, r1, c2, r2, parent){ if (c1 == c2) { @@ -320,7 +337,7 @@ class Organism { var real_c = this.c + cell.rotatedCol(this.rotation); var real_r = this.r + cell.rotatedRow(this.rotation); this.env.changeCell(real_c, real_r, cell.type, this); - if (cell.type == CellTypes.eye){ + if (cell.type == CellTypes.eye) { this.getRealCell(cell).direction = cell.eye.getAbsoluteDirection(this.rotation); } } diff --git a/src/Organism/Perception/Brain.js b/src/Organism/Perception/Brain.js index e901809..7031a53 100644 --- a/src/Organism/Perception/Brain.js +++ b/src/Organism/Perception/Brain.js @@ -5,7 +5,10 @@ const Directions = require("../Directions"); const Decision = { neutral: 0, retreat: 1, - chase: 2 + chase: 2, + getRandom: function(){ + return Math.floor(Math.random() * 3); + } } class Brain { @@ -16,7 +19,7 @@ class Brain { // corresponds to CellTypes this.decisions = [ Decision.neutral, // empty - Decision.chase, // food + Decision.chase, // food Decision.neutral, // wall Decision.neutral, // mouth Decision.neutral, // producer @@ -27,19 +30,19 @@ class Brain { ]; } - observe(observation){ + observe(observation) { this.observations.push(observation); } - decide(){ + decide() { var decision = Decision.neutral; var closest = Hyperparams.lookRange + 1; var move_direction = 0; for (var obs of this.observations) { - if (obs.cell == null || obs.cell.owner == this.owner){ + if (obs.cell == null || obs.cell.owner == this.owner) { continue; } - if (obs.distance < closest){ + if (obs.distance < closest) { decision = this.decisions[obs.cell.type]; move_direction = obs.direction; closest = obs.distance; @@ -47,17 +50,20 @@ class Brain { } this.observations = []; if (decision == Decision.chase) { - this.owner.direction = move_direction; - this.owner.move_count = 0; + this.owner.changeDirection(move_direction); return true; } else if (decision == Decision.retreat) { - this.owner.direction = Directions.getOppositeDirection(move_direction); - this.owner.move_count = 0; + this.owner.changeDirection(Directions.getOppositeDirection(move_direction)); return true; } return false; } + + mutate() { + var selection = Math.floor(Math.random() * (this.decisions.length-1))+1; + this.decisions[selection] = Decision.getRandom(); + } } module.exports = Brain; \ No newline at end of file diff --git a/src/Organism/Perception/Eye.js b/src/Organism/Perception/Eye.js index 11ac185..d649909 100644 --- a/src/Organism/Perception/Eye.js +++ b/src/Organism/Perception/Eye.js @@ -4,12 +4,11 @@ const CellTypes = require("../Cell/CellTypes"); const Observation = require("./Observation") class Eye { - constructor(loc_cell, direction=-1) { + constructor(direction=-1) { this.direction = direction; if (direction == -1){ this.direction = Directions.getRandomDirection(); } - this.loc_cell = loc_cell } getAbsoluteDirection(parent_dir) { @@ -44,7 +43,7 @@ class Eye { col+=addCol; row+=addRow; cell = env.grid_map.cellAt(col, row); - if (cell == null){ + if (cell == null) { break; } if (cell.type != CellTypes.empty){ diff --git a/src/Rendering/Renderer.js b/src/Rendering/Renderer.js index 023da32..15f3623 100644 --- a/src/Rendering/Renderer.js +++ b/src/Rendering/Renderer.js @@ -34,8 +34,7 @@ class Renderer { renderFullGrid(grid) { for (var col of grid) { for (var cell of col){ - this.ctx.fillStyle = cell.getColor(); - this.ctx.fillRect(cell.x, cell.y, this.cell_size, this.cell_size); + this.renderCell(cell); } } } @@ -66,31 +65,17 @@ class Renderer { //odd var w = 1; } - var halfInt = Math.floor(this.cell_size/2); + var halfInt = Math.ceil(this.cell_size/2); var halfFloat = this.cell_size/2; - var h = this.cell_size/3; + var h = this.cell_size/2 + this.cell_size/4; var x = cell.x + h - Math.floor(w/2); var y = cell.y; this.ctx.translate(cell.x+halfFloat, cell.y+halfFloat); - this.ctx.rotate(cell.direction * 90 * Math.PI / 180); - // switch(cell.direction) { - // case Directions.up: - // this.ctx.rotate(90 * Math.PI / 180); - // break; - // case Directions.right: - // this.ctx.rotate(Math.PI / 180); - // break; - // case Directions.down: - // this.ctx.rotate(180 * Math.PI / 180); - // break; - // case Directions.left: - // this.ctx.rotate(270 * Math.PI / 180); - // break; - // } - this.ctx.fillStyle = '#FFFC5E'; - this.ctx.fillRect(-halfFloat, -halfFloat, this.cell_size, h); + this.ctx.rotate((cell.direction * 90) * Math.PI / 180); + this.ctx.fillStyle = '#121D29'; + this.ctx.fillRect(-(this.cell_size)/8, -halfFloat, this.cell_size/4, h); this.ctx.setTransform(1, 0, 0, 1, 0, 0); } diff --git a/src/Util/LinkedList.js b/src/Util/LinkedList.js deleted file mode 100644 index 3818f50..0000000 --- a/src/Util/LinkedList.js +++ /dev/null @@ -1,43 +0,0 @@ -class LinkedList { - constructor() { - this.head = null; - this.size = 0; - } - push(obj) { - var el = new Element(obj, null, this.head); - if (this.head != null){ - this.head.prev = el; - } - this.head = el; - this.size ++; - } - clear() { - var cur = this.head; - while(cur != null){ - this.remove(cur); - cur = cur.next; - } - this.size = 0; - } - - remove(element){ - if (element.prev != null){ - element.prev.next = element.next; - } - else if (this.head == element){ - this.head = element.next; - } - if (element.next != null){ - element.next.prev = element.prev; - } - this.size--; - } -} - -class Element { - constructor(obj, prev, next){ - this.obj = obj; - this.prev = prev; - this.next = next; - } -} \ No newline at end of file