Created
December 5, 2014 02:53
-
-
Save mrdrozdov/7a4a5946e37538a6411b to your computer and use it in GitHub Desktop.
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
<body> | |
<div>Try to guess a correct letter</div> | |
<div id="incomplete-word"></div> | |
<div> | |
<input id="letter-guess"></input> | |
</div> | |
<div>Letters Left: <span id="possible-letters"></span> | |
</div> | |
<div>Guesses Left: <span id="guesses-left"></span> | |
</div> | |
</body> | |
<script> | |
// CSS Constants | |
var cssIncompleteWord = 'incomplete-word'; | |
var cssGuessesLeft = 'guesses-left'; | |
var cssLetterInput = 'letter-guess'; | |
var cssPossibleLetters = 'possible-letters'; | |
// Configuration | |
var validLetters = 'abcdefghijklmnopqrstuvwxyz'; | |
var lettersToRemove = 3; | |
var maxGuesses = 5; | |
var loseMessage = 'So sorry. Try better next time, okey dokey? ^_^'; | |
var winMessage = 'Ta da! You da best! (>\'\')> *@*'; | |
var emptyChar = '_'; | |
var possibleWords = [ | |
'i have the goosebumps', | |
'up up and away', | |
'hunter thompson']; | |
// Globals | |
var wordToGuessIndex; | |
var wordToGuess; | |
var currentWord; | |
var guessesLeft; | |
var lettersLeft; | |
// Event Handlers | |
document.getElementById(cssLetterInput).onkeypress = function (e) { | |
if (!e) e = window.event; | |
var keyCode = e.keyCode || e.which; | |
var prevValue = getLetterInput(); | |
if (keyCode == '13') { | |
playRound(prevValue); | |
} else if (keyCode == '8') { | |
// backspace | |
} else if (letterAvailable(lettersLeft, keyCode) && prevValue.length === 0) { | |
// normal input | |
} else { | |
e.preventDefault(); | |
} | |
} | |
// Initialization | |
playGame(); | |
// Game Functions | |
function letterAvailable(letters, keyCode) { | |
if (!(keyCode >= 97 && keyCode <= 122)) { | |
return false; | |
} | |
var c = String.fromCharCode(keyCode).toLowerCase(); | |
var i; | |
for (i = 0; i < letters.length; i++) { | |
if (letters.charAt(i) === c) { | |
return true; | |
} | |
} | |
return false; | |
} | |
function prepareWord(word, lettersToRemove) { | |
var letters = validLetters.substr(0); | |
var lettersRemoved = 0; | |
var i; | |
while (lettersRemoved < lettersToRemove) { | |
var randLetterIndex = randomIntInRange(0, letters.length - 1); | |
var randLetter = letters[randLetterIndex]; | |
var indexesInWord = getIndexesOfChar(wordToGuess, randLetter); | |
if (indexesInWord.length > 0) { | |
for (i = 0; i < indexesInWord.length; i++) { | |
word = stringByReplacingCharAtIndex( | |
word, indexesInWord[i], emptyChar); | |
} | |
lettersRemoved++; | |
} | |
letters = stringByRemovingCharAtIndex(letters, randLetterIndex); | |
} | |
for (i = 0; i < word.length; i++) { | |
if (word.charAt(i) !== emptyChar) { | |
lettersLeft = lettersLeft.replace(word.charAt(i), ''); | |
} | |
} | |
return word; | |
} | |
function guessLetter(expectedWord, currentWord, letter) { | |
var i; | |
var success = -1; | |
for (i = 0; i < expectedWord.length; i++) { | |
if (expectedWord.charAt(i) === letter && currentWord.charAt(i) !== letter) { | |
currentWord = stringByReplacingCharAtIndex( | |
currentWord, i, letter); | |
success++; | |
} | |
} | |
return { | |
word: currentWord, | |
success: success | |
}; | |
} | |
function playRound(prevValue) { | |
if (prevValue.length === 1) { | |
var guessLetterResults = guessLetter( | |
wordToGuess, currentWord, prevValue); | |
if (guessLetterResults.success >= 0) { | |
currentWord = guessLetterResults.word; | |
if (currentWord === wordToGuess) { | |
alert(winMessage); | |
return playGame(); | |
} | |
} else { | |
setGuessesLeft(--guessesLeft); | |
if (guessesLeft < 1) { | |
alert(loseMessage); | |
return playGame(); | |
} | |
} | |
lettersLeft = stringByRemovingCharAtIndex( | |
lettersLeft, lettersLeft.indexOf(prevValue)); | |
} | |
updateUI(); | |
} | |
function playGame() { | |
guessesLeft = maxGuesses; | |
lettersLeft = validLetters.substr(0); | |
wordToGuessIndex = randomIntInRange(0, possibleWords.length - 1); | |
wordToGuess = possibleWords[wordToGuessIndex]; | |
currentWord = prepareWord(wordToGuess, lettersToRemove); | |
updateUI(); | |
} | |
// Utility | |
function randomIntInRange(min, max) { | |
return Math.floor(Math.random() * (max - min + 1)) + min; | |
} | |
function stringByRemovingCharAtIndex(str, idx) { | |
return str.substr(0, idx) + str.substr(idx + 1); | |
} | |
function stringByReplacingCharAtIndex(str, idx, replacement) { | |
return str.substr(0, idx) + replacement + str.substr(idx + 1); | |
} | |
function getIndexesOfChar(str, c) { | |
var results = []; | |
var i; | |
for (i = 0; i < str.length; i++) { | |
if (str.charAt(i) === c) { | |
results.push(i); | |
} | |
} | |
return results; | |
} | |
// UI | |
function updateUI() { | |
setLetterInput(''); | |
setIncompleteWord(currentWord); | |
setPossibleLetters(lettersLeft); | |
setGuessesLeft(guessesLeft); | |
} | |
// Access the DOM | |
function getLetterInput() { | |
return document.getElementById(cssLetterInput).value; | |
} | |
function setLetterInput(val) { | |
document.getElementById(cssLetterInput).value = val; | |
} | |
function getIncompleteWord() { | |
return document.getElementById(cssIncompleteWord).innerHTML; | |
} | |
function setIncompleteWord(content) { | |
document.getElementById(cssIncompleteWord).innerHTML = content; | |
} | |
function setPossibleLetters(content) { | |
document.getElementById(cssPossibleLetters).innerHTML = content; | |
} | |
function setGuessesLeft(content) { | |
document.getElementById(cssGuessesLeft).innerHTML = content; | |
} | |
/* | |
Just a note, I prefer using one var statement per line, and am extremely | |
opposed to Yoda Style commas (in production code). The reasoning is that | |
Yoda Style commas are harder to lint for (JSHint no longer enforces this | |
rule). Also, it's been observed that TJ Holowaychuk at one point switched | |
from Yoda Style to the one var per line style. | |
*/ | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment