Skip to content

Instantly share code, notes, and snippets.

@codecademydev
Created July 9, 2020 23:04
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 codecademydev/990cd6f84bc6265cf634b67902f0b16b to your computer and use it in GitHub Desktop.
Save codecademydev/990cd6f84bc6265cf634b67902f0b16b to your computer and use it in GitHub Desktop.
Codecademy export
const prompt = require('prompt-sync')({sigint: true});
const hat = '^';
const hole = 'O';
const fieldCharacter = '░';
const pathCharacter = '*';
const MoveStat = {
GOOD: 0,
FOUND_HAT: 1,
IN_HOLE: 2,
OUT_OF_BOUNDS: 3
}
function randInt(max) {
return (Math.random() * max) | 0;
}
class Field {
constructor(grid) {
this._grid = grid;
this.findStart();
}
get x() { return this._x; }
get y() { return this._y; }
get grid() { return this._grid; }
// Find the first path character in the field and sets _x,_y to it.
findStart() {
for (let y = 0; y < this._grid.length; ++y) {
let x = this._grid[y].findIndex(elem => elem === pathCharacter);
if (x >= 0) {
this._x = x;
this._y = y;
return;
}
}
this._x = this._y = -1;
}
// Print the field to the console
print() {
for (let row of this._grid) {
console.log(row.join(''));
}
}
// Returns a value from the MoveStat "enum".
// If a valid move, also plops the path character down there.
setPos(x, y) {
if (x < 0 || y < 0 || y >= this._grid.length || x >= this._grid[y].length) {
return MoveStat.OUT_OF_BOUNDS;
}
if (this._grid[y][x] === hat) {
return MoveStat.FOUND_HAT;
}
if (this._grid[y][x] === hole) {
return MoveStat.IN_HOLE;
}
this._x = x;
this._y = y;
this._grid[y][x] = pathCharacter;
return MoveStat.GOOD;
}
// Adds a hole to a random open spot.
addHole() {
let [x, y] = Field.findOpenSpot(this._grid);
this._grid[y][x] = hole;
}
// Returns a new width x height field.
// Holeyness is the percentage of the field covered in holes.
static generateField(width, height, holeyness=30) {
// Create empty grid
const grid = Array.from({ length: height }, () => Array(width).fill(fieldCharacter));
// Clamp holeyness between 0% - 90%
holeyness = Math.min(Math.max(0, holeyness), 90)
// Add holes to it
holeyness *= 0.01; // Convert from percent to fraction
if (0) {
// This version treats holeyness as the percentage of the
// field covered in holes.
const numholes = holeyness * width * height;
for (let i = 0; i < numholes; ++i) {
let [x, y] = Field.findOpenSpot(grid);
grid[y][x] = hole;
}
} else {
// This version treats holeyness as the percent chance that
// a particular grid square will be a hole instead of field.
for (let y = 0; y < height; ++y) {
for (let x = 0; x < width; ++x) {
if (Math.random() < holeyness) {
grid[y][x] = hole;
}
}
}
}
// Start in a random location
grid[randInt(height)][randInt(width)] = pathCharacter;
// Drop a hat on the field somewhere
let [x, y] = Field.findOpenSpot(grid);
grid[y][x] = hat;
return new Field(grid);
}
static findOpenSpot(grid) {
let x, y;
do {
y = randInt(grid.length);
x = randInt(grid[y].length);
} while (grid[y][x] !== fieldCharacter);
return [x, y];
}
}
// Game loop. If holeFreq is non-0, then a hole is ended
// every holeFreq-th turn.
function loop(field, holeFreq) {
for (let turnNum = 0;; ++turnNum) {
if (holeFreq > 0 && turnNum > 0 && turnNum % holeFreq == 0) {
field.addHole();
}
field.print();
let x = field.x;
let y = field.y;
console.log(x,y);
const dir = prompt('Which way? ');
switch (dir[0].toLowerCase()) {
case 'u': --y; break;
case 'd': ++y; break;
case 'l': --x; break;
case 'r': ++x; break;
default:
console.log('What way is that?');
continue;
}
switch (field.setPos(x, y)) {
case MoveStat.OUT_OF_BOUNDS:
console.log('You fell off the edge of the world! AAAAA!!!');
return;
case MoveStat.IN_HOLE:
console.log("You've fallen down a hole and can't get up!");
return;
case MoveStat.FOUND_HAT:
console.log('Yay! You found your hat!');
return;
}
}
}
/*
const myField = new Field([
['░', '*', 'O'],
['░', 'O', '░'],
['░', '^', '░'],
]);
*/
const width = Number(prompt('Width (20)? ', 20));
const height = Number(prompt('Height (10)? ', 10));
const holepercent = Number(prompt('Hole percentage (15)? ', 15));
const holeadd = Number(prompt('How often to add a hole (0)? ', 0));
const myField = Field.generateField(width, height, holepercent);
loop(myField, holeadd);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment