Chore Door Training Problem, Unable to Click the DOOR

Hello, I am currently working on the Chore Door the link is here : https://www.codecademy.com/paths/web-development/tracks/build-interactive-websites/modules/web-dev-interactive-websites/projects/chore-door

The problem is at the before I make randomChoreDoorGenerator my code was working fine. But i keep up following the guide until I realize the code is not working.

I wish someone coud help me figure out what is wrong . Thank you(I’ve checked mine many times but still cant wonder why it doesnt work

My HTML :

<!DOCTYPE html>
<html>
  <head>
    <title>Chore Door!</title>
    <link href="./style.css" rel="stylesheet" type="text/css">
    <link href="https://fonts.googleapis.com/css?family=Work+Sans" rel="stylesheet" type="text/css">
  </head>

  <body>
    <div class="header">
      <img src="https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/logo.svg">
    </div>
    <div class="title-row">
      <img src="https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/star.svg">
      <p class="instruction-title">Instructions</p>
      <img src="https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/star.svg"> 
    </div>
    <table class="instructions-row">
        <tr>
          <td class="instructions-number">1</td>
          <td class="instructions-text">Hiding behind one of these doors is the ChoreBot.</td>
        </tr>
        <tr>
        	<td class="instructions-number">2</td>
          <td class="instructions-text">Your mission is to open all of the doors without running into the ChoreBot.</td>
        </tr>
        <tr>
        	<td class="instructions-number">3</td>
          <td class="instructions-text">If you manage to avoid the ChoreBot until you open the very last door, you win!</td>
        </tr>
        <tr>
        	<td class="instructions-number">4</td>
          <td class="instructions-text">See if you can score a winning streak!</td>
        </tr>
      </table>
		<div class="door-row">
      <img id="door1" class="door-frame" src="https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/closed_door.svg">
      <img id="door2" class="door-frame" src="https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/closed_door.svg">
      <img id="door3" class="door-frame" src="https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/closed_door.svg">
    </div>
    <div id="start" class="start-row">
      GoodLuck!
    </div>
    <script type="text/javascript" src="./sript.js"></script>
  </body>
</html>

My CSS :

body {
  background-color: #010165;
  margin: 0px;
}

.header{
  background-color: #00ffff;
  text-align: center;
}

.title-row {
  margin-top: 42px;
  margin-bottom: 21px;
  text-align: center;
}

.instruction-title {
  display: inline;
  font-size: 18px;
  color: #00ffff;
	font-family: 'Work Sans';
}

.instructions-row {
  margin: 0 auto;
	width: 400px;
}

.instructions-number {
    padding-right: 25px;
    font-family: 'Work Sans';
    font-size: 36px;
    color: #00ffff;
}

.instructions-text{
    padding: 10px;
    font-family: 'Work Sans';
    font-size: 14px;
    color: #ffffff;
}

.door-row{
  text-align: center;
}

.door-frame {
  cursor: pointer;
  padding: 10px;
}

.start-row{
    margin: auto;
    width: 120px;
    height: 43px;
    font-family: 'Work Sans';
    background-color: #eb6536;
    padding-top: 18px;
    font-size: 18px;
    text-align: center;
    color: #010165;
    margin-bottom: 21px;
    cursor: pointer;

}


My JS =

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

let doorImage1= document.getElementById("door1");
let doorImage2= document.getElementById("door2");
let doorImage3= document.getElementById("door3");
let startButton= documen.getElementById("start");

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 isBot(door){
  if(door === botDoorPath){
    return true;
  } else {
    return false;
  }
}

let isClicked = (door) => {
  if(door === closedDoorPath){
    return false;
  } else {
    return true;
  }
}

let playDoor = (door) => {
  numClosedDoor--;
	if(numClosedDoor === 0) {
  	gameOver('win');
	}else if (isBot(door)){
    gameOver();
  }
}

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

doorImage1.onclick = () => {
  doorImage1.src = botDoorPath;
  if(!isClicked(doorImage1) && currentlyPlaying){
    playDoor(doorImage1);
  }
}
doorImage2.onclick = () => {
  doorImage1.src = openDoor2;
  if(!isClicked(doorImage2) && currentlyPlaying){
    playDoor(doorImage2);
  }
}
doorImage3.onclick = () => {
  doorImage1.src = openDoor3;
  if(!isClicked(doorImage3) && currentlyPlaying){
    playDoor(doorImage3);
  }
}

const startRound = () => {
  doorImage1 = closedDoorPath;
  doorImage2 = closedDoorPath;
  doorImage3 = closedDoorPath;
  numClosedDoors = 3;
  startButton.innerHTML = "Good Luck!";
  randomChoreDoorGenerator()
}

startButton.onclick = () => {
  startRound();
}

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

startRound()

The codepen is here : https://codepen.io/anshory/pen/pMrddZ

These can be const, too, since they won’t be changing anytime soon, we hope.

Finding discrepancies…

1 Like

Thank you, that was the mistake I didnt expect lol. But too bad, it still cant working :((

Updated JS =

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

const doorImage1= document.getElementById("door1");
const doorImage2= document.getElementById("door2");
const doorImage3= document.getElementById("door3");
const startButton= documen.getElementById("start");

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 isBot(door){
  if(door === botDoorPath){
    return true;
  } else {
    return false;
  }
}

let isClicked = (door) => {
  if(door === closedDoorPath){
    return false;
  } else {
    return true;
  }
}

let playDoor = (door) => {
  numClosedDoor--;
  if(numClosedDoor === 0) {
    gameOver('win');
  }else if (isBot(door)){
    gameOver();
  }
}

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

doorImage1.onclick = () => {
  doorImage1.src = openDoor1;
  if(!isClicked(doorImage1) && currentlyPlaying){
    playDoor(doorImage1);
  }
}
doorImage2.onclick = () => {
  doorImage2.src = openDoor2;
  if(!isClicked(doorImage2) && currentlyPlaying){
    playDoor(doorImage2);
  }
}
doorImage3.onclick = () => {
  doorImage3.src = openDoor3;
  if(!isClicked(doorImage3) && currentlyPlaying){
    playDoor(doorImage3);
  }
}

const startRound = () => {
  doorImage1 = closedDoorPath;
  doorImage2 = closedDoorPath;
  doorImage3 = closedDoorPath;
  numClosedDoors = 3;
  startButton.innerHTML = "Good Luck!";
  randomChoreDoorGenerator()
}

startButton.onclick = () => {
  startRound();
}

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

startRound()

A typo that keeps the start button from working.

1 Like

Thank youu. Guess i need to learn more to avoid typo

1 Like
let numClosedDoors= 3;
let openDoor1;
let openDoor2;
let openDoor3;
let currentlyPlaying = true;

const doorImage1 = document.getElementById("door1");
const doorImage2 = document.getElementById("door2");
const doorImage3 = document.getElementById("door3");
const startButton = document.getElementById("start");

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"

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(numClosedDoors === 0) {
    gameOver('win');
  }else if (isBot(door)){
    gameOver();
  }
}

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

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

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

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();
  }
}

let gameOver = (status) => {
  if (status === 'win') {
    startButton.innerHTML = 'You win! Play again?';
  }else{
    startButton.innerHTML = 'Game Over! \n Play again?';
  }
  currentlyPlaying = false;
}

startRound()

That looks like it should all work, which I’m assuming it does. Is this from following the video, or the written instructions, only? Hard to tell by looking with my memory of video (or the instructions) so vague.

At each juncture in the path to developing a finished product are iterations that incorporate newer or differing methods of construction and/or materials.

Take for instance this function…

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

First let’s segue to prefixed decrement and suffixed decrement and see how they differ:

x = 3
--x === 0    // false
--x === 0    // false
--x === 0    // true
x = 3
x-- === 0    // false
x-- === 0    // false
x-- === 0    // false
x-- === 0    // true

The reason we are exploring this will become clear in a moment, but first let’s look at the logic of the function above.

To my mind it would make perfect sense to go the shortest route to determining a loss, as opposed to a win.

if (isBot(door)) {
    gameOver()
}

which due to its simplicity, we can write in more expression like form,

if (isBot{door)) gameOver('lose');

Shortest path? Success. It also removes the need for an else clause.

if (--numClosedDoors === 0) gameOver('win');

Using prefixed decrement directly in the conditional combines both operations in a single expression.

Another brief segue that will need to be further researched along the best practices line is default return.

I’ve read (don’t ask me where or when) that all functions should return something, the very least of which is undefined. That is what led JS working groups to create a default return in the first place. But how telling is that return? (Rhetorical question)

In the function above, there is no return unless the result of the latter conditional is false. We can rewire it to return false when gameOver is not called and with a little rewiring of that function, return true.

Bear with me, as this is theoretical, at time of writing.

return --numClosedDoors ? false : gameOver('win');

and to the gameOver function add a final line,

return true;

That return value will travel back to the caller, playDoor and be returned to its caller, one of the doorImage event handlers. Were we to log,

console.log(playDoor(doorImageN));   // N = 1 | 2 | 3

we would see the outcomes in the console with each door click.

Of course this is not productive at all, save for debugging, be we have created a verification process, just the same, and it didn’t take a lot of code, just returns in our functions.

Without changing any other code, ignore the false, and see if this works in your program.

const playDoor = door => {
  return isBot(door) ? gameOver('lose') : 
    --numClosedDoors ? false : gameOver('win')
} 

Before changing anything, can you create a repl of the existing code that one can fork? The image URLs should still work there. That way I can test independent of your code.

If you do not have a profile on repl.it, I’d recommend it as the starting place of sandbox development. Be sure to choose HTML, CSS, JS as the environment (language) so you have all three APIs present.

If the platform will not allow off-domain images, then see if there is a files tab that permits uploads. It will mean having to download the five or so images (all svg) to your computer, and upload from there.


Belay, belay. I have a working version on repl.it that uses images from the CC CDN. No uploads required. It’s still cross domain, though. I wouldn’t count on it always working. But, that’s another thing.

This version is completely refactored and didn’t immediately accept my revised playDoor function, but a tiny revision elsewhere solved that problem.

numClosedDoors = 2

(mind, in my code it’s just, closedDoors). A win in the console would look like this,

 > 
 false
 true
 >

but then so would a loss if the botDoor was clicked on the second try.

By my logic there is no third click.

1 Like

With further retooling we simplify even more…

  const playDoor = door => isBot(door) ? gameOver('') : --closedDoors ? false : gameOver('win');