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/ | ||||
| _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) { | ||||
|   cfg.addPassthroughCopy("assets/styles/main.css"); | ||||
|   cfg.addPassthroughCopy("assets/scripts/**/*.js"); | ||||
|   cfg.addPassthroughCopy("site/assets/styles/main.css"); | ||||
|   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 { | ||||
|   static targets = ["row"]; | ||||
|    | ||||
|   connect() {  | ||||
|   async connect() { | ||||
|     this._wordSource = new WordSource(); | ||||
|     this._gameController = new GameController(this._wordSource); | ||||
|      | ||||
| 
 | ||||
|     await this._gameController.start(); | ||||
| 
 | ||||
|     this._buildPlayfield(); | ||||
|   } | ||||
|    | ||||
|  | @ -13,29 +13,36 @@ export const MARKERS = { | |||
| export class GameController { | ||||
|   constructor(wordSource) { | ||||
|     this._wordSource = wordSource; | ||||
|     this._currentWord = wordSource.getCurrentWord(); | ||||
|   } | ||||
| 
 | ||||
|   async start() { | ||||
|     this._currentWord = await this._wordSource.getCurrentWord(); | ||||
|     this._guesses = 5; | ||||
| 
 | ||||
|     console.log("The current word: " + this._currentWord); | ||||
|   } | ||||
|    | ||||
|   wordLength() { | ||||
|     this._checkHasStarted(); | ||||
|     return this._currentWord.length; | ||||
|   } | ||||
|    | ||||
|   guesses() { | ||||
|     this._checkHasStarted(); | ||||
|     return this._guesses; | ||||
|   } | ||||
|    | ||||
|   nextWord() { | ||||
|     if (!this._wordSource.nextWord()) { | ||||
|       return false; | ||||
|     } | ||||
|      | ||||
|     this._currentWord = this._wordSource.getCurrentWord(); | ||||
|   async nextWord() { | ||||
|     this._currentWord = await this._wordSource.getCurrentWord(); | ||||
|     this._guesses = 5; | ||||
|     return true; | ||||
|   } | ||||
|    | ||||
|   checkGuess(guess) { | ||||
|     this._checkHasStarted(); | ||||
| 
 | ||||
|     guess = guess.toLowerCase(); | ||||
| 
 | ||||
|     if (guess.length != this._currentWord.length) { | ||||
|       throw Error(`Expected length to be ${this._currentWord.length} but was ${guess.length}`); | ||||
|     } | ||||
|  | @ -100,4 +107,10 @@ export class GameController { | |||
|       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