From 4a6d948d10eb0aacc9d036e5152ad28488f66515 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 23 Nov 2016 08:13:29 -0700 Subject: Refactored some vars, fixed some docs. It works with the google javascript compiler now. --- js/lost.js | 363 ++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 192 insertions(+), 171 deletions(-) diff --git a/js/lost.js b/js/lost.js index e2cfda5..133dfac 100644 --- a/js/lost.js +++ b/js/lost.js @@ -13,20 +13,20 @@ function oppositeDir( iDir ) return iDir+1; } -// -// Create a new button element using the dom that has the given label, -// and calls the movePlayer method on the given map, along the provided -// dimension, and in the specified direction. -// -// The button created is then returned. -// -function createMoveButton( rMap, iDim, iDir, sLabel ) +/** + * Create a new button element using the dom that has the given label, + * and calls the movePlayer method on the given map, along the provided + * dimension, and in the specified direction. + * + * The button created is then returned. + */ +function createMoveButton( rMazeMap, iDim, iDir, sLabel ) { let btn = document.createElement('button'); btn.addEventListener( 'click', - Map.prototype.movePlayer.bind( - rMap, + MazeMap.prototype.movePlayer.bind( + rMazeMap, iDim, iDir ) @@ -46,22 +46,24 @@ function createMoveButton( rMap, iDim, iDir, sLabel ) return btn; } -// -// Class: RandomLcg -// -// This implements a Linear Congruential Generator PRNG. Is this the best PRNG? -// Nope! Is it decently random for our purposes, sure. -// -// Why was this implemented? I wanted to be able to share mazes, in order to do -// that we needed two things that we can't get from JS by default: -// 1. To be able to set the seed (and get it if possible). -// 2. To be sure that the same algorithm would be used on every version of -// every browser. -// -// Unfortunately JavaScript doesn't gurantee either of these things, so instead -// of writing a CMWC and using a bunch of memory I just used the settings from -// the glibc random function and here we are. -// +/** + * Class: RandomLcg + * + * This implements a Linear Congruential Generator PRNG. Is this the best + * PRNG? Nope! Is it decently random for our purposes, sure. + * + * Why was this implemented? I wanted to be able to share mazes, in order to + * do that we needed two things that we can't get from JS by default: + * 1. To be able to set the seed (and get it if possible). + * 2. To be sure that the same algorithm would be used on every version of + * every browser. + * + * Unfortunately JavaScript doesn't gurantee either of these things, so + * instead of writing a CMWC and using a bunch of memory I just used the + * settings from the glibc random function and here we are. + * + * @constructor + */ function RandomLcg() { // Current state @@ -124,13 +126,15 @@ RandomLcg.prototype.randInt = function randInt( max ) // Lets just build a shared prng object to use all over. let lRand = new RandomLcg(); -// -// Class: Signal -// -// Super simple implementation of a signal/slot concept. I didn't need most of -// the features, so this just lets us connect 0-parameter functions and call -// them en-masse whenever the signal is fired. -// +/** + * Class: Signal + * + * Super simple implementation of a signal/slot concept. I didn't need most of + * the features, so this just lets us connect 0-parameter functions and call + * them en-masse whenever the signal is fired. + * + * @constructor + */ function Signal() { this.aSlot = new Array(); @@ -157,11 +161,13 @@ Signal.prototype.emit = function emit() } } -// -// Class: Cell -// -// Simple container that tracks info about a cell in the maze. -// +/** + * Class: Cell + * + * Simple container that tracks info about a cell in the maze. + * + * @constructor + */ function Cell() { this.iDist = 0; @@ -169,13 +175,15 @@ function Cell() this.iWalls = 0; } -// -// Class: Position -// -// A simple class that keeps track of coordinates in N-dimensional space. -// That's really just an array of numbers with N spaces in it. -// -function Position( iDims, ...Vals ) +/** + * Class: Position + * + * A simple class that keeps track of coordinates in N-dimensional space. + * That's really just an array of numbers with N spaces in it. + * + * @constructor + */ +function Position( iDims, Vals ) { if( typeof iDims === 'string' ) { @@ -263,7 +271,7 @@ Position.prototype.add = function add( iDim, iDelta ) // Position.prototype.translate = function translate( iDim, iDelta ) { - let tmp = new Position( this.iDims, ...this.aiValues.slice() ); + let tmp = new Position( this.iDims, this.aiValues.slice() ); tmp.add( iDim, iDelta ); return tmp; } @@ -273,7 +281,7 @@ Position.prototype.translate = function translate( iDim, iDelta ) // Position.prototype.copy = function translate() { - return new Position( this.iDims, ...this.aiValues.slice() ); + return new Position( this.iDims, this.aiValues.slice() ); } // @@ -309,14 +317,16 @@ Position.prototype.toString = function toString() return ret; } -// -// Class: Map -// -// The maze itself. This doesn't do a whole lot on it's own except track data -// and manage the player position and worms. The worms do the real work of -// generating a maze. -// -function Map( Dimensions ) +/** + * Class: MazeMap + * + * The maze itself. This doesn't do a whole lot on it's own except track data + * and manage the player position and worms. The worms do the real work of + * generating a maze. + * + * @constructor + */ +function MazeMap( Dimensions ) { // Store dimensional data this.Dimensions = Dimensions; @@ -345,7 +355,7 @@ function Map( Dimensions ) // // Get the number of dimensions in this maze. // -Map.prototype.getDims = function getDims() +MazeMap.prototype.getDims = function getDims() { return this.Dimensions.getDims(); } @@ -353,7 +363,7 @@ Map.prototype.getDims = function getDims() // // Get the size of the specified dimension. // -Map.prototype.getSize = function getSize( iDim ) +MazeMap.prototype.getSize = function getSize( iDim ) { return this.Dimensions.get( iDim ); } @@ -361,7 +371,7 @@ Map.prototype.getSize = function getSize( iDim ) // // Get a reference to the current player position in the maze. // -Map.prototype.getPlayerPos = function getPlayerPos() +MazeMap.prototype.getPlayerPos = function getPlayerPos() { return this.pPlayer; } @@ -369,7 +379,7 @@ Map.prototype.getPlayerPos = function getPlayerPos() // // Replace the player position with a new position. // -Map.prototype.setPlayerPos = function setPlayerPos( pNewPos ) +MazeMap.prototype.setPlayerPos = function setPlayerPos( pNewPos ) { this.pPlayer = pNewPos; this.ePlayerMoved.emit(); @@ -380,7 +390,7 @@ Map.prototype.setPlayerPos = function setPlayerPos( pNewPos ) // (iDim). This takes walls and maze borders into account, and will not move // the player in an "illegal" way. // -Map.prototype.movePlayer = function movePlayer( iDim, iDelta ) +MazeMap.prototype.movePlayer = function movePlayer( iDim, iDelta ) { let cCur = this.get( this.pPlayer ); @@ -407,7 +417,7 @@ Map.prototype.movePlayer = function movePlayer( iDim, iDelta ) // // Helper that determines if the provided position is inside the maze or not. // -Map.prototype.isInside = function isInside( Position ) +MazeMap.prototype.isInside = function isInside( Position ) { if( Position.getDims() != this.Dimensions.getDims() ) { @@ -433,7 +443,7 @@ Map.prototype.isInside = function isInside( Position ) // one dimensional array coordinate. This is used to find the actual storage // location of cells internally. // -Map.prototype.getIndex = function getIndex( Position ) +MazeMap.prototype.getIndex = function getIndex( Position ) { if( !this.isInside( Position ) ) { @@ -453,7 +463,7 @@ Map.prototype.getIndex = function getIndex( Position ) // // Get a cell at the given Position. // -Map.prototype.get = function get( Position ) +MazeMap.prototype.get = function get( Position ) { return this.aCell[this.getIndex( Position )]; } @@ -463,7 +473,7 @@ Map.prototype.get = function get( Position ) // and the loop chance (betweer 0.0 and 1.0). This returns the ID that the // added worm was assigned, which starts at one and goes up from there. // -Map.prototype.addWorm = function addWorm( pStart, dLoopChance ) +MazeMap.prototype.addWorm = function addWorm( pStart, dLoopChance ) { if( this.pPlayer === null ) { @@ -493,7 +503,7 @@ Map.prototype.addWorm = function addWorm( pStart, dLoopChance ) // At the moment this function assumes we have 2 worms and connects them // automatically once it's done running. // -Map.prototype.buildMaze = function buildMaze() +MazeMap.prototype.buildMaze = function buildMaze() { do { @@ -516,7 +526,7 @@ Map.prototype.buildMaze = function buildMaze() // wall that seperates the longest combined pathway between the two, and opens // it up into a pathway. // -Map.prototype.connect = function connect( iWormId1, iWormId2 ) +MazeMap.prototype.connect = function connect( iWormId1, iWormId2 ) { let p = new Position( this.getDims() ); let pMax1 = null; @@ -585,46 +595,50 @@ Map.prototype.connect = function connect( iWormId1, iWormId2 ) this.get( pMax2 ).iWalls |= (1< 0 ) { // We are near a wall, pick a random wall to open a hole in - this.rMap.get(this.pPosition).iWalls |= iDirs[lRand.randInt(iDirs.length)]; - this.rMap.get(this.pPosition).iPath = this.iId; + this.rMazeMap.get(this.pPosition).iWalls |= iDirs[lRand.randInt(iDirs.length)]; + this.rMazeMap.get(this.pPosition).iPath = this.iId; } } @@ -659,7 +673,7 @@ function Worm( iId, pStart, rMap, dLoopChance ) Worm.prototype.timestep = function timestep() { // Handy to reference how many dimensions we have - let iDims = this.rMap.getDims(); + let iDims = this.rMazeMap.getDims(); // Possible directions let pDirs = []; @@ -668,16 +682,16 @@ Worm.prototype.timestep = function timestep() let cCur; for(;;) { - cCur = this.rMap.get( this.pPosition ); + cCur = this.rMazeMap.get( this.pPosition ); let pBack = null; pLoopDirs = []; for( let j = 0; j < iDims; j++ ) { - let iSize = this.rMap.getSize( j ); + let iSize = this.rMazeMap.getSize( j ); let pPos = this.pPosition.translate( j, -1 ); if( pPos.get( j ) >= 0 ) { - let xCell = this.rMap.get( pPos ); + let xCell = this.rMazeMap.get( pPos ); if( xCell.iPath === 0 ) { pDirs.push( new Vector( pPos, j*2 ) ); @@ -697,7 +711,7 @@ Worm.prototype.timestep = function timestep() pPos = this.pPosition.translate( j, 1 ); if( pPos.get( j ) < iSize ) { - let xCell = this.rMap.get( pPos ); + let xCell = this.rMazeMap.get( pPos ); if( xCell.iPath === 0 ) { pDirs.push( new Vector( pPos, j*2+1 ) ); @@ -733,10 +747,10 @@ Worm.prototype.timestep = function timestep() } } - cCur = this.rMap.get( this.pPosition ); + cCur = this.rMazeMap.get( this.pPosition ); let iSel = lRand.randInt( pDirs.length ); cCur.iWalls |= (1<= 3 ) + if( this.rMazeMap.getDims() >= 3 ) { cardTd = document.createElement('td'); this.aMoveButtons[4] = cardTd.appendChild( - createMoveButton( this.rMap, 2, -1, "Up (^)" ) + createMoveButton( this.rMazeMap, 2, -1, "Up (^)" ) ); cardRow.appendChild( cardTd ); } @@ -889,16 +907,16 @@ function RenderCanvas2D( rMap, params ) // eMazeContainer, eUIContainer ) cardTbl.appendChild( cardRow ); cardTd = document.createElement('td'); this.aMoveButtons[0] = cardTd.appendChild( - createMoveButton( this.rMap, 0, -1, "West" ) + createMoveButton( this.rMazeMap, 0, -1, "West" ) ); cardRow.appendChild( cardTd ); cardRow.appendChild( document.createElement('td') ); cardTd = document.createElement('td'); this.aMoveButtons[1] = cardTd.appendChild( - createMoveButton( this.rMap, 0, 1, "East" ) + createMoveButton( this.rMazeMap, 0, 1, "East" ) ); cardRow.appendChild( cardTd ); - if( this.rMap.getDims() >= 3 ) + if( this.rMazeMap.getDims() >= 3 ) { cardRow.appendChild( document.createElement('td') ); } @@ -908,38 +926,38 @@ function RenderCanvas2D( rMap, params ) // eMazeContainer, eUIContainer ) cardRow.appendChild( document.createElement('td') ); cardTd = document.createElement('td'); this.aMoveButtons[3] = cardTd.appendChild( - createMoveButton( this.rMap, 1, 1, "South" ) + createMoveButton( this.rMazeMap, 1, 1, "South" ) ); cardRow.appendChild( cardTd ); cardRow.appendChild( document.createElement('td') ); - if( this.rMap.getDims() >= 3 ) + if( this.rMazeMap.getDims() >= 3 ) { cardTd = document.createElement('td'); this.aMoveButtons[5] = cardTd.appendChild( - createMoveButton( this.rMap, 2, 1, "Down (v)" ) + createMoveButton( this.rMazeMap, 2, 1, "Down (v)" ) ); cardRow.appendChild( cardTd ); } this.btnBox.appendChild( cardTbl ); - if( this.rMap.getDims() >= 3 ) + if( this.rMazeMap.getDims() >= 3 ) { cardTbl = document.createElement('table'); - for( let j = 3; j < this.rMap.getDims(); j++ ) + for( let j = 3; j < this.rMazeMap.getDims(); j++ ) { cardRow = document.createElement('tr'); cardTbl.appendChild( cardRow ); cardTd = document.createElement('td'); this.aMoveButtons[j*2] = cardTd.appendChild( - createMoveButton( this.rMap, j, -1, (j+1) + '-' ) + createMoveButton( this.rMazeMap, j, -1, (j+1) + '-' ) ); cardRow.appendChild( cardTd ); cardTd = document.createElement('td'); this.aMoveButtons[j*2+1] = cardTd.appendChild( - createMoveButton( this.rMap, j, 1, (j+1) + '+' ) + createMoveButton( this.rMazeMap, j, 1, (j+1) + '+' ) ); cardRow.appendChild( cardTd ); } @@ -970,10 +988,10 @@ RenderCanvas2D.prototype.render = function render() this.ctx.beginPath(); let p; - if( this.rMap.pPlayer === null ) + if( this.rMazeMap.pPlayer === null ) p = this.pExtPosition.copy(); else - p = this.rMap.pPlayer.copy(); + p = this.rMazeMap.pPlayer.copy(); let iPlayerIcon = Math.floor(this.iIconSquare*0.5) + @@ -981,29 +999,29 @@ RenderCanvas2D.prototype.render = function render() this.ctx.beginPath(); this.ctx.strokeStyle = 'whitesmoke'; - for( let x = 0; x < this.rMap.getSize( 0 ); x++ ) + for( let x = 0; x < this.rMazeMap.getSize( 0 ); x++ ) { this.ctx.moveTo( x*iSize, 0 ); - this.ctx.lineTo( x*iSize, this.rMap.getSize( 1 )*iSize ); + this.ctx.lineTo( x*iSize, this.rMazeMap.getSize( 1 )*iSize ); } - for( let y = 0; y < this.rMap.getSize( 1 ); y++ ) + for( let y = 0; y < this.rMazeMap.getSize( 1 ); y++ ) { this.ctx.moveTo( 0, y*iSize ); - this.ctx.lineTo( this.rMap.getSize( 0 )*iSize, y*iSize ); + this.ctx.lineTo( this.rMazeMap.getSize( 0 )*iSize, y*iSize ); } this.ctx.stroke(); this.ctx.beginPath(); this.ctx.strokeStyle = 'black'; - for( let x = 0; x < this.rMap.getSize( 0 ); x++ ) + for( let x = 0; x < this.rMazeMap.getSize( 0 ); x++ ) { - for( let y = 0; y < this.rMap.getSize( 1 ); y++ ) + for( let y = 0; y < this.rMazeMap.getSize( 1 ); y++ ) { p.set( 0, x ); p.set( 1, y ); - let c = this.rMap.get( p ); + let c = this.rMazeMap.get( p ); - if( p.equals( this.rMap.pGoal ) ) + if( p.equals( this.rMazeMap.pGoal ) ) { let oldStyle = this.ctx.fillStyle; this.ctx.fillStyle = 'palegreen'; @@ -1034,7 +1052,7 @@ RenderCanvas2D.prototype.render = function render() // Extended dimenisons (above 2 :-P) let iIcon = 0; - for( let ed = 2; ed < this.rMap.getDims(); ed++ ) + for( let ed = 2; ed < this.rMazeMap.getDims(); ed++ ) { if( iIcon == iPlayerIcon ) iIcon++; @@ -1057,13 +1075,13 @@ RenderCanvas2D.prototype.render = function render() this.ctx.stroke(); // Draw the player - if( this.rMap.pPlayer !== null ) + if( this.rMazeMap.pPlayer !== null ) { - let bx = this.rMap.pPlayer.get(0)*iSize + + let bx = this.rMazeMap.pPlayer.get(0)*iSize + this.iBorder + Math.floor(iPlayerIcon%this.iIconSquare)*(this.iBorder+this.iIconSize); - let by = this.rMap.pPlayer.get(1)*iSize + + let by = this.rMazeMap.pPlayer.get(1)*iSize + this.iBorder + Math.floor(iPlayerIcon/this.iIconSquare)*(this.iBorder+this.iIconSize); - this.rMap.pPlayer.equals( p ); + this.rMazeMap.pPlayer.equals( p ); this.ctx.beginPath(); this.ctx.ellipse( bx+this.iIconSize*0.5, by+this.iIconSize*0.5, @@ -1143,8 +1161,8 @@ RenderCanvas2D.prototype.renderDirIcon = function renderDirIcon( // RenderCanvas2D.prototype.updateButtons = function updateButtons() { - let c = this.rMap.get( this.rMap.pPlayer ); - for( let j = 0; j < this.rMap.getDims()*2; j++ ) + let c = this.rMazeMap.get( this.rMazeMap.pPlayer ); + for( let j = 0; j < this.rMazeMap.getDims()*2; j++ ) { this.aMoveButtons[j].disabled = (c.iWalls&(1<