Last active
February 27, 2018 03:42
-
-
Save dsoverby1986/aaecccf76375cb03ebfffbb1a759011c to your computer and use it in GitHub Desktop.
My JavaScript/jQuery for Edford's random number crystal guessing game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
I've wrapped the calls to setRandomNumber() and setCrystalValues() in the window ready function so that | |
so that they won't be called until the page has completely loaded all elements. I am doing this to because | |
both of these functions work with DOM elements and I want to make sure that the elements exist before trying | |
to access them. | |
Also, have included a jQuery click event handler in the window ready function so that it's bound to the button image | |
elements only after they are loaded in the DOM. | |
*/ | |
$(function(){ | |
setRandomNumber(); | |
setCrystalValues(); | |
//Here, I am using the jQuery "starts-with" attribute selector (^=) | |
//This selector says, "select all elements that have an 'id' attribute with a value that starts with 'button' | |
//This way I am able to bind this click event hanlder to all of the elements whose 'id' attribute start with 'button': | |
//button1, button2, button3, button4 | |
//Very handy since I want to have the click event handled in the same way for all of these elements | |
//Another way to have done this would be to add a class to all of these elements and just use the class selector: | |
//$('.crystal-button').click(...); | |
//I could also have used the 'id' attribute values for each of the elements, though it's a bit wordy: | |
//$('#button1, #button2, #button3, #button4').click(...); | |
$('[id^="button"]').click(function(){ | |
//When any of the crystal image button elements is clicked, call the handleCrystalClick() function | |
//and pass to it the jQuery object returned from the selector $(this). $(this) in the scope of this click event handler | |
//represents the button that was clicked. | |
handleCrystalClick($(this)); | |
}); | |
}); | |
//I've declared and initialized these variables in the global scope to make them accessible by multiple functions below | |
var randomNumber = 0; | |
var currentGuess = 0; | |
var wins = 0; | |
var losses = 0; | |
//The multiple functions below exist in the global scope as well, but access to these functions is initiated through | |
//their calling from the window ready function above, or the button click event handler above, which is contained within | |
//the window ready function, itself. | |
//Created the setRandomNumber function to adhere to DRY design, since this functionality is necessary in more than one instance | |
function setRandomNumber() { | |
randomNumber = Math.floor(Math.random() * 101) + 19; | |
$('#randomNumber').html(randomNumber); | |
} | |
//Created the setCrystalValues function to adhere to DRY design, since this functionality is necessary in more than one instance | |
function setCrystalValues() { | |
//Again, using the "starts-with" selector here to select all of the elements having an 'id' attribute value that starts with 'button' | |
var buttons = $('[id^="button"]'); | |
//Using the jQuery .each() method, I am looping through the collection of button elements, accessing the 'data-value' attribute of | |
//each element (I added the 'data-value' attribute to each of these elementing in the index.html file) and assigning the random | |
//result of the calculation below to their 'data-value' attribute. This is just to bind the random number to its respective button | |
//element, so that it may be accessed later when it's needed. | |
$.each(buttons, function(i, button){ | |
$('#' + button.id).data().value = Math.floor(Math.random() * 12) + 1; | |
}); | |
} | |
//The executable code within the handleCrystalClick function below could have just as properly been a part of the buttons' click | |
//event handler above, but for the sake of clarity I decided to refactor it into it's own function. This is a fairly common thing | |
//to see with event handlers; keeping them lean and refactoring the executable logic into it's own function. | |
//The handleCrystalClick function takes the jQuery object passed to it from the click event handler, representing the button that | |
//was clicked. | |
function handleCrystalClick($this) { | |
//I am passing the representation of the clicked button to this function so that I may access it's 'data-value' attribute, as | |
//below, to use the value of that attribute to increment the currentGuess variable's value, | |
var value = $this.data().value; | |
currentGuess += value; | |
//Update the rendered currentGuess value | |
$('.currentGuess').html(currentGuess); | |
//Call the evaluate() function to check whether or not the user has won or lost at this point | |
evaluate(); | |
} | |
//The evaluate() function is only called from one place in this codebase, and could have been included in the | |
//handleCrystalClick function, but I prefer to keep functions fairly lean and not bloat them with multiple | |
//responsibilities. | |
function evaluate() { | |
if(currentGuess === randomNumber) { | |
$('.wins').html(++wins); | |
resetCurrentGuess(); | |
} else if (currentGuess > randomNumber) { | |
$('.losses').html(++losses); | |
resetCurrentGuess(); | |
} | |
} | |
//The name of this function, to me, can seem a little ambiguous, since this function does more than resets the currentGuess values here | |
//and in the page, but, also, it makes sense to me that when the currentGuess values are reset, obviously a new random target number is | |
//required and, as you said about your requirements, new random number are needed for the crystal button. | |
function resetCurrentGuess() { | |
currentGuess = 0; | |
$('.currentGuess').html(''); | |
setRandomNumber(); | |
setCrystalValues(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment