diff options
| author | Mike Buland <Mike.Buland@mjfirm.com> | 2016-10-20 15:35:30 -0600 |
|---|---|---|
| committer | Mike Buland <Mike.Buland@mjfirm.com> | 2016-10-20 15:35:30 -0600 |
| commit | 9fb42f1e2e1361a07f0fca213dfb914d71763781 (patch) | |
| tree | b009c1ab1726f8be7e7ee87456099f68f564de48 | |
| parent | 2c857684d920f502d72a42f97f7b57e5e72ba2f8 (diff) | |
| download | lost-9fb42f1e2e1361a07f0fca213dfb914d71763781.tar.gz lost-9fb42f1e2e1361a07f0fca213dfb914d71763781.tar.bz2 lost-9fb42f1e2e1361a07f0fca213dfb914d71763781.tar.xz lost-9fb42f1e2e1361a07f0fca213dfb914d71763781.zip | |
Hey! it renders and has multiple levels.
It generates buttons so you can see each floor for now.
Diffstat (limited to '')
| -rw-r--r-- | js/lost.html | 7 | ||||
| -rw-r--r-- | js/lost.js | 549 |
2 files changed, 556 insertions, 0 deletions
diff --git a/js/lost.html b/js/lost.html new file mode 100644 index 0000000..38f246e --- /dev/null +++ b/js/lost.html | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | <html> | ||
| 2 | <head> | ||
| 3 | </head> | ||
| 4 | <body> | ||
| 5 | <script src="lost.js"></script> | ||
| 6 | </body> | ||
| 7 | </html> | ||
diff --git a/js/lost.js b/js/lost.js new file mode 100644 index 0000000..b2b908c --- /dev/null +++ b/js/lost.js | |||
| @@ -0,0 +1,549 @@ | |||
| 1 | "use strict"; | ||
| 2 | // It's strict! | ||
| 3 | |||
| 4 | // | ||
| 5 | // Helper functions | ||
| 6 | // | ||
| 7 | |||
| 8 | // Just return a random integer between 0 and max, exclusive on the upper bound. | ||
| 9 | function randInt( max ) | ||
| 10 | { | ||
| 11 | return Math.floor(Math.random() * max); | ||
| 12 | } | ||
| 13 | |||
| 14 | // Return the id for the opposite direction of the direction given. | ||
| 15 | function oppositeDir( iDir ) | ||
| 16 | { | ||
| 17 | if( iDir%2 === 1 ) | ||
| 18 | return iDir-1; | ||
| 19 | return iDir+1; | ||
| 20 | } | ||
| 21 | |||
| 22 | // | ||
| 23 | // Class: Cell | ||
| 24 | // | ||
| 25 | function Cell() | ||
| 26 | { | ||
| 27 | this.iDist = 0; | ||
| 28 | this.iPath = 0; | ||
| 29 | this.iWalls = 0; | ||
| 30 | } | ||
| 31 | |||
| 32 | // | ||
| 33 | // Class: Position | ||
| 34 | // | ||
| 35 | function Position( iDims, ...Vals ) | ||
| 36 | { | ||
| 37 | // Store dimension count | ||
| 38 | this.iDims = iDims; | ||
| 39 | |||
| 40 | // Check to see if Vals is a non-empty array | ||
| 41 | if( Array.isArray(Vals) && Vals.length > 0 ) | ||
| 42 | { | ||
| 43 | // Make sure Vals has the right number of elements | ||
| 44 | if( Vals.length != iDims ) | ||
| 45 | { | ||
| 46 | throw new Error( | ||
| 47 | 'Position must be initialized with no dimensional data, '+ | ||
| 48 | 'or the correct number of elements.'); | ||
| 49 | } | ||
| 50 | |||
| 51 | // If it does have the correct number of elements, just | ||
| 52 | // use it instead of creating a new array | ||
| 53 | this.aiValues = Vals; | ||
| 54 | } | ||
| 55 | else | ||
| 56 | { | ||
| 57 | // We don't have values from the constructor, let's just | ||
| 58 | // create a new blank one... | ||
| 59 | this.aiValues = new Array( this.iDims ); | ||
| 60 | |||
| 61 | // ...and set the position to zero in all dimensions. | ||
| 62 | for( let j = 0; j < this.iDims; j++ ) | ||
| 63 | { | ||
| 64 | this.aiValues[j] = 0; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | Position.prototype.getDims = function getDims() | ||
| 70 | { | ||
| 71 | return this.iDims; | ||
| 72 | } | ||
| 73 | |||
| 74 | Position.prototype.get = function get( iDim ) | ||
| 75 | { | ||
| 76 | return this.aiValues[iDim]; | ||
| 77 | } | ||
| 78 | |||
| 79 | Position.prototype.set = function set( iDim, iVal ) | ||
| 80 | { | ||
| 81 | this.aiValues[iDim] = iVal; | ||
| 82 | } | ||
| 83 | |||
| 84 | Position.prototype.add = function add( iDim, iDelta ) | ||
| 85 | { | ||
| 86 | this.aiValues[iDim] += iDelta; | ||
| 87 | return this.aiValues[iDim]; | ||
| 88 | } | ||
| 89 | |||
| 90 | Position.prototype.translate = function translate( iDim, iDelta ) | ||
| 91 | { | ||
| 92 | let tmp = new Position( this.iDims, ...this.aiValues.slice() ); | ||
| 93 | tmp.add( iDim, iDelta ); | ||
| 94 | return tmp; | ||
| 95 | } | ||
| 96 | |||
| 97 | Position.prototype.copy = function translate() | ||
| 98 | { | ||
| 99 | return new Position( this.iDims, ...this.aiValues.slice() ); | ||
| 100 | } | ||
| 101 | |||
| 102 | // | ||
| 103 | // Class: Map | ||
| 104 | // | ||
| 105 | function Map( Dimensions ) | ||
| 106 | { | ||
| 107 | // Store dimensional data | ||
| 108 | this.Dimensions = Dimensions; | ||
| 109 | |||
| 110 | // Compute the total number of cells | ||
| 111 | let iTotalSize = 1; | ||
| 112 | for( let j = 0; j < Dimensions.getDims(); j++ ) | ||
| 113 | { | ||
| 114 | iTotalSize *= Dimensions.get( j ); | ||
| 115 | } | ||
| 116 | |||
| 117 | // Allocate cell array, and initialize cells | ||
| 118 | this.aCell = new Array( iTotalSize ); | ||
| 119 | for( let j = 0; j < iTotalSize; j++ ) | ||
| 120 | { | ||
| 121 | this.aCell[j] = new Cell(); | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | Map.prototype.getDims = function getDims() | ||
| 126 | { | ||
| 127 | return this.Dimensions.getDims(); | ||
| 128 | } | ||
| 129 | |||
| 130 | Map.prototype.getSize = function getSize( iDim ) | ||
| 131 | { | ||
| 132 | return this.Dimensions.get( iDim ); | ||
| 133 | } | ||
| 134 | |||
| 135 | Map.prototype.isInside = function isInside( Position ) | ||
| 136 | { | ||
| 137 | if( Position.getDims() != this.Dimensions.getDims() ) | ||
| 138 | { | ||
| 139 | throw new Error( | ||
| 140 | 'Number of dimensions in map and position do not match.' | ||
| 141 | ); | ||
| 142 | } | ||
| 143 | |||
| 144 | for( let j = 0; j < this.getDims(); j++ ) | ||
| 145 | { | ||
| 146 | if( Position.get( j ) < 0 ) | ||
| 147 | return false; | ||
| 148 | if( Position.get( j ) >= this.Dimensions.get( j ) ) | ||
| 149 | return false; | ||
| 150 | } | ||
| 151 | |||
| 152 | return true; | ||
| 153 | } | ||
| 154 | |||
| 155 | Map.prototype.getIndex = function getIndex( Position ) | ||
| 156 | { | ||
| 157 | if( !this.isInside( Position ) ) | ||
| 158 | { | ||
| 159 | throw new Error('Position is outside of map.'); | ||
| 160 | } | ||
| 161 | |||
| 162 | let iIdx = 0; | ||
| 163 | let iScale = 1; | ||
| 164 | for( let j = 0; j < this.getDims(); j++ ) | ||
| 165 | { | ||
| 166 | iIdx += Position.get( j ) * iScale; | ||
| 167 | iScale *= this.Dimensions.get( j ); | ||
| 168 | } | ||
| 169 | return iIdx; | ||
| 170 | } | ||
| 171 | |||
| 172 | Map.prototype.get = function get( Position ) | ||
| 173 | { | ||
| 174 | return this.aCell[this.getIndex( Position )]; | ||
| 175 | } | ||
| 176 | |||
| 177 | Map.prototype.connect = function connect( iWormId1, iWormId2 ) | ||
| 178 | { | ||
| 179 | let p = new Position( this.getDims() ); | ||
| 180 | let pMax1 = null; | ||
| 181 | let pMax2 = null; | ||
| 182 | let iDistMax = 0; | ||
| 183 | let iDirMax = 0; | ||
| 184 | |||
| 185 | let iDim = 0; | ||
| 186 | for(;;) | ||
| 187 | { | ||
| 188 | let c = this.get( p ); | ||
| 189 | if( c.iPath === iWormId1 || c.iPath === iWormId2 ) | ||
| 190 | { | ||
| 191 | // This cell is one of the two paths we want to connect, let's | ||
| 192 | // see if there's a cell from the other path nearby. | ||
| 193 | for( iDim = 0; iDim < this.getDims(); iDim++ ) | ||
| 194 | { | ||
| 195 | // Look 'down' in the current dimension | ||
| 196 | let t = p.translate( iDim, -1 ); | ||
| 197 | for( let iDir = 0; iDir < 2; iDir++ ) | ||
| 198 | { | ||
| 199 | // Is the current position inside the maze? | ||
| 200 | if( t.get( iDim ) >= 0 && | ||
| 201 | t.get( iDim ) < this.getSize( iDim ) ) | ||
| 202 | { | ||
| 203 | // Get cell here. | ||
| 204 | let c2 = this.get( t ); | ||
| 205 | if( c.iPath !== c2.iPath && | ||
| 206 | (c2.iPath === iWormId1 || c2.iPath === iWormId2 ) ) | ||
| 207 | { | ||
| 208 | let iDist = c.iDist + c2.iDist; | ||
| 209 | if( iDist > iDistMax ) | ||
| 210 | { | ||
| 211 | iDistMax = iDist; | ||
| 212 | pMax1 = p.copy(); | ||
| 213 | pMax2 = t.copy(); | ||
| 214 | iDirMax = iDim*2+iDir; | ||
| 215 | } | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | // Look the other direction | ||
| 220 | t.add( iDim, 2 ); | ||
| 221 | } | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | // This is the rediculous engine that lets us iterate through | ||
| 226 | // the entire maze, one cell at a time. This basically increments our | ||
| 227 | // position by one, but wraps at the edges of the maze. | ||
| 228 | for( iDim = 0; iDim < this.getDims(); iDim++ ) | ||
| 229 | { | ||
| 230 | let iNewVal = p.add( iDim, 1 ); | ||
| 231 | if( iNewVal < this.getSize( iDim ) ) | ||
| 232 | break; | ||
| 233 | p.set( iDim, 0 ); | ||
| 234 | } | ||
| 235 | |||
| 236 | // If we ran out of dimensions then it means that we hit the last | ||
| 237 | // cell in the grid. | ||
| 238 | if( iDim == this.getDims() ) | ||
| 239 | break; | ||
| 240 | } | ||
| 241 | |||
| 242 | this.get( pMax1 ).iWalls |= (1<<iDirMax); | ||
| 243 | this.get( pMax2 ).iWalls |= (1<<oppositeDir(iDirMax)); | ||
| 244 | } | ||
| 245 | |||
| 246 | // | ||
| 247 | // Class: Vector | ||
| 248 | // | ||
| 249 | function Vector( pPos, iDir ) | ||
| 250 | { | ||
| 251 | this.pPos = pPos; | ||
| 252 | this.iDir = iDir; | ||
| 253 | } | ||
| 254 | |||
| 255 | // | ||
| 256 | // Class: Worm | ||
| 257 | // | ||
| 258 | function Worm( iId, pStart, rMap ) | ||
| 259 | { | ||
| 260 | // Initialize basic state, we start with distance set to 1 | ||
| 261 | this.iId = iId; | ||
| 262 | this.pPosition = pStart; | ||
| 263 | this.rMap = rMap; | ||
| 264 | this.iDist = 1; | ||
| 265 | |||
| 266 | // Setup walls here to create an opening. We're only going to do | ||
| 267 | // this on the first two dimensions. This assumes that we have at least | ||
| 268 | // two dimensions, which I feel like is a safe assumption. 1d mazes are... | ||
| 269 | // pretty easy. | ||
| 270 | let iDirs = []; | ||
| 271 | if( this.pPosition.get( 0 ) === 0 ) | ||
| 272 | iDirs.push( 1 ); | ||
| 273 | else if( this.pPosition.get( 0 ) === this.rMap.getSize( 0 )-1 ) | ||
| 274 | iDirs.push( 2 ); | ||
| 275 | |||
| 276 | if( this.pPosition.get( 1 ) === 0 ) | ||
| 277 | iDirs.push( 4 ); | ||
| 278 | else if( this.pPosition.get( 1 ) === this.rMap.getSize( 1 )-1 ) | ||
| 279 | iDirs.push( 8 ); | ||
| 280 | |||
| 281 | // Now that we know if we're near a wall in the first two demensions | ||
| 282 | // do something with that | ||
| 283 | if( iDirs.length > 0 ) | ||
| 284 | { | ||
| 285 | // We are near a wall, pick a random wall to open a hole in | ||
| 286 | this.rMap.get(this.pPosition).iWalls |= iDirs[randInt(iDirs.length)]; | ||
| 287 | this.rMap.get(this.pPosition).iPath = this.iId; | ||
| 288 | } | ||
| 289 | } | ||
| 290 | |||
| 291 | Worm.prototype.timestep = function timestep() | ||
| 292 | { | ||
| 293 | // Handy to reference how many dimensions we have | ||
| 294 | let iDims = this.rMap.getDims(); | ||
| 295 | |||
| 296 | // Possible directions | ||
| 297 | let pDirs = []; | ||
| 298 | |||
| 299 | for(;;) | ||
| 300 | { | ||
| 301 | let pBack = null; | ||
| 302 | for( let j = 0; j < iDims; j++ ) | ||
| 303 | { | ||
| 304 | let iSize = this.rMap.getSize( j ); | ||
| 305 | let pPos = this.pPosition.translate( j, -1 ); | ||
| 306 | if( pPos.get( j ) >= 0 ) | ||
| 307 | { | ||
| 308 | let xCell = this.rMap.get( pPos ); | ||
| 309 | if( xCell.iPath === 0 ) | ||
| 310 | { | ||
| 311 | pDirs.push( new Vector( pPos, j*2 ) ); | ||
| 312 | } | ||
| 313 | else if( xCell.iPath === this.iId && | ||
| 314 | xCell.iDist === this.iDist-1 ) | ||
| 315 | { | ||
| 316 | pBack = pPos; | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | pPos = this.pPosition.translate( j, 1 ); | ||
| 321 | if( pPos.get( j ) < iSize ) | ||
| 322 | { | ||
| 323 | let xCell = this.rMap.get( pPos ); | ||
| 324 | if( xCell.iPath === 0 ) | ||
| 325 | { | ||
| 326 | pDirs.push( new Vector( pPos, j*2+1 ) ); | ||
| 327 | } | ||
| 328 | else if( xCell.iPath === this.iId && | ||
| 329 | xCell.iDist === this.iDist-1 ) | ||
| 330 | { | ||
| 331 | pBack = pPos; | ||
| 332 | } | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | if( pDirs.length > 0 ) | ||
| 337 | { | ||
| 338 | break; | ||
| 339 | } | ||
| 340 | else | ||
| 341 | { | ||
| 342 | if( pBack !== null ) | ||
| 343 | { | ||
| 344 | this.pPosition = pBack; | ||
| 345 | this.iDist--; | ||
| 346 | } | ||
| 347 | else | ||
| 348 | { | ||
| 349 | return false; | ||
| 350 | } | ||
| 351 | } | ||
| 352 | } | ||
| 353 | |||
| 354 | let iSel = randInt( pDirs.length ); | ||
| 355 | let cCur = this.rMap.get( this.pPosition ); | ||
| 356 | cCur.iWalls |= (1<<pDirs[iSel].iDir); | ||
| 357 | let cNext = this.rMap.get( pDirs[iSel].pPos ); | ||
| 358 | cNext.iWalls |= (1<<oppositeDir( pDirs[iSel].iDir )); | ||
| 359 | cNext.iDist = ++this.iDist; | ||
| 360 | cNext.iPath = this.iId; | ||
| 361 | this.pPosition = pDirs[iSel].pPos; | ||
| 362 | |||
| 363 | return true; | ||
| 364 | } | ||
| 365 | |||
| 366 | // | ||
| 367 | // Class: Render | ||
| 368 | // | ||
| 369 | function Render( rMap, eParent ) | ||
| 370 | { | ||
| 371 | this.rMap = rMap; | ||
| 372 | this.eParent = eParent; | ||
| 373 | } | ||
| 374 | |||
| 375 | Render.prototype.render = function render() | ||
| 376 | { | ||
| 377 | } | ||
| 378 | |||
| 379 | // | ||
| 380 | // Class: RenderCanvas2D | ||
| 381 | // | ||
| 382 | function RenderCanvas2D( rMap, eParent ) | ||
| 383 | { | ||
| 384 | Render.call( this, rMap, eParent ); | ||
| 385 | |||
| 386 | this.eCanvas = null; | ||
| 387 | this.ctx = null; | ||
| 388 | |||
| 389 | this.pExtPosition = new Position( rMap.getDims() ); | ||
| 390 | |||
| 391 | this.iIconSize = 11; | ||
| 392 | this.iBorder = 3; | ||
| 393 | this.iCellSize = | ||
| 394 | this.iBorder + | ||
| 395 | (this.rMap.getDims()-2)*2*(this.iIconSize+this.iBorder); | ||
| 396 | |||
| 397 | this.eCanvas = document.createElement('canvas'); | ||
| 398 | this.eCanvas.width = this.iCellSize*this.rMap.getSize( 0 ); | ||
| 399 | this.eCanvas.height = this.iCellSize*this.rMap.getSize( 1 ); | ||
| 400 | eParent.appendChild( this.eCanvas ); | ||
| 401 | this.ctx = this.eCanvas.getContext("2d"); | ||
| 402 | this.ctx.lineWidth = 1.0; | ||
| 403 | |||
| 404 | this.render(); | ||
| 405 | |||
| 406 | let btnBox = document.createElement('div'); | ||
| 407 | eParent.appendChild( document.createElement('br') ); | ||
| 408 | eParent.appendChild( document.createElement('br') ); | ||
| 409 | eParent.appendChild( btnBox ); | ||
| 410 | |||
| 411 | for( let j = 2; j < this.rMap.getDims(); j++ ) | ||
| 412 | { | ||
| 413 | for( let k = 0; k < this.rMap.getSize( j ); k++ ) | ||
| 414 | { | ||
| 415 | let btn = document.createElement('button'); | ||
| 416 | btn.addEventListener( | ||
| 417 | 'click', | ||
| 418 | RenderCanvas2D.prototype.setFloor.bind( | ||
| 419 | this, | ||
| 420 | [k] | ||
| 421 | ) | ||
| 422 | ); | ||
| 423 | btn.appendChild( | ||
| 424 | document.createTextNode('Floor ' + (k+1) ) | ||
| 425 | ); | ||
| 426 | btnBox.appendChild( btn ); | ||
| 427 | } | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | RenderCanvas2D.prototype = Object.create(Render.prototype); | ||
| 432 | RenderCanvas2D.prototype.constructor = RenderCanvas2D; | ||
| 433 | |||
| 434 | RenderCanvas2D.prototype.render = function render() | ||
| 435 | { | ||
| 436 | let iSize = this.iCellSize; | ||
| 437 | this.ctx.clearRect( 0, 0, this.eCanvas.width, this.eCanvas.height ); | ||
| 438 | this.ctx.beginPath(); | ||
| 439 | |||
| 440 | let p = this.pExtPosition.copy(); | ||
| 441 | { | ||
| 442 | for( let x = 0; x < this.rMap.getSize( 0 ); x++ ) | ||
| 443 | { | ||
| 444 | for( let y = 0; y < this.rMap.getSize( 1 ); y++ ) | ||
| 445 | { | ||
| 446 | p.set( 0, x ); | ||
| 447 | p.set( 1, y ); | ||
| 448 | let c = this.rMap.get( p ); | ||
| 449 | if( (c.iWalls&1) === 0 && x === 0) | ||
| 450 | { | ||
| 451 | this.ctx.moveTo( x*iSize, y*iSize ); | ||
| 452 | this.ctx.lineTo( x*iSize, (y+1)*iSize ); | ||
| 453 | } | ||
| 454 | if( (c.iWalls&2) === 0 ) | ||
| 455 | { | ||
| 456 | this.ctx.moveTo( (x+1)*iSize, y*iSize ); | ||
| 457 | this.ctx.lineTo( (x+1)*iSize, (y+1)*iSize ); | ||
| 458 | } | ||
| 459 | if( (c.iWalls&4) === 0 && y === 0) | ||
| 460 | { | ||
| 461 | this.ctx.moveTo( x*iSize, y*iSize ); | ||
| 462 | this.ctx.lineTo( (x+1)*iSize, y*iSize ); | ||
| 463 | } | ||
| 464 | if( (c.iWalls&8) === 0 ) | ||
| 465 | { | ||
| 466 | this.ctx.moveTo( x*iSize, (y+1)*iSize ); | ||
| 467 | this.ctx.lineTo( (x+1)*iSize, (y+1)*iSize ); | ||
| 468 | } | ||
| 469 | |||
| 470 | if( (c.iWalls&16) !== 0 ) | ||
| 471 | { | ||
| 472 | // Up | ||
| 473 | let bx = x*iSize+this.iBorder; | ||
| 474 | let by = y*iSize+this.iBorder; | ||
| 475 | this.ctx.moveTo( | ||
| 476 | bx, | ||
| 477 | by+this.iIconSize | ||
| 478 | ); | ||
| 479 | this.ctx.lineTo( | ||
| 480 | bx+this.iIconSize/2, | ||
| 481 | by | ||
| 482 | ); | ||
| 483 | this.ctx.lineTo( | ||
| 484 | bx+this.iIconSize, | ||
| 485 | by+this.iIconSize | ||
| 486 | ); | ||
| 487 | } | ||
| 488 | if( (c.iWalls&32) !== 0 ) | ||
| 489 | { | ||
| 490 | // Down | ||
| 491 | let bx = x*iSize+this.iBorder*2+this.iIconSize; | ||
| 492 | let by = y*iSize+this.iBorder; | ||
| 493 | this.ctx.moveTo( | ||
| 494 | bx, | ||
| 495 | by | ||
| 496 | ); | ||
| 497 | this.ctx.lineTo( | ||
| 498 | bx+this.iIconSize/2, | ||
| 499 | by+this.iIconSize | ||
| 500 | ); | ||
| 501 | this.ctx.lineTo( | ||
| 502 | bx+this.iIconSize, | ||
| 503 | by | ||
| 504 | ); | ||
| 505 | } | ||
| 506 | } | ||
| 507 | } | ||
| 508 | } | ||
| 509 | this.ctx.stroke(); | ||
| 510 | } | ||
| 511 | |||
| 512 | RenderCanvas2D.prototype.setFloor = function setFloor( aFloor ) | ||
| 513 | { | ||
| 514 | for( let j = 0; j < aFloor.length; j++ ) | ||
| 515 | { | ||
| 516 | this.pExtPosition.set( j+2, aFloor[j] ); | ||
| 517 | } | ||
| 518 | this.render(); | ||
| 519 | } | ||
| 520 | |||
| 521 | // | ||
| 522 | // Initialize | ||
| 523 | // | ||
| 524 | let p = new Position( 3, 15, 15, 3 ); | ||
| 525 | let m = new Map( p ); | ||
| 526 | let exit1 = new Position( p.getDims() ); | ||
| 527 | let exit2 = new Position( p.getDims() ); | ||
| 528 | exit2.set( 1, p.get( 1 )-1 ); | ||
| 529 | let w = [ | ||
| 530 | new Worm( 1, exit1, m ), | ||
| 531 | new Worm( 2, exit2, m ) | ||
| 532 | ]; | ||
| 533 | |||
| 534 | do | ||
| 535 | { | ||
| 536 | for( let j = 0; j < w.length; j++ ) | ||
| 537 | { | ||
| 538 | if( !w[j].timestep() ) | ||
| 539 | { | ||
| 540 | w.splice( j, 1 ); | ||
| 541 | j--; | ||
| 542 | } | ||
| 543 | } | ||
| 544 | } while( w.length > 0 ); | ||
| 545 | |||
| 546 | m.connect( 1, 2 ); | ||
| 547 | |||
| 548 | let rend = new RenderCanvas2D( m, document.body ); | ||
| 549 | //rend.render( document.body ); | ||
