Skip to content

Instantly share code, notes, and snippets.

@mj2silva
Last active August 14, 2021 07:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mj2silva/ea2b54c0145dff6b3ae5c21f86e07a23 to your computer and use it in GitHub Desktop.
Save mj2silva/ea2b54c0145dff6b3ae5c21f86e07a23 to your computer and use it in GitHub Desktop.
Node JS Console hat finder game
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