-
-
Save mj2silva/ea2b54c0145dff6b3ae5c21f86e07a23 to your computer and use it in GitHub Desktop.
Node JS Console hat finder game
This file contains 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
const prompt = require('prompt-sync')({ sigint: true }); | |
const hat = '^'; | |
const hole = 'O'; | |
const fieldCharacter = '░'; | |
const pathCharacter = '*'; | |
class Field { | |
constructor(field) { | |
this.field = field; | |
this.positionX = 0; | |
this.positionY = 0; | |
this.rows = field.length - 1; | |
this.columns = field[0].length - 1; | |
this.path = [[0, 0]]; | |
this.win = false; | |
this.lose = false; | |
} | |
fillPath(x, y) { | |
this.field[x][y] = pathCharacter; | |
} | |
print() { | |
const fieldBoardStr = this.field.reduce((accum, curr) => accum + curr.join('') + '\n', ''); | |
console.log(fieldBoardStr); | |
} | |
checkMove(newPositionX, newPositionY) { | |
if (newPositionX < 0 || newPositionX > this.rows || newPositionY < 0 || newPositionY > this.columns) { | |
throw new Error('You are out of the field'); | |
} else { | |
if (this.path.length > 1 && newPositionX === this.path[this.path.length - 2][0] && newPositionY === this.path[this.path.length - 2][1]) { | |
throw new Error('You can\'t go back!'); | |
} | |
const nextPathObj = this.field[newPositionY][newPositionX]; | |
if (nextPathObj === hole) throw new Error('You fall down in a hole!'); | |
if (nextPathObj === pathCharacter) return false; | |
if (nextPathObj === hat) return true; | |
} | |
} | |
static generateField(height, width, percentage = 0) { | |
// Initialize the number of hats, holes and blanks that should fill the field | |
let hats = 1; | |
let holes = (percentage) ? height * width * percentage / 100 : 1; | |
let blanks = width * height - holes - hats - 1; // Minus one because of the first path character | |
let field = []; | |
const pickOne = () => { | |
const numberOfItemsRemaining = hats + holes + blanks; | |
if (numberOfItemsRemaining) { | |
const newPick = Math.floor(Math.random() * numberOfItemsRemaining + 1); | |
// The program selects an item based on the number of items remaining | |
// This method allows that when the program pick an item for the field, | |
// the probability of picking a certain item was based in the in the remaining | |
// number of items of that particular item. | |
if (newPick <= hats) { | |
hats--; | |
return hat; | |
} | |
if (newPick <= hats + holes) { | |
holes--; | |
return hole; | |
} | |
if (newPick <= numberOfItemsRemaining) { | |
blanks--; | |
return fieldCharacter; | |
} | |
} | |
// By default returns the field character (just in case ;) ) | |
return fieldCharacter; | |
} | |
for (let i = 0; i < height; i++) { | |
const line = []; | |
for (let j = 0; j < width; j++) { | |
if (i === 0 && j === 0) line.push(pathCharacter); | |
else line.push(pickOne()); | |
} | |
field.push(line); | |
} | |
return field; | |
} | |
// 0 -> left - 1 -> Right - 2 -> Up - 3 -> Down | |
movePlayer(direction) { | |
const prevPosition = [this.positionX, this.positionY]; | |
let newPositionX = this.positionX; | |
let newPositionY = this.positionY; | |
switch (direction) { | |
case 0: | |
newPositionX = this.positionX - 1; | |
break; | |
case 1: | |
newPositionX = this.positionX + 1; | |
break; | |
case 2: | |
newPositionY = this.positionY - 1; | |
break; | |
case 3: | |
newPositionY = this.positionY + 1; | |
break; | |
default: | |
break; | |
} | |
try { | |
const winner = this.checkMove(newPositionX, newPositionY); | |
if (!winner) { | |
this.positionX = newPositionX; | |
this.positionY = newPositionY; | |
if (prevPosition[0] !== this.positionX || prevPosition[1] !== this.positionY) { | |
this.path.push([this.positionX, this.positionY]); | |
this.field[this.positionY][this.positionX] = pathCharacter; | |
} | |
} else { | |
this.win = true; | |
console.log("You find the hat!") | |
} | |
} catch (err) { | |
this.lose = true; | |
console.log(err.message); | |
} | |
} | |
} | |
const newField = Field.generateField(5, 6, 20); | |
const myField = new Field(newField); | |
while (!myField.win && !myField.lose) { | |
// console.clear(); | |
myField.print(); | |
const direction = prompt( | |
`Which direction you like to move?: | |
0 -> left |||| 1 -> Right |||| 2 -> Up |||| 3 -> Down: `); | |
myField.movePlayer(Number.parseInt(direction)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment