Hangman

View Build

HTML

            
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hangman</title>
    <link rel="stylesheet" href="style.css">
    <script src="script.js" defer></script>
</head>
<body>
    <main>
        <canvas width="300" height="300"></canvas>
        <section class="guesses">
        </section>
        <section class="puzzle"></section>
    </main>
</body>
</html>
            
        

CSS

            
body{
    margin: 0;
    height: 100vh;
    background: black;
    color: white;
    display: flex;
    justify-content: center;
    align-items: center;
}
.guesses{
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 10px;
    width: 300px;
    padding: 10px;
}
.guesses div{
    padding: 10px;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #bbb;
    border-radius: 6px;
    color: #111;
    font-size: 1.3rem;
}
.puzzle{
    border: 1px solid white;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100px;
    font-size: 1.5rem;
}
            
        

JS

            
let guessesElem = document.querySelector(".guesses")
let puzzleElem = document.querySelector(".puzzle")
let canvasElem = document.querySelector("canvas")



let guesses = []
let puzzle = "turkey"
let misses = 0

let ctx = canvasElem.getContext("2d")


function update(letter){
    if(letter){
        if(puzzle.includes(letter)){
            if(guesses.includes(letter)){
                //if letter has already been guessed
                misses++
                miss(misses)
            }
        }
        else{
            //if new guess is not in puzzle
            misses++
            miss(misses)
        }
        //add letter to guesses, multiples allowed
        guesses.push(letter)
    }
    //keep track of what letters to show and hide
    //and keep count of how many letters have been shown
    let temp = ""
    let count = 0
    for(let symbol of puzzle){
        if(guesses.includes(symbol)) {
            //show letter if already guessed
            temp += symbol + "  "
            count ++
        }
        //show square is letter has not been guessed yet
        else temp += "⯀  "
    }
    //show the state of the puzzle
    puzzleElem.innerHTML = temp

    //clear the guesses and add them all back one by one
    guessesElem.innerHTML = ""
    guesses.forEach((guess,index) => {
        let newDiv = document.createElement("div")
        if(guesses.slice(0,index).includes(guess)){
            //if guess is a duplicate, make it red
            newDiv.style.background = "#fa8"   
        }
        //add letter to box and add box to page
        newDiv.innerHTML = guess
        guessesElem.appendChild(newDiv)
    })
    if(misses > 6){
        //if you made 6 failed guess, you lose and inputs disabled
        document.onkeydown = null
        setTimeout(function () {
            let response = confirm("You have lost. Do you want to play again?")
            if(response){
                //if you want to play again, start again
                reset()
            }
        },500)
    }
    else if(count == puzzle.length){
        //you win and have solved the puzzle
        document.onkeydown = null
        setTimeout(function () {
            let response = confirm("You have reveal the puzzle. Do you want to play again?")
            if(response){
                //if you want to play again, start again
                reset()
            }
        },500)
    }
}

const alphabet = "abcdefghijklmnopqrstuvwxyz"

//game inputs
let gameaction = (e) =>{
    if(alphabet.includes(e.key)){
        // if a letter key is pressed, it is a guess
        update(e.key)
    }
}

//turn on the game inputs
document.onkeydown = gameaction



//when a guess fails, draw another body part
function miss(number){
    console.log(number)
    ctx.lineWidth = 3
    switch(number){
        case 1:       
            ctx.beginPath()
            ctx.arc(100,100,30,0,2*Math.PI)
            ctx.strokeStyle = "yellow"
            ctx.stroke()
            break;
        case 2: 
            ctx.beginPath()
            ctx.moveTo(100,130)
            ctx.lineTo(100,180)
            ctx.strokeStyle = "yellow"
            ctx.stroke()
            break;
        case 3: 
            ctx.beginPath()
            ctx.moveTo(100,140)
            ctx.lineTo(60,120)
            ctx.strokeStyle = "yellow"
            ctx.stroke()
            break;
        case 4: 
            ctx.beginPath()
            ctx.moveTo(100,140)
            ctx.lineTo(140,120)
            ctx.strokeStyle = "yellow"
            ctx.stroke()
            break;
        case 5: 
            ctx.beginPath()
            ctx.moveTo(100,180)
            ctx.lineTo(60,200)
            ctx.strokeStyle = "yellow"
            ctx.stroke()
            break;
        case 6: 
            ctx.beginPath()
            ctx.moveTo(100,180)
            ctx.lineTo(140,200)
            ctx.strokeStyle = "yellow"
            ctx.stroke()
            break;
        case 7: 
            ctx.beginPath()
            ctx.moveTo(85,100)
            ctx.lineTo(95,110)
            ctx.moveTo(85,110)
            ctx.lineTo(95,100)
            ctx.moveTo(105,100)
            ctx.lineTo(115,110)
            ctx.moveTo(105,110)
            ctx.lineTo(115,100)
            ctx.strokeStyle = "yellow"
            ctx.stroke()
            break;
        case 8: 
            ctx.beginPath()
            ctx.moveTo(100,180)
            ctx.lineTo(60,200)
            ctx.strokeStyle = "yellow"
            ctx.stroke()
            break;
        case 9: 
            ctx.beginPath()
            ctx.moveTo(100,180)
            ctx.lineTo(60,200)
            ctx.strokeStyle = "yellow"
            ctx.stroke()
            break;
        default:

            break;

    }
}


reset()


function reset(){
    //clear guesses
    guesses = []
    puzzle = ""
    misses = 0
    setTimeout(function (){
        //prompt users for another word
        puzzle = prompt("choose a word").trim()
        //clear image and draw the pole
        ctx.clearRect(0,0,300,300)
        ctx.beginPath()
        ctx.moveTo(10,250)
        ctx.lineTo(50,250)
        ctx.moveTo(30,250)
        ctx.lineTo(30,20)
        ctx.lineTo(100,20)
        ctx.lineTo(100,50)
        ctx.lineWidth = 10
        ctx.strokeStyle = "brown"
        ctx.stroke()
        //draw the noose
        ctx.lineWidth = 4
        ctx.beginPath()
        ctx.moveTo(100,70)
        ctx.lineTo(100,50)
        ctx.strokeStyle = "green"
        ctx.stroke()
        //turn on game inputs
        document.onkeydown = gameaction
        //render the puzzle state and guesses area
        update()
    },1000)
}