-
-
Save codecademydev/990cd6f84bc6265cf634b67902f0b16b to your computer and use it in GitHub Desktop.
Codecademy export
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 = '*'; | |
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