-
Notifications
You must be signed in to change notification settings - Fork 357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Guess who game #335
base: main
Are you sure you want to change the base?
Guess who game #335
Changes from all commits
0022587
7799429
2a684ed
6c86cbe
77fdb6c
cab52cb
347ef3d
a7e2907
88fe915
50a2850
a63bc30
9d85399
9c0a791
58062bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,11 @@ | ||
# Project Name | ||
|
||
Replace this readme with your own information about your project. | ||
|
||
Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. | ||
A 'guess who' game that filters the cards based on user selection. The game selects a new "secret person" every time new board is loaded and you win by correctly guessing who it is. | ||
|
||
## The problem | ||
|
||
Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? | ||
The problem for me was to understand categories, values and parameters in the objects. I had to rely on coursemates code to debug and get it working (almost completely). At the time of submission the there is no working Timer-reset function when game is restarted (only on page refresh). | ||
|
||
## View it live | ||
https://mellifluous-smakager-f98424.netlify.app/ | ||
|
||
Have you deployed your project somewhere? Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,56 @@ | ||
// All the DOM selectors stored as short variables | ||
const board = document.getElementById('board') | ||
const questions = document.getElementById('questions') | ||
const restartButton = document.getElementById('restart') | ||
|
||
const board = document.getElementById('board') //board is the id of the div in html file where the cards are displayed | ||
|
||
const questions = document.getElementById('questions') //questions is the id of the select element in html file | ||
|
||
const restartButton = document.getElementById('restart') //restart is the id of the button element in html file | ||
|
||
const resultScreen = document.getElementById('winOrLoseSection') //winOrLoseSection is the id of the section element in html file | ||
|
||
const resultText= document.getElementById('winOrLoseText') //winOrLoseText is the id of the p element in html file | ||
|
||
const playAgainButton = document.getElementById('playAgain') //playAgain is the id of the button element in html file | ||
|
||
const findOutButton = document.getElementById('filter') //filter is the id of the button element in html file | ||
|
||
//declaring a clock counter for the website, it starts at 2 minutes and counts down to 0 | ||
// In minute format, sarting at 02:00 | ||
let time = 120 | ||
|
||
|
||
|
||
|
||
// Function to format the time as "MM:SS" | ||
function formatTime(seconds) { | ||
const minutes = Math.floor(seconds / 60); | ||
const remainingSeconds = seconds % 60; | ||
return `${String(minutes).padStart(2, '0')}:${String(remainingSeconds).padStart(2, '0')}`; | ||
} | ||
/* This code will display the initial time as "02:00" and then count down in the "MM:SS" format until it reaches "00:00". When it reaches "00:00", you can add your logic to handle the end of the timer. | ||
*/ | ||
|
||
// When timer starts, display the starting time | ||
|
||
document.getElementById("timer").innerHTML = formatTime(time) | ||
let timer = setInterval(function() { | ||
time--; // decrease time by 1 | ||
if (time <= 0) { | ||
clearInterval(timer) | ||
alert("You lost! The correct person was " + secret.name + "."); | ||
winOrLose.style.display = 'flex'; | ||
board.style.display = 'none'; | ||
winOrLoseText.innerHTML = `You lost! The correct person was ${secret.name}.` | ||
} | ||
document.getElementById("timer").innerHTML = formatTime(time); | ||
// update the element where the timer will be displayed | ||
}, 1000)//1000ms = 1s | ||
|
||
|
||
|
||
|
||
// Array with all the characters, as objects | ||
const CHARACTERS = [ | ||
const CHARACTERS = [ | ||
{ | ||
name: 'Jabala', | ||
img: 'images/jabala.svg', | ||
|
@@ -199,11 +245,13 @@ const CHARACTERS = [ | |
other: [] | ||
}, | ||
] | ||
|
||
// Global variables | ||
let secret | ||
let currentQuestion | ||
let charactersInPlay | ||
let secret // The current secret person | ||
let keep // The current keep value for filtering | ||
let currentQuestion // The current question in play | ||
let charactersInPlay// charactersInPlay is an array of objects | ||
|
||
|
||
// Draw the game board | ||
const generateBoard = () => { | ||
|
@@ -221,105 +269,174 @@ const generateBoard = () => { | |
` | ||
}) | ||
} | ||
|
||
// Randomly select a person from the characters array and set as the value of the variable called secret | ||
const setSecret = () => { | ||
secret = charactersInPlay[Math.floor(Math.random() * charactersInPlay.length)] | ||
console.log(secret); | ||
} | ||
|
||
// This function to start (and restart) the game | ||
/// This function to start (and restart) the game | ||
const start = () => { | ||
// Here we're setting charactersInPlay array to be all the characters to start with | ||
charactersInPlay = CHARACTERS | ||
board.style.display = 'flex' | ||
winOrLose.style.display = 'none' | ||
// What else should happen when we start the game? | ||
//Game board should be rendered on the screen | ||
generateBoard(); | ||
setSecret(); | ||
//startTimer(); // can't get this to work together with findout dropdown filter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could be helpful to console log when the start function is being called, as it is easier to spot errors in restart / play again |
||
} | ||
|
||
// setting the currentQuestion object when you select something in the dropdown | ||
const selectQuestion = () => { | ||
const category = questions.options[questions.selectedIndex].parentNode.label | ||
|
||
// This variable stores what option group (category) the question belongs to. | ||
// We also need a variable that stores the actual value of the question we've selected. | ||
// const value = | ||
const value = questions.options[questions.selectedIndex].value | ||
|
||
currentQuestion = { | ||
category: category, | ||
// value: value | ||
value: value | ||
} | ||
console.log(currentQuestion); | ||
} | ||
|
||
// This function should be invoked when you click on 'Find Out' button. | ||
const checkQuestion = () => { | ||
const { category, value } = currentQuestion | ||
const { category, value } = currentQuestion // MISSING PIECE THAT FINALLY MADE THE FILTER WORK..currentQuestion is an object with two properties: category and value. Declaring these two variables and assigning them to the properties of currentQuestion object makes it possible to use them in the if statement below. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found this complicated, you explain it well here |
||
|
||
// Compare the currentQuestion details with the secret person details in a different manner based on category (hair/eyes or accessories/others). | ||
// See if we should keep or remove people based on that | ||
// Then invoke filterCharacters | ||
if (category === 'hair' || category === 'eyes') { | ||
if (secret[category].includes(value)) { | ||
filterCharacters(true) | ||
//(value === secret[category]) { | ||
// filterCharacters(true) | ||
console.log("keep") | ||
} else | ||
filterCharacters(false) | ||
console.log("remove") | ||
|
||
} else if (category === 'accessories' || category === 'other') { | ||
|
||
if (secret[category].includes(value)) { | ||
filterCharacters(true) | ||
console.log("keep") | ||
} else | ||
filterCharacters(false) | ||
console.log("remove") | ||
} | ||
} | ||
|
||
// It'll filter the characters array and redraw the game board. | ||
// Determine what is the category | ||
// filter by category to keep or remove based on the keep variable. | ||
const filterCharacters = (keep) => { | ||
const { category, value } = currentQuestion | ||
// Show the correct alert message for different categories | ||
if (category === 'accessories') { | ||
if (keep) { | ||
alert( | ||
`Yes, the person wears ${value}! Keep all people that wears ${value}` | ||
`Yes, the person wears ${value}! Keep all people that wear ${value}.` | ||
) | ||
//filter out people from the charactersInPlay array using the filter method | ||
charactersInPlay = charactersInPlay.filter((person) => person[category].includes(value)) | ||
} else { | ||
alert( | ||
`No, the person doesn't wear ${value}! Remove all people that wears ${value}` | ||
`No, the person doesn't wear ${value}! Remove all people that wear ${value}.` | ||
) | ||
charactersInPlay = charactersInPlay.filter((person) => !person[category].includes(value)) | ||
} | ||
} else if (category === 'other') { | ||
// Similar to the one above | ||
if (keep) { | ||
alert( | ||
`Yes, the person has a ${value}! Keep all people that have a ${value}.` | ||
) | ||
charactersInPlay = charactersInPlay.filter((person) => person[category].includes(value)) | ||
} else { | ||
alert( | ||
`No, the person doesn't have a ${value}! Remove all people that have a ${value}.` | ||
) | ||
charactersInPlay = charactersInPlay.filter((person) => !person[category].includes(value)) | ||
} | ||
} else if (category === 'eyes') { | ||
// Similar to the one above | ||
if (keep) { | ||
alert( | ||
`Yes, the person has ${value} eyes! Keep all people that have ${value} eyes.` | ||
) | ||
charactersInPlay = charactersInPlay.filter((person) => person[category] === value) | ||
} else { | ||
alert( | ||
`No, the person doesn't have ${value} eyes! Remove all people that have ${value} eyes.` | ||
) | ||
charactersInPlay = charactersInPlay.filter((person) => person[category] !== value) | ||
} | ||
} else { | ||
if (keep) { | ||
// alert popup that says something like: "Yes, the person has yellow hair! Keep all people with yellow hair" | ||
alert( | ||
`Yes, the person has ${value} hair! Keep all people that have ${value} hair.` | ||
) | ||
charactersInPlay = charactersInPlay.filter((person) => person[category] === value) | ||
Comment on lines
+380
to
+382
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From playing your game a few times, it looks like you did the filtering correctly. However, the values could be paid more attention to. None of the caracters match the value red hair, while there is no value for hidden hair or orange and purple hair. This makes it harder to filter away the wrong options. |
||
} else { | ||
// alert popup that says something like: "No, the person doesnt have yellow hair! Remove all people with yellow hair" | ||
alert( | ||
`No, the person doesn't have ${value} hair! Remove all people that have ${value} hair.` | ||
) | ||
charactersInPlay = charactersInPlay.filter((person) => person[category] !== value) | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stenli left this comment for me - I found it useful as I used the same approach as you, so passing it on: like the following : const filterCharacters = (keep) => { if (category === 'accessories') { if (keep) { |
||
|
||
// Determine what is the category | ||
// filter by category to keep or remove based on the keep variable. | ||
/* | ||
for hair and eyes : | ||
charactersInPlay = charactersInPlay.filter((person) => person[attribute] === value) | ||
or | ||
charactersInPlay = charactersInPlay.filter((person) => person[attribute] !== value) | ||
|
||
for accessories and other | ||
charactersInPlay = charactersInPlay.filter((person) => person[category].includes(value)) | ||
or | ||
charactersInPlay = charactersInPlay.filter((person) => !person[category].includes(value)) | ||
*/ | ||
|
||
// Invoke a function to redraw the board with the remaining people. | ||
generateBoard() | ||
} | ||
|
||
// when clicking guess, the player first have to confirm that they want to make a guess. | ||
// when clicking guess, the player first has to confirm that they want to make a guess. | ||
const guess = (personToConfirm) => { | ||
// store the interaction from the player in a variable. | ||
// remember the confirm() ? | ||
const confirmation = confirm(`Are you sure you want to guess ${personToConfirm}?`) | ||
// If the player wants to guess, invoke the checkMyGuess function. | ||
if (confirmation === true) { | ||
checkMyGuess(personToConfirm) | ||
} | ||
} | ||
|
||
// If you confirm, this function is invoked | ||
const checkMyGuess = (personToCheck) => { | ||
// 1. Check if the personToCheck is the same as the secret person's name | ||
// 2. Set a Message to show in the win or lose section accordingly | ||
// 3. Show the win or lose section | ||
winOrLose.style.display = 'flex'; | ||
// 4. Hide the game board | ||
board.style.display = 'none'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you need both of these? I think display flex should overwrite the board |
||
// 2. Set a Message to show in the win or lose section accordingly | ||
if (secret.name === personToCheck) { | ||
winOrLoseText.innerHTML = `You guessed right! Congratulations, you are a winner!` | ||
} else { | ||
winOrLoseText.innerHTML = `You lost! The correct person was ${secret.name}.` | ||
} | ||
} | ||
|
||
// Invokes the start function when website is loaded | ||
start() | ||
|
||
// Show the correct alert message for different categories | ||
alert(`You have ${charactersInPlay.length} characters left.`) | ||
|
||
// All the event listeners | ||
restartButton.addEventListener('click', start) | ||
|
||
questions.addEventListener('change', selectQuestion) | ||
|
||
findOutButton.addEventListener('click', checkQuestion) | ||
|
||
playAgainButton.addEventListener('click', start) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see you mentioned some of this in your readme - the play again (after guessing) and the restart (while playting) buttons work well (you have the event listeners set up), however the game does not reset. The scroll down menu should go back to "please choose an option" and timer should start. The secret person does change however. Perhaps the end of my code can help you here - notice the start function being called once more: //Restart game |
||
|
||
|
||
|
||
|
||
// 1. Check if the personToCheck is the same as the secret person's name | ||
//secret.name is the name of the secret person | ||
// 2. Set a Message to show in the win or lose section accordingly | ||
// 3. Show the win or lose section | ||
// 4. Hide the game board |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the timer function, as I did not do that myself! Made the page more alive and interactive. Stressed me out through ;)