initial commit

This commit is contained in:
Akbar Rahman 2022-01-27 18:36:45 +00:00
commit 2903155df6
Signed by: alvierahman90
GPG Key ID: 20609519444A1269
8 changed files with 280 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
wordlist.js

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "english-words"]
path = english-words
url = https://github.com/dwyl/english-words

12
Makefile Normal file
View 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

@ -0,0 +1 @@
Subproject commit 22d7c41119076750a96fca2acd664ed994cc0a75

160
game.js Normal file
View 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
View 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
View 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
View 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)}