I retried my solution and it worked very well. Are you sure you execute it normaly?
This was the hardest challenge yet, and I have to admit, at my stage in the Front-end Developer Pathway I couldn’t solve it. I know quite a bit of JavaScript by now, but I still don’t know how to think like a developer, especially not a game developer so I really didn’t have a clue how to approach this.
Like many of the other people here I had to ask Copilot/AI to help me understand the instructions and explain suggested solution code step-by-step.
Because I wrote my final code alongside Copilot, I don’t consider that I have completed the challenge, but I did learn something from the explanations and re-writing suggested code blocks etc.
Changes
- I changed from prompt-sync to readline-sync because readline-sync actually waits for the player to press enter before moving on, whereas prompt-sync was repeating the ‘question’ again before I had even pressed enter on my previous direction choice.
- In the constructor I check if there is a custom field argument from the class instance, and if not then the generateField method will create a random one
- I use WASD as they are more common direction keys in games today
Printing the map
I didn’t really understand this instruction, so my code is literally printing the current state of the map. This is obviously not a good idea for the game because right from the start the player knows exactly where the hat and holes are and what move would be out of bounds. I am assuming the instructions alluded to me writing code to somehow mask the field and only show the players moves (with an *), but I didn’t know how to approach this so left it.
My ‘pair programming’ code with Copilot :
const readlineSync = require("readline-sync");
const hat = "^";
const hole = "O";
const fieldCharacter = "░";
const pathCharacter = "*";
class Field {
constructor(field) {
if (field) {
this.field = field;
} else {
this.field = Field.generateField();
}
this.locationX = 0;
this.locationY = 0;
this.field[0][0] = pathCharacter;
}
//test if is a hole
isHole() {
return this.field[this.locationY][this.locationX] === hole;
}
//test if is hat
isHat() {
return this.field[this.locationY][this.locationX] === hat;
}
//test if is out of bounds
isInBounds() {
return (
this.locationX >= 0 &&
this.locationY >= 0 &&
this.locationX < this.field[0].length &&
this.locationY < this.field.length
);
}
//ask user direction question and get answer.
askQuestion() {
const question = readlineSync
.question(
`Which way?
W = up
A = left
S = down
D = right: `
)
.toUpperCase();
return question;
}
//update users location on the map
updateLocation(direction) {
switch (direction) {
case "W":
this.locationY -= 1;
break;
case "S":
this.locationY += 1;
break;
case "A":
this.locationX -= 1;
break;
case "D":
this.locationX += 1;
break;
default:
console.log("Please enter W, A,S, D to move");
break;
}
}
//update the map with the new user pathway (user moves marked by *)
updateField() {
return (this.field[this.locationY][this.locationX] = pathCharacter);
}
//print the current state of the field map
print() {
this.field.forEach((row) => {
console.log(row.join(""));
});
}
//run through the game loop until win or lose
runGame() {
let playing = true;
while (playing) {
this.print(); // Prints the map
const userMove = this.askQuestion(); // Prompts the player for move
this.updateLocation(userMove);
if (!this.isInBounds()) {
console.log("You fell off the map and lost the game!");
playing = false;
} else if (this.isHole()) {
console.log("You fell in a hole and lost the game!");
playing = false;
} else if (this.isHat()) {
console.log("You found your hat and won the game!");
playing = false;
} else {
const fieldUpdated = this.updateField();
if (fieldUpdated) {
this.print(); // Print updated field to show new state
}
}
}
}
static generateField() {
const height = Math.floor(Math.random() * 5) + 5;
const width = Math.floor(Math.random() * 5) + 5;
const percentage = Math.random() * 0.2 + 0.1;
const field = Array.from({ length: height }, () =>
Array.from({ length: width }, () => fieldCharacter)
);
let hatX, hatY;
do {
hatX = Math.floor(Math.random() * width);
hatY = Math.floor(Math.random() * height);
} while (hatX === 0 && hatY === 0);
field[hatY][hatX] = hat;
const numHoles = Math.floor(width * height * percentage);
let holesPlaced = 0;
while (holesPlaced < numHoles) {
const holeX = Math.floor(Math.random() * height);
const holeY = Math.floor(Math.random() * width);
if ((holeX !== 0 || holeY !== 0) && field[holeX][holeY] !== hat) {
field[holeX][holeY] = hole;
holesPlaced++;
}
}
return field;
}
} //end class
const game1 = new Field();
game1.runGame();
My Code’s hosted on GitHub here.
I didn’t find this to be quite as hard as it sounded, but it did take me a while! I didn’t use the prompt-sync package because I didn’t know what it was, so I just used the process.stdin.on() function to set up an input listener.
Hello everyone,
At this point, I have to say that this assignment feels too challenging given the course material we’ve covered so far. While we’re approaching 2025 and tools like ChatGPT can help us complete the assignment with ease, the real issue lies in doing so without truly understanding it.
This is where my concern stems from. Since 2020, no one from Codecademy has created a video tutorial to guide us through this process. I believe such a resource would be incredibly helpful in explaining the logic behind the assignment and enabling more people to move forward with confidence.
Thank for any feedback
I will be appreciated if anyone can review my code and give some feedback on how to optimize and make it cleaner
I agree and have felt this about lots of projects.
Done this. Haven’t done “hard mode” or validator, as well as any graphics. Only random spawn location is done amongst the challanges. It was quite interesting to solve though.
hey. my solution:
nice project to work on and hone up the skills.
Here is my solution to the challange.
This is my solution!
Hi! Here is my solution: My Code