mirror of https://github.com/espruino/BangleApps
Reword word lookup algorith to use bisection, get rid of index file.
parent
4edfcc6d00
commit
f7b2ece533
|
@ -1,2 +1,3 @@
|
|||
0.01: New app!
|
||||
0.02: Fix bug with regenerating index, fix bug in word lookups
|
||||
0.03: Improve word search performance
|
||||
|
|
|
@ -27,10 +27,7 @@ least once and yields an additional 7 points. Each game contains at least one pa
|
|||
The game uses an internal dictionary consisting of a newline separated list of English words ('bee.words', using the '2of12inf' word list).
|
||||
The dictionary is fairly large (~700kB of flash space) and thus requires appropriate space on the watch and will make installing the app somewhat
|
||||
slow. Because of its size it cannot be compressed (heatshrink needs to hold the compressed/uncompressed data in memory).
|
||||
In order to make checking the validity of a guessed word faster an index file ('bee_lindex.json') is installed with
|
||||
the app that facilitates faster word lookups. This index file is specific to the dictionary file used. If one were to
|
||||
replace the dictionary file with a different version (e.g. a different language) the index file has to be regenerated. The easiest
|
||||
way to do so is to delete (via the Web IDE or the fileman app on the watch) the file 'bee_lindex.json' - it will be regenerated (and saved,
|
||||
i.e. it only happens once) on app startup automatically, a process that takes roughly 30 seconds.
|
||||
This file can be replaced with a custom dictionary, an ASCII file containing a newline-separated (single "\n", not DOS-style "\r\n") alphabetically
|
||||
sorted (sorting is important for the word lookup algorithm) list of words.
|
||||
|
||||

|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
const S = require("Storage");
|
||||
const words = S.read("bee.words");
|
||||
var letters = [];
|
||||
var letterIdx = [];
|
||||
|
||||
var centers = [];
|
||||
|
||||
|
@ -12,29 +12,17 @@ var score = 0;
|
|||
|
||||
var intervalID = -1;
|
||||
|
||||
function prepareLetterIdx () {
|
||||
function biSearch(w, ws, start, end, count) {
|
||||
"compile"
|
||||
var li = [0];
|
||||
if (S.read("bee_lindex.json")!==undefined) li = S.readJSON("bee_lindex.json"); // check for cached index
|
||||
else {
|
||||
for (var i=1; i<26; ++i) {
|
||||
var prefix = String.fromCharCode(97+i%26);
|
||||
console.log(prefix);
|
||||
li.push(S.read('bee.words').indexOf("\n"+prefix, li[i-1])+1);
|
||||
}
|
||||
li.push(S.read('bee.words').length);
|
||||
S.writeJSON("bee_lindex.json", li);
|
||||
}
|
||||
for (var i=0; i<26; ++i) letterIdx[i] = S.read("bee.words", li[i], li[i+1]-li[i]);
|
||||
}
|
||||
|
||||
function findWord (w) {
|
||||
"compile"
|
||||
var ci = w.charCodeAt(0)-97;
|
||||
var f = letterIdx[ci].indexOf("\n"+w+"\n");
|
||||
if (f>=0) return true;
|
||||
if (letterIdx[ci].substr(0, w.length)==w) return true;
|
||||
return false;
|
||||
if (start>end-w.legnth || count--<=0) return ws.substr(start, end-start).indexOf("\n"+w+"\n");
|
||||
var mid = (end+start)>>1;
|
||||
if (ws[mid-1]==="\n") --mid;
|
||||
else while (mid<end && ws[mid]!=="\n") mid++;
|
||||
var i = 0;
|
||||
while (i<w.length && ws[mid+i+1]==w[i]) ++i;
|
||||
if (i==w.length && ws[mid+i+1]==="\n") return mid+1;
|
||||
if (i==w.length || w[i]<ws[mid+i+1]) return biSearch(w, ws, start, mid+1, count);
|
||||
if (w[i]>ws[mid+i+1]) return biSearch(w, ws, mid+1, end, count);
|
||||
}
|
||||
|
||||
function isPangram(w) {
|
||||
|
@ -46,7 +34,7 @@ function isPangram(w) {
|
|||
function checkWord (w) {
|
||||
if (w.indexOf(String.fromCharCode(97+letters[0]))==-1) return false; // does it contain central letter?
|
||||
if (foundWords.indexOf(w)>=0) return false; // already found
|
||||
if (findWord(w)) {
|
||||
if (biSearch(w, words, 0, words.length, 20)>-1) {
|
||||
foundWords.push(w);
|
||||
foundWords.sort();
|
||||
if (w.length==4) score++;
|
||||
|
@ -93,13 +81,12 @@ function pickLetters() {
|
|||
var ltrs = "";
|
||||
while (ltrs.length!==7) {
|
||||
ltrs = [];
|
||||
var j = Math.floor(26*Math.random());
|
||||
var i = Math.floor((letterIdx[j].length-10)*Math.random());
|
||||
while (letterIdx[j][i]!="\n" && i<letterIdx[j].length) ++i;
|
||||
if (i<letterIdx[j].length-1) {
|
||||
var i = Math.floor((words.length-10)*Math.random());
|
||||
while (words[i]!="\n" && i<words.length) ++i;
|
||||
if (i<words.length-1) {
|
||||
++i;
|
||||
while (letterIdx[j][i]!=="\n") {
|
||||
var c = letterIdx[j][i];
|
||||
while (words[i]!=="\n") {
|
||||
var c = words[i];
|
||||
if (ltrs.indexOf(c)===-1) ltrs += c;
|
||||
++i;
|
||||
}
|
||||
|
@ -187,7 +174,6 @@ function showWordList() {
|
|||
});
|
||||
}
|
||||
|
||||
prepareLetterIdx();
|
||||
pickLetters();
|
||||
drawHive();
|
||||
drawScore();
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
[0,41048,80445,152390,198606,228714,257919,279071,303726,337982,343582,348026,367246,404452,419780,438696,496250,499697,544600,624304,659085,680996,691270,708186,708341,709916,710883]
|
74578
apps/bee/bee_words_2of12
74578
apps/bee/bee_words_2of12
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
|||
"name": "Bee",
|
||||
"shortName":"Bee",
|
||||
"icon": "app.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "Spelling bee",
|
||||
"supports" : ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
|
@ -10,7 +10,6 @@
|
|||
"storage": [
|
||||
{"name":"bee.app.js","url":"bee.app.js"},
|
||||
{"name":"bee.words","url":"bee_words_2of12"},
|
||||
{"name":"bee_lindex.json","url":"bee_lindex.json"},
|
||||
{"name":"bee.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue