words/game.js

216 lines
6.8 KiB
JavaScript

// global constants
const gridWidth = 5
const gridHeight = 6
const word = wordlist.valid_answers[Math.floor(Math.random()*wordlist.valid_answers.length)];
// global state variables
var gameCompleted = null
// HTML items
const body = document.getElementsByTagName("body")[0]
const endScreen = document.getElementById("end_screen")
const endScreenGuesses = document.getElementById("end_screen_guesses")
const endScreenMessage = document.getElementById("end_screen_message")
const endScreenImage = document.getElementById("end_screen_image")
const endScreenTime = document.getElementById("end_screen_time")
const gameContainer = document.getElementById("game_container")
const gridItems = []
const kbLetters = Array.from(document.getElementsByClassName("kb_letter")).filter(kbl => kbl.id === '')
const kbEnter = document.getElementById("kb_enter")
const kbBackspace = document.getElementById("kb_backspace")
// helper functions
const gridItemId = (row, column) => "grid_item_" + row + "_" + column
const getGridRow = (row) => gridItems[row]
const getGridItem = (row, column) => gridItems[row].items[column]
const getkbLetter = letter => kbLetters.filter(kbl => kbl.innerHTML.toLowerCase() === letter.toLowerCase())[0]
const isLetter = string => /^[a-zA-Z]$/.test(string)
function setGridLetter(row, column, letter) {
console.log([row, column])
console.log(letter)
getGridItem(row, column).letter = letter
getGridItem(row, column).HTMLItem.getElementsByClassName("grid_item_p")[0].innerHTML = letter !== null ? letter : ""
}
function checkGridRow() {
var [row, _ ] = findCurrentLetterPosition()
var rowWord = ''
getGridRow(row).items.forEach(item => rowWord += item.letter)
console.log(rowWord)
if (!wordlist.valid_inputs.includes(rowWord)) {
getGridRow(row).items.forEach(item => {
item.HTMLItem.classList.add("incorrect")
setTimeout( () => item.HTMLItem.classList.remove("incorrect"), 500)
})
return
}
var correct_letters = 0
var dedupword = word
for (var column = 0; column < gridWidth; column++) {
gridItem = getGridItem(row, column)
// letters are removed from dedupword as letters are matched
if (gridItem.letter === null) return
if (gridItem.letter === word[column]) {
gridItem.HTMLItem.classList.add('grid_correct')
getkbLetter(gridItem.letter).classList.add('kb_letter_correct_discovered')
correct_letters += 1
} else if (dedupword.includes(gridItem.letter)) {
gridItem.HTMLItem.classList.add('grid_present')
getkbLetter(gridItem.letter).classList.add('kb_letter_present_discovered')
} else {
gridItem.HTMLItem.classList.add('grid_wrong')
getkbLetter(gridItem.letter).classList.add('kb_letter_incorrect_discovered')
}
dedupword = dedupword.replace(gridItem.letter, '')
console.log(gridItem.letter)
console.log(dedupword)
if (correct_letters == gridWidth) {
endGame(true)
return
}
}
getGridRow(row).complete = true
if (row === gridHeight-1) endGame(false)
}
function init(){
// clear game div
gameContainer.innerHTML = ""
// build letter grid and populate gridItems
const letterGrid = document.createElement("div")
letterGrid.setAttribute("id", "letter_grid")
for (var row = 0; row < gridHeight; row++) {
var gridRow = document.createElement('div')
gridRow.classList.add('grid_row')
gridItems.push({
items: [],
complete: false,
})
for (var column = 0; column < gridWidth; column++) {
var gridItem = document.createElement('div')
gridItem.classList.add('grid_item')
gridItem.setAttribute('id', gridItemId(row, column))
var gridItemP = document.createElement('p')
gridItemP.classList.add('grid_item_p')
gridItem.appendChild(gridItemP)
gridRow.appendChild(gridItem)
gridItems[row].items.push({
HTMLItem: gridItem,
letter: null,
correct: null
})
}
letterGrid.appendChild(gridRow)
}
gameContainer.appendChild(letterGrid)
gameCompleted = false
}
function findNextLetterPosition() {
for (var row = 0; row < gridHeight; row++) {
for (var column = 0; column < gridWidth; column++) {
if (getGridItem(row, column).letter === null) return [row, column]
}
}
}
function findCurrentLetterPosition() {
var lastRow = 0
var lastColumn = 0
for (var row = 0; row < gridHeight; row++) {
for (var column = 0; column < gridWidth; column++) {
if (getGridItem(row, column).letter === null) return [lastRow, lastColumn]
lastRow = row
lastColumn = column
}
}
return [lastRow, lastColumn]
}
function setNextLetter(key) {
if (gameCompleted) return
var [currentRow, currentColumn] = findCurrentLetterPosition()
if (key.code === "Backspace") {
if (currentColumn === -1 || getGridRow(currentRow).complete) return
setGridLetter(currentRow, currentColumn, null)
return
}
if (key.code === "Enter") {
checkGridRow()
}
if (isLetter(key.key)) {
if (key.altKey || key.ctrlKey || key.metaKey) return
var [nextRow, nextColumn] = findNextLetterPosition()
if (currentRow !== nextRow && !getGridRow(currentRow).complete) return
setGridLetter(nextRow, nextColumn, key.key)
return
}
}
function endGame(won) {
gameCompleted = true
if (won) {
endScreenMessage.innerHTML = "niceeeeeeeee"
endScreenImage.src = "trophy.svg"
} else {
endScreenMessage.innerHTML = `damn. better luck nex time <br>(the word was ${word})`
endScreenImage.src = "rusty_medal.svg"
}
endScreenGuesses.innerHTML = `guesses used: ${findCurrentLetterPosition()[0]+1}/${gridHeight}`
endScreen.style.display = "";
}
function runClickAnimation(el) {
console.log(el)
el.classList.add("clicked")
setTimeout(() => el.classList.remove("clicked"), 500)
}
// create event listeners
document.addEventListener('keyup', e => setNextLetter(e))
kbBackspace.addEventListener('click', () => {
runClickAnimation(kbBackspace)
setNextLetter({code: "Backspace", key: "Backspace"})
})
kbEnter.addEventListener('click', () => {
runClickAnimation(kbEnter)
setNextLetter({code: "Enter", key: "Enter"})
})
kbLetters.forEach(kbl => {
kbl.addEventListener('click', () => {
runClickAnimation(kbl)
setNextLetter({code: kbl.innerHTML, key: kbl.innerHTML })
})
})
// start game
init()
console.log(word)