Have got a dictionary of words
This commit is contained in:
parent
5cb44dd17e
commit
d9fa154a01
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
||||||
node_modules/
|
node_modules/
|
||||||
_site/
|
_site/
|
||||||
|
build/
|
||||||
|
.idea/
|
|
@ -1,28 +0,0 @@
|
||||||
export class WordSource {
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this._words = [
|
|
||||||
"MUNCH",
|
|
||||||
"HOUSE",
|
|
||||||
"MOON"
|
|
||||||
];
|
|
||||||
this._currentWord = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
isWord(word) {
|
|
||||||
return this._words.filter((x) => x == word).length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCurrentWord() {
|
|
||||||
return this._words[this._currentWord];
|
|
||||||
}
|
|
||||||
|
|
||||||
nextWord() {
|
|
||||||
if (this._currentWord >= this._words.length - 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._currentWord += 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
72
cmd/prep-words/main.go
Normal file
72
cmd/prep-words/main.go
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
type wordList struct {
|
||||||
|
Words map[int][]string `json:"words"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
dictFile := flag.String("dict", "", "dictionary of word to prep")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
words := wordList{
|
||||||
|
Words: make(map[int][]string),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanSuitableWords(*dictFile, func(word string) {
|
||||||
|
if len(word) >= 4 && len(word) <= 6 {
|
||||||
|
words.Words[len(word)] = append(words.Words[len(word)], word)
|
||||||
|
}
|
||||||
|
}); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, word := range words.Words {
|
||||||
|
sort.Strings(word)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.NewEncoder(os.Stdout).Encode(words); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func scanSuitableWords(dictFile string, withWord func(word string)) error {
|
||||||
|
f, err := os.Open(dictFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(f)
|
||||||
|
for scanner.Scan() {
|
||||||
|
isSuitable := true
|
||||||
|
breakpoint := len(scanner.Text())
|
||||||
|
|
||||||
|
for i, r := range scanner.Text() {
|
||||||
|
if r == '/' {
|
||||||
|
breakpoint = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if r < 'a' || r > 'z' {
|
||||||
|
isSuitable = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isSuitable {
|
||||||
|
word := scanner.Text()[:breakpoint]
|
||||||
|
withWord(word)
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scanner.Err()
|
||||||
|
}
|
2
dict/README.md
Normal file
2
dict/README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
This is a Hunspell dictionary taken from this location:
|
||||||
|
https://archive.netbsd.org/pub/pkgsrc-archive/distfiles/2019Q4/hunspell-dictionaries/en_GB-20061130/en_GB.zip
|
46281
dict/en_GB.dic
Normal file
46281
dict/en_GB.dic
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,12 @@
|
||||||
export default function(cfg) {
|
export default function(cfg) {
|
||||||
cfg.addPassthroughCopy("assets/styles/main.css");
|
cfg.addPassthroughCopy("site/assets/styles/main.css");
|
||||||
cfg.addPassthroughCopy("assets/scripts/**/*.js");
|
cfg.addPassthroughCopy("site/assets/scripts/**/*.js");
|
||||||
|
cfg.addPassthroughCopy("site/assets/data/*");
|
||||||
|
|
||||||
|
return {
|
||||||
|
dir: {
|
||||||
|
input: "site",
|
||||||
|
output: "build/site"
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
1
site/assets/data/words.json
Normal file
1
site/assets/data/words.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -7,10 +7,12 @@ import { WordSource } from "../models/words.js";
|
||||||
export default class extends Controller {
|
export default class extends Controller {
|
||||||
static targets = ["row"];
|
static targets = ["row"];
|
||||||
|
|
||||||
connect() {
|
async connect() {
|
||||||
this._wordSource = new WordSource();
|
this._wordSource = new WordSource();
|
||||||
this._gameController = new GameController(this._wordSource);
|
this._gameController = new GameController(this._wordSource);
|
||||||
|
|
||||||
|
await this._gameController.start();
|
||||||
|
|
||||||
this._buildPlayfield();
|
this._buildPlayfield();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,29 +13,36 @@ export const MARKERS = {
|
||||||
export class GameController {
|
export class GameController {
|
||||||
constructor(wordSource) {
|
constructor(wordSource) {
|
||||||
this._wordSource = wordSource;
|
this._wordSource = wordSource;
|
||||||
this._currentWord = wordSource.getCurrentWord();
|
}
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
this._currentWord = await this._wordSource.getCurrentWord();
|
||||||
this._guesses = 5;
|
this._guesses = 5;
|
||||||
|
|
||||||
|
console.log("The current word: " + this._currentWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
wordLength() {
|
wordLength() {
|
||||||
|
this._checkHasStarted();
|
||||||
return this._currentWord.length;
|
return this._currentWord.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
guesses() {
|
guesses() {
|
||||||
|
this._checkHasStarted();
|
||||||
return this._guesses;
|
return this._guesses;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextWord() {
|
async nextWord() {
|
||||||
if (!this._wordSource.nextWord()) {
|
this._currentWord = await this._wordSource.getCurrentWord();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._currentWord = this._wordSource.getCurrentWord();
|
|
||||||
this._guesses = 5;
|
this._guesses = 5;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkGuess(guess) {
|
checkGuess(guess) {
|
||||||
|
this._checkHasStarted();
|
||||||
|
|
||||||
|
guess = guess.toLowerCase();
|
||||||
|
|
||||||
if (guess.length != this._currentWord.length) {
|
if (guess.length != this._currentWord.length) {
|
||||||
throw Error(`Expected length to be ${this._currentWord.length} but was ${guess.length}`);
|
throw Error(`Expected length to be ${this._currentWord.length} but was ${guess.length}`);
|
||||||
}
|
}
|
||||||
|
@ -100,4 +107,10 @@ export class GameController {
|
||||||
markers: markers
|
markers: markers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_checkHasStarted() {
|
||||||
|
if (!this._currentWord) {
|
||||||
|
throw new Error("call start() first");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
64
site/assets/scripts/models/words.js
Normal file
64
site/assets/scripts/models/words.js
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
function binSearch(list, word) {
|
||||||
|
let first = 0;
|
||||||
|
let last = list.length;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
let ptr = (first + (last - first) / 2) | 0;
|
||||||
|
if (list[ptr] === word) {
|
||||||
|
return true;
|
||||||
|
} else if (last - first <= 1) {
|
||||||
|
return false;
|
||||||
|
} else if (list[ptr] > word) {
|
||||||
|
last = ptr;
|
||||||
|
} else if (list[ptr] < word) {
|
||||||
|
first = ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class WordSource {
|
||||||
|
constructor() {
|
||||||
|
this._wordData = null;
|
||||||
|
this._currentWord = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
isWord(word) {
|
||||||
|
let list = this._wordData.words[word.length.toString()];
|
||||||
|
if (!list) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return binSearch(list, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCurrentWord() {
|
||||||
|
if (this._currentWord) {
|
||||||
|
return this._currentWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
let words = await this._fetchAllWordsIfNecessary();
|
||||||
|
this._currentWord = words.words["4"][7];
|
||||||
|
|
||||||
|
return this._currentWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
async nextWord() {
|
||||||
|
if (this._currentWord >= this._words.length - 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._currentWord += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async _fetchAllWordsIfNecessary() {
|
||||||
|
if (this._wordData) {
|
||||||
|
return this._wordData;
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = await fetch("/assets/data/words.json");
|
||||||
|
this._wordData = await res.json();
|
||||||
|
return this._wordData;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue