Find Your Hat Challenge Project (JavaScript)

Thanks David, this works perfectly! It looks a lot better now.

Frustrating but got there in the end! First time dealing with creating 2d arrays, had to use one line from the solution code. Added a few extras; The quicker you are the higher your score. Default mode moves the hat every 10 moves, hard mode moves the hat after a random amount of moves.

Here’s the link: Find-your-hat-game/main.js at master · jamesHarradon/Find-your-hat-game · GitHub

Thanks :slight_smile:

Cheers for that, so much better!

Nice one! I like how you allow the user to choose the size of the field and percentage of holes. I was trying to do the same but completely forgot about parseInt! Thanks :+1:

1 Like

Hello!

This is my solution for the project: GitHub - saritchi/Find-Your-Hat

I was able to implement random field generation, and checked to see it the generation is solvable using Breadth-First Search.

Also, I was trying to use the terminal-kit package but for some reason I couldn’t get ’ ^ ’ to show up in green. I omitted it for now from my code, but I’m curious is anyone else had a similar issue with it.

That was very impressive.

Here’s my attempt at the Find Your Hat Challenge Project:

I am yet to implement a field validator that will ensure the randomly generated field can actually be solved.

Any feedback would be greatly appreciated.

Happy coding.

Here is my solution, open to feedback - find-my-hat/main.js at master · brettjames250/find-my-hat · GitHub

const prompt = require("prompt-sync")({ sigint: true });

const hat = "^";
const hole = "O";
const fieldCharacter = "░";
const pathCharacter = "*";

class Field {
  constructor(field) {
    this.field = field;
    this.row = 0;
    this.column = 0;
  }

  startGame() {
    // PRINT FIELD INITIALLY
    this.print();
    let gameOverFlag = false;

    while (gameOverFlag != true) {
      // RETRIEVE USER MOVE
      const move = prompt("Which way?");

      switch (move) {
        case "r":
          this.column += 1;
          console.log("RIGHT");
          break;
        case "d":
          this.row += 1;
          console.log("DOWN");
          break;
        case "u":
          this.row -= 1;
          console.log("UP");
          break;
        case "l":
          this.column -= 1;
          console.log("LEFT");
          break;
        default:
          console.log("Enter U, D, L or R.");
      }

      // CHECK IF OUT OF BOUNDS
      if (this.isOutOfBounds()) {
        console.log("OUT OF BOUNDS");
        gameOverFlag = true;
        break;
      }

      // CHECK IF HOLE
      if (this.hasFallenDownHole()) {
        console.log("GAME OVER YOU HAVE FALLEN DOWN A HOLE!");
        gameOverFlag = true;
        break;
      }

      // CHECK IF HAT
      if (this.hasFoundHat()) {
        console.log("CONGRATULATIONS, YOU WIN!");
        gameOverFlag = true;
        break;
      }

      // SET NEW USER POSITION
      if (gameOverFlag != true) {
        this.field[this.row][this.column] = pathCharacter;

        // PRINT UPDATED FIELD
        this.print();
      }
    }
  }

  isOutOfBounds() {
    return (
      this.row < 0 ||
      this.row > this.field.length - 1 ||
      this.column < 0 ||
      this.column > this.field[0].length - 1
    );
  }

  hasFoundHat() {
    return this.field[this.row][this.column] === hat;
  }

  hasFallenDownHole() {
    return this.field[this.row][this.column] === hole;
  }

  print() {
    for (let row of this.field) {
      console.log(row.join(" "));
    }
  }

  randomIndex(upperRange) {
    return Math.floor(Math.random() * upperRange);
  }

  static generateField(rows, columns, percentageHoles) {
    let fieldArray = [];

    // GENERATE GRID BASED ON HEIGHT AND WIDTH
    for (let i = 0; i < rows; i++) {
      const line = [];
      for (let j = 0; j < columns; j++) {
        line.push(fieldCharacter);
      }
      fieldArray.push(line);
    }

    // ADD USER
    fieldArray[0][0] = pathCharacter;

    // ADD HAT IN
    const hatColumn = Math.floor(Math.random() * columns);
    const hatRow = Math.floor(Math.random() * rows);

    fieldArray[hatColumn][hatRow] = hat;

    // CALCULATE REQUIRED HOLES
    const numCells = fieldArray.length * fieldArray[0].length;
    let numHoles = Math.round((percentageHoles / 100) * numCells);

    // ADD HOLES IN
    for (numHoles; numHoles > 0; numHoles--) {
      let holeRow = 0;
      let holeColumn = 0;

      // CHECK IF HOLE LOCATION IS ALREADY PATH OR HAT
      while (fieldArray[holeRow][holeColumn] != fieldCharacter) {
        holeRow = Math.floor(Math.random() * rows);
        holeColumn = Math.floor(Math.random() * columns);
      }

      fieldArray[holeRow][holeColumn] = hole;
    }

    return fieldArray;
  }
}

let field = Field.generateField(10, 10, 35);

const myField = new Field(field);

myField.startGame();

Find Your Hat | Generate Random Field | Codecademy Javascript III Project (github.com)

Anyone searching for generating a random field board, here is my approach. Also, modularity and comments for better readability and debugging.

Happy Coding :slight_smile:

Finally got my head around this. I’ll admit I had to get some help on the game mechanic from the codecademy solution, but I think if I had to do something similar in the future, I’d be better able to do it now. Definitely learned a lot with this, also would be worth coming back to try to recreate from memory or adapt to something new.

Here’s my solution

Hi All,

I slightly changed my project as I found more incentive to find Coffee than a Hat. I’ve kept to the Project requirements regarding everything else though …

find-your-coffee-game-simone-waring

I built / ran my project in VS Code rather than using Codecademy’s CLI (for those who are wondering if its worth taking the time to set this up my answer is YES - much easier to debug for starters).

I can see how this project is a handy foundation for all sorts of min games, so I’m really glad we got to do this.

Cheers,
Simone

Hey space_horse

Not sure if this will help but … your arguments for your static method are rows, columns and this is (in my opinion) a really good way to visualise the JS 2D array.

Put simply, a 1D array is a table with 1 row and 1 or more columns whilst a 2D array is a table with 1 or more rows and one or more columns.

single array = 1 row and 3 columns = only 1 row so only one loop

Manhattan | New York | USA

2d array of 2 rows and 2 columns = outer loop for the rows, inner loop for the columns

Manhattan | New York | USA
Sydney | NSW | Australia

Hope this makes it easier to see what you are asking the computer to do - i.e. to start at the first row (0), then go through and do something in each column of that row, represented by the inner loop - just like a table or spreadsheet.

Once you hit your limit of columns, the inner loop finishes meaning you’ve populated the first row.

So now JS moves to the outer loop to see if there is another row (1), if there is it repeats the process of addressing each column in that row and then moves on until you’ve filled out your table