Find Your Hat Project - help

Almost done with this project, but I’m hung up on a type error thrown when I try to print this.field.
Here’s my code:

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

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

//Parent class
class Field {
    constructor(field){
        this.field = field; //array
        this.move = '';
        this.y= 0;
        this.x= 0;  
    }
    //print field
     print(height) {        
      for(let i = 0; i< height-1; i++){
        console.log(this.field[i].join(''));
      };   
    }
    //initiate game()
    playGame(){
        let height = prompt('Enter field height');
        let width = prompt('Enter field width');
        let percent = prompt('Enter percentage of holes')

        this.generateField(height,width,percent);
         
      this.x = 0;
      this.y = 0;

      this.print(width);
      this.userMove();    
    }
    //user input - ask and process move
    userMove(){       
        console.log('Enter: up, down, right or left');
        this.move = prompt('Which way?');

        //test if out of bounds  
        //move up but on first row     
        if(this.move === 'up' && this.y === 0){
            console.log('Not valid move, game over');
            this.playAgain();
        //move down but on bottom of column
        }else if (this.move === 'down' && this.y === (this.field.length)-1){
            console.log('Not valid move, game over');
            this.playAgain();
        //move left but on first column 
        }else if(this.move === 'left' && this.x === 0){
            console.log('Not valid move, game over');
            this.playAgain();
        //move right but at end of a row
        }else if(this.move === 'right' && this.x === this.field[this.y].length -1){
            console.log('Not valid move, game over');
            this.playAgain();
        }else {
            //set new coordinates
            if(this.move === 'up'){
                this.y -=1;
            }else if(this.move === 'down'){
                this.y +=1 ;                         
            }else if(this.move === 'left'){
                this.x -=1;
            }else if(this.move === 'right' ) {
                this.x +=1;                
            }else console.log('Enter: up, down, right or left');
            //test if win or lose
            //move = hat, then winner
            if(this.field[this.y][this.x] === hat){
                console.log('You found your hat!, you win!');
                this.playAgain();
            //move = hole, then loser
            }else if(this.field[this.y][this.x] === hole){
                console.log('You found a hole, you lose.');
                this.playAgain();
            }else {
                 //if no win or lose,set new position, then continue              
                this.field[this.y][this.x] = pathCharacter;  
                this.print();
                this.userMove();
            }
        }    
    }

    //reset game, restart
    playAgain(){    
        let resetGame = prompt('Play Again? yes or no');
        if(resetGame === 'yes'){
            this.playGame();
        }else console.log('End');
    }

      //generate random grid static method
    generateField(height,width,percent){
        //declare parent array
        const parentArr = []; 
        // number of child arrays determined by height 
        // length of child arrays determine by width
        //fill child arrays with field character
        for(let z = 0; z< height; z++){
            parentArr.push([]);
            for(let b = 0; b <width;b++){
                parentArr[z].push(fieldCharacter);
            }
        };
        
        //percentage of field covered with holes 
        const totalCharacters = height * width;
        const numberHoles = Math.floor(totalCharacters * (percent * .01));

        //randomize holes in each child array using percentage
        for(let a = 0;a < numberHoles;a++ ){
            let y = Math.floor(Math.random()* height);
            let x = Math.floor(Math.random()* width);
            parentArr[y][x] = hole;
        }

        //set path character at [0][0]
        parentArr[0][0]= pathCharacter;

        //randomize one hat
        let m = Math.floor(Math.random()* height);
        let n =  Math.floor(Math.random()* width);
        parentArr[m][n] = hat; 
         
        this.field = parentArr;  
    }
}

const myField = new Field();

myField.playGame();

Here’s the error message:

C:\Users\Jeffery Amem\Documents\webDev project files\Find-your-hat\main.js:19
        console.log(this.field[i].join(''));
                                  ^

TypeError: Cannot read property 'join' of undefined
:33:12)                                                                                          :35)
    at Object.<anonymous> (C:\Users\Jeffery Amem\Documents\webDev project files\Find-your-hat\mai:33:12)n.js:139:9) 

The error message refers to line 19 which is the print() method. However. the field does print out in the console before the error is thrown.

*░O░░░O░░░
░░░O░░░░░░
░O░O░░░░░░
OO░░░░░░░O
O░░░░O░^O░
OO░░░O░O░░

Thank you in advance. Jeff

Hi Jeff,

I played your game in Fiddle and did not get the error message. But I also did not get all the other console messages until the game was finished. That is probably due to the environment?
Anyway, this doesn’t look right to me:

Your print method requires an argument. In playGame you pass width, in the method definition you called the parameter height, I guess it is the row length?

1 Like

Thank you for the prompt response. I will let you know how it goes. :slightly_smiling_face:

1 Like

@mirja_t Yes!!! I got it to work! You were spot on about my mismatched arguments. Thank you so much for your help.
Here’s my code:

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

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

//Parent class
class Field {
    constructor(field){
        this.field = field; //array
        this.move = '';
        this.y= 0;
        this.x= 0;  
    }
    //print field
     print(height) {        
      for(let i = 0; i< height-1; i++){
        console.log(this.field[i].join(''));
      };   
    }
    //initiate game()
    playGame(){
        let height = prompt('Enter field height');
        let width = prompt('Enter field width');
        let percent = prompt('Enter percentage of holes')

        this.generateField(height,width,percent);
         
      this.x = 0;
      this.y = 0;

      this.userMove(height);
      return height;    
    }
    //user input - ask and process move
    userMove(height){ 
        this.print(height);    
        console.log('Enter: up, down, right or left');
        this.move = prompt('Which way?');

        //test if out of bounds  
        //move up but on first row     
        if(this.move === 'up' && this.y === 0){
            console.log('Not valid move, game over');
            this.playAgain();
        //move down but on bottom of column
        }else if (this.move === 'down' && this.y === (this.field.length)-1){
            console.log('Not valid move, game over');
            this.playAgain();
        //move left but on first column 
        }else if(this.move === 'left' && this.x === 0){
            console.log('Not valid move, game over');
            this.playAgain();
        //move right but at end of a row
        }else if(this.move === 'right' && this.x === this.field[this.y].length -1){
            console.log('Not valid move, game over');
            this.playAgain();
        }else {
            //set new coordinates
            if(this.move === 'up'){
                this.y -=1;
            }else if(this.move === 'down'){
                this.y +=1 ;                         
            }else if(this.move === 'left'){
                this.x -=1;
            }else if(this.move === 'right' ) {
                this.x +=1;                
            }else console.log('Enter: up, down, right or left');
            //test if win or lose
            //move = hat, then winner
            if(this.field[this.y][this.x] === hat){
                console.log('You found your hat!, you win!');
                this.playAgain();
            //move = hole, then loser
            }else if(this.field[this.y][this.x] === hole){
                console.log('You found a hole, you lose.');
                this.playAgain();
            }else {
                 //if no win or lose,set new position, then continue              
                this.field[this.y][this.x] = pathCharacter;             
                this.userMove(height);
            }
            return this.field;
        }    
    }

    //reset game, restart
    playAgain(){    
        let resetGame = prompt('Play Again? yes or no');
        if(resetGame === 'yes'){
            this.playGame();
        }else console.log('End');
    }

      //generate random grid static method
    generateField(height,width,percent){
        //declare parent array
        const parentArr = []; 
        // number of child arrays determined by height 
        // length of child arrays determine by width
        //fill child arrays with field character
        for(let z = 0; z< height; z++){
            parentArr.push([]);
            for(let b = 0; b <width;b++){
                parentArr[z].push(fieldCharacter);
            }
        };
        
        //percentage of field covered with holes 
        const totalCharacters = height * width;
        const numberHoles = Math.floor(totalCharacters * (percent * .01));

        //randomize holes in each child array using percentage
        for(let a = 0;a < numberHoles;a++ ){
            let y = Math.floor(Math.random()* height);
            let x = Math.floor(Math.random()* width);
            parentArr[y][x] = hole;
        }

        //set path character at [0][0]
        parentArr[0][0]= pathCharacter;

        //randomize one hat
        let m = Math.floor(Math.random()* height);
        let n =  Math.floor(Math.random()* width);
        parentArr[m][n] = hat; 
        this.field = parentArr;  
    }
}

const myField = new Field();

myField.playGame();
1 Like

Cool, congratulations! Interesting to see your approach. Mine looks quite different which shows how flexible that project is. I liked it…

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.