Skip to content

Instantly share code, notes, and snippets.

@electricg
Last active December 31, 2015 00:18
Show Gist options
  • Save electricg/7906164 to your computer and use it in GitHub Desktop.
Save electricg/7906164 to your computer and use it in GitHub Desktop.
Hangman game
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hangman</title>
<meta name="author" content="Giulia Alfonsi">
<meta name="description" content="Giulia Alfonsi's Hangman game">
<style>
textarea {
border: 1px solid #999;
font-family: monospace;
font-size: 1.2em;
height: 22em;
width: 100%;
}
input {
border: 1px solid #999;
margin-left: 1em;
}
</style>
</head>
<body>
<script>
var dictionary = [
{
cat: 'colors',
words: ['red', 'green', 'yellow', 'blue', 'white', 'black', 'brown', 'orange', 'purple', 'pink', 'cyan', 'magenta']
},
{
cat: 'fruits',
words: ['apple', 'orange', 'banana', 'pear', 'strawberry', 'cherry', 'pineapple', 'peach', 'pomegranate', 'apricot', 'raspberry', 'watermelon']
},
{
cat: 'flowers',
words: ['rose', 'daisy', 'tulip', 'poppy', 'daffodil', 'bluebell', 'lilly', 'violet', 'narcisuss', 'chrysanthemum', 'carnation']
}
];
var _MAX_ATTEMPTS = 10;
// I couldn't resist from drawing an ASCII hangman
var pictures = [
/*
_________
| / |
|/ |
| @
| /|\
| / \
_|____________
/ | /|
/_____________ //
|______________|/
*/
'\
\n\
\n\
\n\
\n\
\n\
\n\
______________\n\
/ /|\n\
/_____________ //\n\
|______________|/\
',
'\
\n\
|\n\
|\n\
|\n\
|\n\
|\n\
_|____________\n\
/ | /|\n\
/_____________ //\n\
|______________|/\
',
'\
_________\n\
|\n\
|\n\
|\n\
|\n\
|\n\
_|____________\n\
/ | /|\n\
/_____________ //\n\
|______________|/\
',
'\
_________\n\
| /\n\
|/\n\
|\n\
|\n\
|\n\
_|____________\n\
/ | /|\n\
/_____________ //\n\
|______________|/\
',
'\
_________\n\
| / |\n\
|/ |\n\
|\n\
|\n\
|\n\
_|____________\n\
/ | /|\n\
/_____________ //\n\
|______________|/\
',
'\
_________\n\
| / |\n\
|/ |\n\
| @\n\
|\n\
|\n\
_|____________\n\
/ | /|\n\
/_____________ //\n\
|______________|/\
',
'\
_________\n\
| / |\n\
|/ |\n\
| @\n\
| |\n\
|\n\
_|____________\n\
/ | /|\n\
/_____________ //\n\
|______________|/\
',
'\
_________\n\
| / |\n\
|/ |\n\
| @\n\
| /|\n\
|\n\
_|____________\n\
/ | /|\n\
/_____________ //\n\
|______________|/\
',
'\
_________\n\
| / |\n\
|/ |\n\
| @\n\
| /|\\\n\
|\n\
_|____________\n\
/ | /|\n\
/_____________ //\n\
|______________|/\
',
'\
_________\n\
| / |\n\
|/ |\n\
| @\n\
| /|\\\n\
| /\n\
_|____________\n\
/ | /|\n\
/_____________ //\n\
|______________|/\
',
'\
_________\n\
| / |\n\
|/ |\n\
| @\n\
| /|\\\n\
| / \\\n\
_|____________\n\
/ | /|\n\
/_____________ //\n\
|______________|/\
'
];
/**
* Core Hangman game API
*/
var Hangman = function(words) {
var word = '',
result = {},
emptyWord = '',
usedLetters = '',
leftLetters = 'abcdefghijklmnopqrstuvwxyz',
attempts = 0,
end = false;
/**
* Pick word to guess
* @returns {string}
*/
var pickWord = function() {
var len = words.length,
index = Math.floor(Math.random() * len);
return words[index];
};
/**
* Check letter against solution
* @param {string} c - letter to check
* @returns {string} status of the attempt - yes|no
*/
var checkLetter = function(c) {
var status;
if (typeof result[c] === "undefined") {
status = 'no';
}
else {
status = 'yes';
}
return status;
};
/**
* Update current user solution with given letter
* @param {string} c - letter to use
*/
var updateEmptyWord = function(c) {
for (var i = 0; i < result[c].length; i++) {
var index = result[c][i];
emptyWord = emptyWord.substr(0, index) + c + emptyWord.substr(index + 1);
}
};
/**
* Check victory/defeat status
* @returns {string}
*/
this.checkVictory = function() {
var status = '';
if (attempts >= _MAX_ATTEMPTS) {
if (word === emptyWord) {
status = 'victory';
}
else {
status = 'too many attempts';
}
end = true;
}
else {
if (word === emptyWord) {
status = 'victory';
end = true;
}
}
return status;
};
/**
* Return current user solution
* @returns {string}
*/
this.getEmptyWord = function() {
return emptyWord;
};
/**
* Return attempts
* @returns {number}
*/
this.getAttempts = function() {
return attempts;
};
/**
* Return tried letters in attempt order
* @returns {string}
*/
this.getUsedLetters = function() {
return usedLetters;
};
/**
* Return letters yet to try in alphabetic order
* @returns {string}
*/
this.getLeftLetters = function() {
return leftLetters;
};
/**
* Return solution if game is over
* @returns {string}
*/
this.getSolution = function() {
if (end === true) {
return word;
}
else {
return '';
}
};
/**
* Update game with given letter
* @param {string} c - letter to use
* @returns {string} status of the input
*/
this.input = function(c) {
if (end) {
return 'game over';
}
c = c.toString();
if (c.length !== 1) {
return 'only 1 char';
}
c = c.toLowerCase();
if (c.charCodeAt(0) < 97 || c.charCodeAt(0) > 122) {
return 'only alphabet';
}
if (usedLetters.indexOf(c) !== -1) {
return 'letter already used';
}
var status = checkLetter(c);
if (status === 'yes') {
updateEmptyWord(c);
}
else {
attempts++;
}
usedLetters += c;
leftLetters = leftLetters.replace(c, '');
return status;
};
/**
* Start game
*/
this.init = function() {
word = pickWord();
for (var i = 0; i < word.length; i++) {
var w = word[i];
if (typeof result[w] === "undefined") {
result[w] = [];
}
result[w].push(i);
emptyWord += '_';
}
};
};
/**
* Interface
* @param {string} output - 'console' for browser console | 'txt' for textarea
*/
var HangmanGraphic = function(output) {
var h,
word,
len,
att,
attLeft,
prettyWord,
usedLetters,
leftLetters,
cat;
var printOutput,
clearOutput,
par1,
par2,
par3;
if (output === 'txt') {
var fase = 0;
var $txt = document.createElement('textarea'),
$lbl = document.createElement('label'),
$inp = document.createElement('input'),
$btn = document.createElement('input'),
$form = document.createElement('form');
document.body.appendChild($form);
$form.appendChild($txt);
$lbl.innerHTML = 'INPUT:';
$form.appendChild($lbl);
$lbl.appendChild($inp);
$form.appendChild($btn);
$txt.readOnly = true;
$inp.type = 'text';
$btn.type = 'submit';
$btn.value = 'SEND';
Element.prototype.on = Element.prototype.addEventListener;
var prev = function(event) {
if (event.preventDefault) { event.preventDefault(); }
else { event.returnValue = false; }
};
$form.on('submit', function(event) {
prev(event);
if (fase === 0) {
if ($inp.value.toLowerCase() === 'start') {
fase++;
$inp.value = '';
window.start();
}
}
else if (fase === 1) {
window.cat($inp.value);
}
else if (fase === 2) {
window.use($inp.value);
}
});
printOutput = function(o) {
$txt.value += o + '\n';
};
clearOutput = function() {
$txt.value = '';
};
par1 = 'THE number';
par2 = 'THE letter';
par3 = '';
}
else if (output === 'console') {
printOutput = function() {
return console.info.apply( console, arguments );
};
clearOutput = function() {
return console.clear.apply( console, arguments );
};
par1 = 'cat(number)';
par2 = 'use("letter")';
par3 = '()';
}
else {
return;
}
var printWord = function() {
return word.split('').join(' ');
};
window.start = function() {
clearOutput();
printOutput('===> GAME START');
printOutput('===> CHOOSE ONE OF THE FOLLOWING CATEGORIES:');
for (var i =0; i < dictionary.length; i++) {
printOutput('===> ' + (i + 1) + ' - ' + dictionary[i].cat);
}
printOutput('===> TYPE ' + par1 + ' TO SELECT IT');
};
window.cat = function(n) {
n = Math.floor(n);
if (isNaN(n) || n < 1 || n > dictionary.length) {
printOutput('===> PLEASE ENTER A VALID NUMBER');
return;
}
clearOutput();
n = n - 1;
cat = dictionary[n].cat;
h = new Hangman(dictionary[n].words);
h.init();
word = h.getEmptyWord();
len = word.length;
att = h.getAttempts();
attLeft = _MAX_ATTEMPTS - att;
prettyWord = printWord();
printOutput('===> YOU HAVE SELECTED "' + cat + '"');
printOutput('===> TYPE ' + par2);
printOutput('===> THE WORD IS: ' + prettyWord + ' (' + len + ' LETTERS) - ' + attLeft + ' ATTEMPTS LEFT');
printOutput(pictures[att]);
if (output === 'txt') {
fase++;
$inp.value = '';
}
};
window.use = function(c) {
var status = h.input(c),
status2 = h.checkVictory(),
msg,
msg2;
word = h.getEmptyWord();
att = h.getAttempts();
attLeft = _MAX_ATTEMPTS - att;
prettyWord = printWord();
usedLetters = h.getUsedLetters();
leftLetters = h.getLeftLetters();
switch(status) {
case 'yes':
msg = '===> GOOD JOB - LETTER FOUND!';
break;
case 'no':
msg = '===> I AM SORRY - LETTER NOT FOUND!';
break;
case 'game over':
msg = '===> GAME OVER';
break;
case 'only 1 char':
msg = '===> ONLY ONE LETTER ALLOWED';
break;
case 'letter already used':
msg = '===> LETTER ALREADY USED';
break;
case 'only alphabet':
msg = '===> ONLY ALPHABETIC LETTERS ARE ALLOWED';
break;
}
switch(status2) {
case 'victory':
msg2 = '===> CONGRATULATIONS! YOU WON!';
break;
case 'too many attempts':
msg2 = '===> I AM SORRY - NO ATTEMPTS LEFT\n===> GAME OVER';
word = h.getSolution();
prettyWord = printWord();
break;
default:
msg2 = '';
break;
}
if (output === 'txt') {
$inp.value = '';
}
clearOutput();
printOutput(msg);
if (msg2 !== '') {
printOutput(msg2);
}
printOutput('===> THE WORD IS: ' + prettyWord + ' (' + len + ' LETTERS) - ' + attLeft + ' ATTEMPTS LEFT - CATEGORY: ' + cat);
printOutput('===> LETTERS USED: ' + usedLetters);
printOutput('===> LETTERS LEFT: ' + leftLetters);
printOutput(pictures[att]);
};
printOutput('===> WELCOME TO HANGMAN');
printOutput('===> TO START, TYPE start' + par3);
};
var hangmanGraphic = new HangmanGraphic('txt');
</script>
</body>
</html>
@electricg
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment