initial commit
This commit is contained in:
commit
2903155df6
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
wordlist.js
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "english-words"]
|
||||||
|
path = english-words
|
||||||
|
url = https://github.com/dwyl/english-words
|
12
Makefile
Normal file
12
Makefile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
wordlist.js: english-words
|
||||||
|
scripts/gen_wordlist.py english-words/words.txt 5 > wordlist.js
|
||||||
|
|
||||||
|
english-words: .SUBMODULES
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf wordlist.js
|
||||||
|
|
||||||
|
.SUBMODULES:
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
|
1
english-words
Submodule
1
english-words
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 22d7c41119076750a96fca2acd664ed994cc0a75
|
160
game.js
Normal file
160
game.js
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
// global constants
|
||||||
|
const gridWidth = 5
|
||||||
|
const gridHeight = 6
|
||||||
|
const word = wordlist[Math.floor(Math.random()*wordlist.length)];
|
||||||
|
|
||||||
|
// global state variables
|
||||||
|
var gameCompleted = null
|
||||||
|
|
||||||
|
// HTML items
|
||||||
|
const gameContainer = document.getElementById("game_container")
|
||||||
|
const gridItems = []
|
||||||
|
|
||||||
|
// helper functions
|
||||||
|
const gridItemId = (row, column) => "grid_item_" + row + "_" + column
|
||||||
|
const getGridRow = (row) => gridItems[row]
|
||||||
|
const getGridItem = (row, column) => gridItems[row].items[column]
|
||||||
|
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.includes(rowWord)) 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')
|
||||||
|
correct_letters += 1
|
||||||
|
} else if (dedupword.includes(gridItem.letter)) {
|
||||||
|
gridItem.HTMLItem.classList.add('grid_present')
|
||||||
|
} else {
|
||||||
|
gridItem.HTMLItem.classList.add('grid_wrong')
|
||||||
|
}
|
||||||
|
|
||||||
|
dedupword = dedupword.replace(gridItem.letter, '')
|
||||||
|
console.log(gridItem.letter)
|
||||||
|
console.log(dedupword)
|
||||||
|
|
||||||
|
if (correct_letters == gridWidth) gameCompleted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
getGridRow(row).complete = true
|
||||||
|
if (row === gridHeight-1) gameCompleted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// create event listeners
|
||||||
|
document.addEventListener('keyup', (e) => {
|
||||||
|
console.log(e)
|
||||||
|
setNextLetter(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
init()
|
25
index.html
Normal file
25
index.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles.css">
|
||||||
|
<title>word guessing game: infinite</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>word guessing game</h1>
|
||||||
|
|
||||||
|
<div id="game_container">
|
||||||
|
you need javascript enabled to play this game
|
||||||
|
<div id="letter_grid">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
built with ❤ and adequate amounts of care by
|
||||||
|
<a href="https://alv.cx">alv</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<script type="application/javascript" src="wordlist.js"></script>
|
||||||
|
<script type="application/javascript" src="game.js"></script>
|
||||||
|
</body>
|
31
scripts/gen_wordlist.py
Executable file
31
scripts/gen_wordlist.py
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def get_args():
|
||||||
|
""" Get command line arguments """
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('wordlist')
|
||||||
|
parser.add_argument('word_length', type=int)
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
""" Entry point for script """
|
||||||
|
with open(args.wordlist) as fp:
|
||||||
|
words = [ word.lower() for word in fp.read().split('\n') if len(word) == args.word_length and word.isalpha() ]
|
||||||
|
|
||||||
|
print(f"wordlist = {json.dumps(words)}")
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
sys.exit(main(get_args()))
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(0)
|
47
styles.css
Normal file
47
styles.css
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
@import url("https://alv.cx/styles.css");
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--default-bg: #fefefe;
|
||||||
|
--dark-bg: #b8b8b8;
|
||||||
|
--selected-bg: #383838;
|
||||||
|
--default-fg: #454545;
|
||||||
|
--red: #ab4642;
|
||||||
|
--orange: #dc9656;
|
||||||
|
--yellow: #f7ca88;
|
||||||
|
--green: #a1b56c;
|
||||||
|
--teal: #86c1b9;
|
||||||
|
--blue: #7cafc2;
|
||||||
|
--purple: #ba8baf;
|
||||||
|
--brown: #a16946;
|
||||||
|
}
|
||||||
|
|
||||||
|
#letter_grid {
|
||||||
|
width: fit-content;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid_row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid_item {
|
||||||
|
width: 3em;
|
||||||
|
height: 3em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border: 0.2em solid var(--dark-bg);
|
||||||
|
margin: 1em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid_item * {
|
||||||
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid_correct { background-color: var(--green)}
|
||||||
|
.grid_present { background-color: var(--yellow)}
|
||||||
|
.grid_wrong { background-color: var(--brown)}
|
Loading…
Reference in New Issue
Block a user