Last active
November 10, 2017 16:35
-
-
Save barreyro/db6c9428f8fbc1ca67a7a0541203f805 to your computer and use it in GitHub Desktop.
Paint balls and 1 dimensional walls
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Complete this JS class of a 1 dimensional wall for us to shoot random | |
paint balls at. | |
We want to be able to fire paint balls at a given position and ask the wall | |
if it has been 100% covered by paint. | |
You cannot change any code already written, you can only add to it. This | |
includes the constructor parameter, method names and method parameters. | |
*/ | |
class Wall { | |
constructor(size) { | |
this.size = size; | |
this.covered = false; | |
this.hitCount = 0; | |
this.rangeCovered = {0: {startingRange: 0.0, | |
endingRange: 1.0} | |
};//key: integer, value: rangeObject | |
this.numbersCovered = []; | |
} | |
/** | |
* Add a paint ball at position x (float) | |
* The paint ball is 1 unit wide | |
* x is it's left most position. A paint ball at position 4 will fill units | |
* 4 to 5. A paint ball at position 4.21 will fill 4.21 to 5.21 etc... | |
* @param {float} x left most position where paint ball strikes the wall | |
* @return {null} | |
*/ | |
addPaintBall(x) { //Assumes input has no more than 2 integers after decimal | |
let fixedX = x.toFixed(2) * 1.0; | |
let self = this; | |
self.hitCount++; | |
if(self.numbersCovered.length === self.size) { | |
self.covered = true; | |
} | |
if(self.numbersCovered.length !== self.size) {//Checks if all ranges haven't been hit yet | |
let wholeNum = Math.floor(fixedX); | |
//If x is a whole number and we haven't accounted for x's range, add it to `numbersCovered`: | |
if ((wholeNum === fixedX) && (self.numbersCovered.indexOf(fixedX) === -1)) { | |
self.numbersCovered.push(fixedX); | |
} else { | |
self.setStartingAndEndingRanges(wholeNum, fixedX) | |
} | |
} | |
} | |
setStartingAndEndingRanges(wholeNum, currentFloat) { | |
let self = this; | |
let xRangeLeftOver = (currentFloat - wholeNum).toFixed(2); | |
if (!self.rangeCovered[wholeNum]) { //If key doesn't exist in `this.rangeCovered` | |
self.saveNumWithEndRangeInRangeCoveredObj(wholeNum, 1-xRangeLeftOver) // Set current num in `this.rangeCovered` | |
if (((wholeNum + 1) < self.size) && !self.rangeCovered[wholeNum +1]) { // Set next num in `this.rangeCovered` if not defined yet | |
self.saveNumWithStartRangeInRangeCoveredObj(wholeNum+1, xRangeLeftOver) | |
} else if((wholeNum + 1) < self.size) { //Update next num range if it's already defined in `this.rangeCovered` | |
self.calculateRange(wholeNum + 1, xRangeLeftOver, 'nextNumber') | |
} | |
} else if (!self.rangeCovered[wholeNum +1] && (wholeNum < (self.size - 1))){ //If next num exists in `this.rangeCovered`, but next number is not defined | |
self.calculateRange(wholeNum, xRangeLeftOver, 'currentNumber') | |
self.saveNumWithStartRangeInRangeCoveredObj(wholeNum+1, xRangeLeftOver) | |
} else { //If current num and next number exists in `this.rangeCovered`: | |
self.calculateRange(wholeNum, xRangeLeftOver, 'currentNumber') //sets the endingRange for current num | |
if ((wholeNum +1) < self.size) self.calculateRange(wholeNum + 1, xRangeLeftOver, 'nextNumber') //sets the startingRange for next number | |
} | |
} | |
calculateRange(hashKey, range, bound) { | |
let self = this; | |
let rangeObj = this.rangeCovered[hashKey]; | |
if (bound === 'currentNumber'){ | |
if (rangeObj.startingRange < range){ | |
self.rangeCovered[hashKey].startingRange = range; | |
self.checkRangeOverlap(this.rangeCovered[hashKey], hashKey) | |
} | |
} else if (bound ==='nextNumber') { | |
if (rangeObj.endingRange < range){ | |
self.rangeCovered[hashKey].endingRange = range; | |
self.checkRangeOverlap(self.rangeCovered[hashKey], hashKey) | |
} | |
} | |
} | |
saveNumWithEndRangeInRangeCoveredObj(rangeCoveredKey, endRange){ | |
this.rangeCovered[rangeCoveredKey] = {startingRange: 0.0, endingRange: endRange.toFixed(2)} | |
} | |
saveNumWithStartRangeInRangeCoveredObj(rangeCoveredKey, startRange){ | |
this.rangeCovered[rangeCoveredKey] = {startingRange: startRange * 1.0, endingRange: 1.0} | |
} | |
checkRangeOverlap(rangeObj, rangeCoveredKey){ //numberRange is covered if endingRange < startingRange | |
if(rangeObj.endingRange < rangeObj.startingRange){ | |
this.numbersCovered.push(rangeCoveredKey) | |
} | |
} | |
/** | |
* Tells us if the wall is 100% covered or not | |
* @return {bool} true if the wall is 100% covered, else false | |
*/ | |
isWallCovered() { | |
if (this.hitCount < this.size) { | |
return false | |
} | |
return (this.covered || (this.numbersCovered.length === this.size)); | |
} | |
} | |
//TEST: | |
let size = 21; | |
let wall = new Wall(size); | |
let paintBallCount = size * 1000; | |
wall.addPaintBall(0); // Covering the unlikely case. | |
for (let i = 0; i < paintBallCount; i++) { | |
let newPaintBallPosition = Math.random() * size; | |
wall.addPaintBall(newPaintBallPosition); | |
if(wall.isWallCovered() === true){ | |
console.log('[YAY!] WALL IS COVERED!'); | |
break; | |
} | |
} | |
console.log('done'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment