랜덤 단어 생성 API에서 데이터를 받아와 새로고침 시마다 다른 퍼즐이 나온다.
퍼즐의 알파벳과 키보드의 키값이 일치하면 해당 알파벳으로 바뀌고, 일치하지 않으면 남은 기회의 갯수가 하나씩 줄어든다. 기회가 다 소진되기 전에 퍼즐을 완성하면 완성했다는 문구가 뜬다.
class Hangman {
constructor(word, remainingGuesses) {
this.word = word.toLowerCase().split('')
this.remainingGuesses = remainingGuesses
this.guessedLetters = []
this.status = 'playing'
}
calculateStatus() {
const finished = this.word.every((letter) => this.guessedLetters.includes(letter) || letter === ' ')
if (this.remainingGuesses === 0) {
this.status = 'failed'
// alert(`Nice try! The word Was '${this.word.join('')}'`)
} else if (finished) {
this.status = 'finished'
// alert('Great Work! You Guessed the word.')
} else {
this.status = 'playing'
}
}
get statusMessage() {
if (this.status === 'playing') {
return `Guesses left : ${this.remainingGuesses}`
} else if (this.status === 'failed') {
return `Nice try! The word was '${this.word.join('')}'`
} else if (this.status === 'finished') {
return 'Great Work! You guessed the word.'
}
}
get puzzle() {
let puzzle = ''
this.word.forEach((letter) => {
if (this.guessedLetters.includes(letter) || letter === ' ') {
puzzle += letter
} else {
puzzle += '*'
}
})
return puzzle
}
makeGuess(guess) {
guess = guess.toLowerCase()
const isUnique = !this.guessedLetters.includes(guess)
const isBadGuess = !this.word.includes(guess)
if (this.status !== 'playing') {
//게임이 끝나면 입력을 멈춤
return
}
if (isUnique) {
this.guessedLetters.push(guess)
}
if (isUnique && isBadGuess) {
this.remainingGuesses--
}
this.calculateStatus()
}
}
const getPuzzle = async (wordCount) => {
const response = await fetch(`http://puzzle.mead.io/puzzle?wordCount=${wordCount}`)
if (response.status === 200) {
const data = await response.json()
return data.puzzle
} else {
throw new Error('unable to get puzzle')
}
}
const puzzleEl = document.querySelector('#puzzle')
const guessesEl = document.querySelector('#guesses')
let game1
window.addEventListener('keydown', (e) => {
const guess = e.key
game1.makeGuess(guess)
render()
})
const render = () => {
puzzleEl.innerHTML = ''
guessesEl.textContent = game1.statusMessage
game1.puzzle.split('').forEach((letter) => {
const letterEl = document.createElement('span')
letterEl.textContent = letter
puzzleEl.appendChild(letterEl)
})
}
const startGame = async () => {
const puzzle = await getPuzzle('2')
game1 = new Hangman(puzzle, 5)
render()
}
document.querySelector('#reset').addEventListener('click', startGame)
startGame()