Need help with my javascript : chore bot project


#1

https://www.codecademy.com/paths/web-development/tracks/building-interactive-javascript-websites/modules/web-dev-interactive-websites/projects/chore-door

Hi, I need some help with my javascript. When I try to debug my JS, they tell me that my function playDoor is not defined. I don’t understand what it means since I passed an argument in the function.

here is my code:

let doorImage1 = document.getElementById('door1');

let doorImage2 = document.getElementById('door2');

let doorImage3 = document.getElementById('door3');

let botDoorPath = "https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/robot.svg";

let beachDoorPath = "https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/beach.svg";

let spaceDoorPath = "https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/space.svg";

let closedDoorPath = "https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/closed_door.svg";

let numClosedDoors= 3;
let openDoor1;
let openDoor2;
let openDoor3;

let startButton= document.getElementById('start');




const randomChoreDoorGenerator=()=> {
  
  let choreDoor= Math.floor(Math.random()*numClosedDoors);
  
  if ( choreDoor === 0){
    openDoor1 = botDoorPath;
    openDoor2 = beachDoorPath;
    openDoor3 = spaceDoorPath;
  }
  else if (choreDoor ===1){
    openDoor2 = botDoorPath;
    openDoor3 = beachDoorPath;
    openDoor1 = spaceDoorPath;
  } 
  else{
    openDoor3 = botDoorPath;
    openDoor1 = beachDoorPath;
    openDoor2 = spaceDoorPath; 
  };
  
};

doorImage1.onclick = function() {
  if (!isClicked(doorImage1)){
    doorImage1.src= openDoor1;
  }  
};
playDoor(door1);

doorImage2.onclick = function() {
  if (!isClicked(doorImage2)){
    doorImage2.src= openDoor2;
  }  
};
playDoor(door2);

doorImage3.onclick = function() {
  if (!isClicked(doorImage3)){
    doorImage3.src= openDoor3;
  }  
};
playDoor(door3);

const gameOver= (status)=> {
  if ( status === 'win'){
    startButton.innerHTML= 'You win! Play again?';
  } else {
    startButton.innerHTML= 'Game Over! Play again?'
  };
};

randomChoreDoorGenerator();

const isBot = (door) =>{
  if(door.src === botDoorPath){
    return true
  }else{
    return false
  };
};

const isClicked = (door) => {
  if (door.src === closedDoorPath){
    return false;  
  }else{
    return true;
  };
};

const playDoor= (door)=> {
  numClosedDoors--;
  if (numberClosedDoors===0){
    gameOver('win')
  }
  else if (isBot(door)) {
   gameOver();
  };
};

#2

A general rule when there is no hoisting is to have functions that call other functions appear later in the source listing. This may be the problem here.

Suggest moving all the click handlers to the bottom of the listing, and the randomChoreDoorGenerator(); line to the very bottom.


#3

i tried to put all this at the very bottom:

doorImage1.onclick = function() {
if (!isClicked(doorImage1)){
doorImage1.src= openDoor1;
}
};
playDoor(door1);

doorImage2.onclick = function() {
if (!isClicked(doorImage2)){
doorImage2.src= openDoor2;
}
};
playDoor(door2);

doorImage3.onclick = function() {
if (!isClicked(doorImage3)){
doorImage3.src= openDoor3;
}
};
playDoor(door3);

randomChoreDoorGenerator();

But it still doesn’t work. I can open a door now but there is no image…


#4

Be sure to put those calls inside the handler body.


#5

it works!
I didn’t know I had to put playDoor inside the function. thank you so much!


#6

I have another issue… My startButton is not working. The innerHTML is not changing.
Have verified my code even against another successful code of the game in the forum but still…

Here is my code:

let doorImage1 = document.getElementById(‘door1’);

let doorImage2 = document.getElementById(‘door2’);

let doorImage3 = document.getElementById(‘door3’);

let botDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/robot.svg”;

let beachDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/beach.svg”;

let spaceDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/space.svg”;

let closedDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/closed_door.svg”;

let numClosedDoors= 3;
let openDoor1;
let openDoor2;
let openDoor3;

let startButton = document.getElementById(“start”);

let currentlyPlaying = true;

const randomChoreDoorGenerator=()=> {

let choreDoor= Math.floor(Math.random()*numClosedDoors);

if ( choreDoor === 0){
openDoor1 = botDoorPath;
openDoor2 = beachDoorPath;
openDoor3 = spaceDoorPath;
}
else if (choreDoor ===1){
openDoor2 = botDoorPath;
openDoor3 = beachDoorPath;
openDoor1 = spaceDoorPath;
}
else{
openDoor3 = botDoorPath;
openDoor1 = beachDoorPath;
openDoor2 = spaceDoorPath;
};

};

const isBot = (door) =>{
if(door.src === botDoorPath){
return true
}else{
return false
};
};

const isClicked = (door) => {
if (door.src === closedDoorPath){
return false;
}else{
return true;
};
};

const playDoor= (door)=> {
numClosedDoors–;
if (numberClosedDoors===0){
gameOver(‘win’)
}
else if (isBot(door)) {
gameOver();
};
};

const gameOver= (status)=> {
if ( status === ‘win’){
startButton.innerHTML= “You win! Play again?”;
} else {
startButton.innerHTML= “Game Over! Play again?”
};
currentlyPlaying = false;
};

doorImage1.onclick = function() {
if (!isClicked(doorImage1) && currentlyPlaying){
doorImage1.src= openDoor1;
}

playDoor(door1);
};
doorImage2.onclick = function() {
if (!isClicked(doorImage2) && currentlyPlaying){
doorImage2.src= openDoor2;
}
playDoor(door2);
};

doorImage3.onclick = function() {
if (!isClicked(doorImage3) && currentlyPlaying){
doorImage3.src= openDoor3;
}
playDoor(door3);
};

const startRound = ()=> {
doorImage1.src= closedDoorPath;
doorImage2.src= closedDoorPath;
doorImage3.src= closedDoorPath;
numClosedDoors= 3;
startButton.innerHTML = “Good luck!”;
currentlyPlaying = true;
randomChoreDoorGenerator();
}

startButton.onclick = ()=>{
if (!currentlyPlaying){
startRound();
}
}

startRound();


#7

Check the variable name against your global.


#8

thanks! i see my mistake:
I wrote “numberClosedDoors” instead of “numClosedDoors”

Game is still not functioning as it should… will start everything from fresh.


#9

Organize your code by purpose, not the order in which the instructions assign it.

cached objects
declared globals
utility functions
program control
event listeners
invocation

I put all listeners at the bottom since they usually depend on callbacks which must appear in the source listing above where the callback is first accessed. For the same reason it makes perfect sense (to me) to cache all the element nodes at the very top, along with the globals.


#10

I restarted every step of the game.
Finally I got the game to work almost perfectly. But I still have one problem with my “onClick” functions or with the numClosedDoor = 3.

When I click 3 times anywhere on the doors, even on the same door 3 times, my startButton goes from “game over” (if I opened the bot door) to “you win”.

let doorImage1= document.getElementById(“door1”);
let doorImage2= document.getElementById(“door2”);
let doorImage3= document.getElementById(“door3”);

const botDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/robot.svg”;

const beachDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/beach.svg”;

const spaceDoorPath= “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/space.svg”;

const closedDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/closed_door.svg”;

let numClosedDoor = 3;
let openDoor1;
let openDoor2;
let openDoor3;

const startButton= document.getElementById(“start”);

let currentlyPlaying = true;

const isBot = (door) => {
if(door.src === botDoorPath) {
return true;
} else {
return false;
}
}

const isClicked = door => {
if (door.src=== closedDoorPath){
return false;
} else {
return true;
}
}

const playDoor = (door) => {
numClosedDoor–;
if(numClosedDoor === 0) {
gameOver(‘win’);
} else if(isBot(door)) {
gameOver();
}
}

const randomChoreDoorGenerator = () => {
let choreDoor= Math.floor(Math.random()*numClosedDoor);
if(choreDoor===0){
openDoor1 = botDoorPath;
openDoor2 = beachDoorPath;
openDoor3 = spaceDoorPath;
} else if(choreDoor===1) {
openDoor2 = botDoorPath;
openDoor3 = beachDoorPath;
openDoor1 = spaceDoorPath;
} else {
openDoor3 = botDoorPath;
openDoor1 = beachDoorPath;
openDoor2 = spaceDoorPath;
}
}

door1.onclick = () => {
if (!isClicked(doorImage1) && currentlyPlaying) {
doorImage1.src= openDoor1;
}
playDoor(door1);
}

door2.onclick = () => {
if (!isClicked(doorImage2) && currentlyPlaying) {
doorImage2.src= openDoor2;
}
playDoor(door2);
}

door3.onclick = () => {
if (!isClicked(doorImage3) && currentlyPlaying) {
doorImage3.src= openDoor3;
}
playDoor(door3);
}

const startRound = () => {
doorImage1.src = closedDoorPath;
doorImage2.src = closedDoorPath;
doorImage3.src = closedDoorPath;
numClosedDoor = 3;
startButton.innerHTML= “Good luck!”;
currentlyPlaying = true;
randomChoreDoorGenerator();
}

startButton.onclick = () => {
if (!currentlyPlaying) {
startRound();
}
}

const gameOver = status => {
if(status === ‘win’) {
startButton.innerHTML= “You win! Play again?”;
} else {
startButton.innerHTML= “Game Over! Play again?”;
}
currentlyPlaying = false;
}

startRound();


#11

thanks for the advice. Once I learn what is what I will apply this rule. I still have no idea of what is a cached object for exemple.


#12
let doorImage1 = document.getElementById(“door1”);
let doorImage2 = document.getElementById(“door2”);
let doorImage3 = document.getElementById(“door3”);

The above three img elements are cached objects (element nodes). Once cached they remain in memory for the duration of the session which allows us to access them in the DOM and manipulate their src attributes.

const startButton= document.getElementById(“start”);

The above cached object lets us manipulate the innerHTML property of that element node.

All four of the above cached nodes can be written at the top, and as we do not want them to ever change, they should all be const.

Your start button handler needs to confirm whether the door has been clicked or not.