Skip to content

Instantly share code, notes, and snippets.

@barreyro
Last active November 10, 2017 16:35
Show Gist options
  • Save barreyro/db6c9428f8fbc1ca67a7a0541203f805 to your computer and use it in GitHub Desktop.
Save barreyro/db6c9428f8fbc1ca67a7a0541203f805 to your computer and use it in GitHub Desktop.
Paint balls and 1 dimensional walls
/*
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