35 - Hangman Project added · Ndblaze/30DaysOfJavaScript@f858c50 · GitHub
Skip to content

Commit f858c50

Browse files
35 - Hangman Project added
1 parent 07005ad commit f858c50

7 files changed

Lines changed: 216 additions & 0 deletions

File tree

‎30DaysOfJavaScript/assets/35.png‎

49.7 KB
Loading

‎35 - Hangman/index.html‎

Lines changed: 21 additions & 0 deletions

‎35 - Hangman/scripts/app.js‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
let game1
2+
const puzzleDIV = document.querySelector('#puzzle');
3+
const remainingDIV = document.querySelector('#guesses');
4+
5+
window.addEventListener('keypress', (e) => {
6+
7+
const guess = String.fromCharCode(e.charCode);
8+
game1.makeGuess(guess);
9+
render()
10+
})
11+
12+
const render = () => {
13+
puzzleDIV.innerHTML = ''
14+
remainingDIV.textContent = game1.statusMessage;
15+
16+
game1.puzzle.split('').forEach((letter) => {
17+
const letterEl = document.createElement('span')
18+
letterEl.textContent = letter
19+
puzzleDIV.appendChild(letterEl)
20+
})
21+
}
22+
23+
const startGame = async () => {
24+
const puzzle = await getPuzzle('3')
25+
game1 = new Hangman(puzzle, 5)
26+
render()
27+
}
28+
29+
document.querySelector('#reset').addEventListener('click', startGame)
30+
startGame()

‎35 - Hangman/scripts/hangman.js‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
class Hangman {
2+
constructor(word, remainingGuesses){
3+
this.word = word.toLowerCase().split('');
4+
this.remainingGuesses = remainingGuesses;
5+
this.guessedLetters = [];
6+
this.status = 'playing';
7+
}
8+
9+
get puzzle() {
10+
let puzzle = '';
11+
this.word.forEach((letter) => {
12+
if (this.guessedLetters.includes(letter) || letter === ' '){
13+
puzzle += letter;
14+
} else {
15+
puzzle += '*'
16+
}
17+
})
18+
return puzzle;
19+
}
20+
21+
makeGuess (guess){
22+
guess = guess.toLowerCase();
23+
const isUnique = !this.guessedLetters.includes(guess);
24+
const isBadGuess = !this.word.includes(guess);
25+
26+
if (this.status !== 'playing'){
27+
return
28+
}
29+
30+
if (isUnique){
31+
this.guessedLetters.push(guess)
32+
}
33+
34+
if (isUnique && isBadGuess){
35+
this.remainingGuesses--
36+
}
37+
this.calculateStatus();
38+
}
39+
40+
get statusMessage(){
41+
if (this.status === 'playing'){
42+
return `Guesses left: ${this.remainingGuesses}`
43+
} else if (this.status === 'failed') {
44+
return `Nice try! The word was "${this.word.join('')}" `
45+
} else {
46+
return 'Great work! You guessed the word right!'
47+
}
48+
}
49+
50+
calculateStatus(){
51+
const finished = this.word.every((letter) => this.guessedLetters.includes(letter) || letter === ' ')
52+
53+
if (this.remainingGuesses === 0){
54+
this.status = 'failed'
55+
} else if (finished){
56+
this.status = 'finished'
57+
} else {
58+
this.status = 'playing'
59+
}
60+
}
61+
62+
}
63+
64+
65+
66+

‎35 - Hangman/scripts/request.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const getPuzzle = async (wordCount) => {
2+
const response = await fetch(`https://puzzle.mead.io/puzzle?wordCount=${wordCount}`)
3+
if (response.status === 200){
4+
const data = await response.json()
5+
return data.puzzle
6+
} else {
7+
throw new Error('Unable to fetch puzzle')
8+
}
9+
}
10+

‎35 - Hangman/styles.css‎

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
* {
2+
box-sizing: border-box;
3+
margin: 0;
4+
padding: 0;
5+
}
6+
7+
html {
8+
font-size: 62.5%;
9+
}
10+
11+
#main{
12+
margin-top: 100px;
13+
}
14+
15+
body {
16+
background: #19172e;
17+
color: #fafafa;
18+
font-family: Helvetica, Arial, sans-serif;
19+
font-size: 1.6rem;
20+
display: flex;
21+
justify-content: center;
22+
min-height: 100vh;
23+
text-align: center;
24+
}
25+
26+
span {
27+
border-bottom: 1px solid #534f59;
28+
display: inline-block;
29+
font-size: 2rem;
30+
height: 2.4rem;
31+
line-height: 2.4rem;
32+
margin: 0 .1rem;
33+
text-align: center;
34+
text-transform: uppercase;
35+
width: 2.4rem;
36+
}
37+
38+
h1{
39+
color: #976dc4;
40+
font-weight: 600;
41+
font-size: 4rem;
42+
}
43+
44+
.desc{
45+
word-wrap: break-word;
46+
max-width: 600px;
47+
margin: 20px auto;
48+
text-align: center;
49+
font-size: 1.7rem;
50+
line-height: 1.5;
51+
}
52+
53+
p {
54+
font-weight: 300;
55+
margin-bottom: .8rem;
56+
}
57+
58+
.puzzle {
59+
display: flex;
60+
margin-bottom: 4.8rem;
61+
}
62+
63+
.puzzle-box{
64+
margin-top: 150px;
65+
text-align: center;
66+
}
67+
68+
.button {
69+
background: #7044a0;
70+
border: none;
71+
border-bottom: 2px solid #603a88;
72+
cursor: pointer;
73+
color: white;
74+
font-size: 1.4rem;
75+
font-weight: 300;
76+
padding: .8rem;
77+
transition: background .3s ease, color .3s ease;
78+
}
79+
80+
.button:hover {
81+
background: #5F3A87;
82+
}

‎index.html‎

Lines changed: 7 additions & 0 deletions

0 commit comments

Comments
 (0)