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.01: New app!
|
||||||
0.02: Fix bug with regenerating index, fix bug in word lookups
|
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 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
|
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).
|
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
|
This file can be replaced with a custom dictionary, an ASCII file containing a newline-separated (single "\n", not DOS-style "\r\n") alphabetically
|
||||||
the app that facilitates faster word lookups. This index file is specific to the dictionary file used. If one were to
|
sorted (sorting is important for the word lookup algorithm) list of words.
|
||||||
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.
|
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
const S = require("Storage");
|
const S = require("Storage");
|
||||||
|
const words = S.read("bee.words");
|
||||||
var letters = [];
|
var letters = [];
|
||||||
var letterIdx = [];
|
|
||||||
|
|
||||||
var centers = [];
|
var centers = [];
|
||||||
|
|
||||||
|
@ -12,29 +12,17 @@ var score = 0;
|
||||||
|
|
||||||
var intervalID = -1;
|
var intervalID = -1;
|
||||||
|
|
||||||
function prepareLetterIdx () {
|
function biSearch(w, ws, start, end, count) {
|
||||||
"compile"
|
"compile"
|
||||||
var li = [0];
|
if (start>end-w.legnth || count--<=0) return ws.substr(start, end-start).indexOf("\n"+w+"\n");
|
||||||
if (S.read("bee_lindex.json")!==undefined) li = S.readJSON("bee_lindex.json"); // check for cached index
|
var mid = (end+start)>>1;
|
||||||
else {
|
if (ws[mid-1]==="\n") --mid;
|
||||||
for (var i=1; i<26; ++i) {
|
else while (mid<end && ws[mid]!=="\n") mid++;
|
||||||
var prefix = String.fromCharCode(97+i%26);
|
var i = 0;
|
||||||
console.log(prefix);
|
while (i<w.length && ws[mid+i+1]==w[i]) ++i;
|
||||||
li.push(S.read('bee.words').indexOf("\n"+prefix, li[i-1])+1);
|
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);
|
||||||
li.push(S.read('bee.words').length);
|
if (w[i]>ws[mid+i+1]) return biSearch(w, ws, mid+1, end, count);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPangram(w) {
|
function isPangram(w) {
|
||||||
|
@ -46,7 +34,7 @@ function isPangram(w) {
|
||||||
function checkWord (w) {
|
function checkWord (w) {
|
||||||
if (w.indexOf(String.fromCharCode(97+letters[0]))==-1) return false; // does it contain central letter?
|
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 (foundWords.indexOf(w)>=0) return false; // already found
|
||||||
if (findWord(w)) {
|
if (biSearch(w, words, 0, words.length, 20)>-1) {
|
||||||
foundWords.push(w);
|
foundWords.push(w);
|
||||||
foundWords.sort();
|
foundWords.sort();
|
||||||
if (w.length==4) score++;
|
if (w.length==4) score++;
|
||||||
|
@ -93,13 +81,12 @@ function pickLetters() {
|
||||||
var ltrs = "";
|
var ltrs = "";
|
||||||
while (ltrs.length!==7) {
|
while (ltrs.length!==7) {
|
||||||
ltrs = [];
|
ltrs = [];
|
||||||
var j = Math.floor(26*Math.random());
|
var i = Math.floor((words.length-10)*Math.random());
|
||||||
var i = Math.floor((letterIdx[j].length-10)*Math.random());
|
while (words[i]!="\n" && i<words.length) ++i;
|
||||||
while (letterIdx[j][i]!="\n" && i<letterIdx[j].length) ++i;
|
if (i<words.length-1) {
|
||||||
if (i<letterIdx[j].length-1) {
|
|
||||||
++i;
|
++i;
|
||||||
while (letterIdx[j][i]!=="\n") {
|
while (words[i]!=="\n") {
|
||||||
var c = letterIdx[j][i];
|
var c = words[i];
|
||||||
if (ltrs.indexOf(c)===-1) ltrs += c;
|
if (ltrs.indexOf(c)===-1) ltrs += c;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +174,6 @@ function showWordList() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareLetterIdx();
|
|
||||||
pickLetters();
|
pickLetters();
|
||||||
drawHive();
|
drawHive();
|
||||||
drawScore();
|
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",
|
"name": "Bee",
|
||||||
"shortName":"Bee",
|
"shortName":"Bee",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "Spelling bee",
|
"description": "Spelling bee",
|
||||||
"supports" : ["BANGLEJS2"],
|
"supports" : ["BANGLEJS2"],
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
|
@ -10,7 +10,6 @@
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"bee.app.js","url":"bee.app.js"},
|
{"name":"bee.app.js","url":"bee.app.js"},
|
||||||
{"name":"bee.words","url":"bee_words_2of12"},
|
{"name":"bee.words","url":"bee_words_2of12"},
|
||||||
{"name":"bee_lindex.json","url":"bee_lindex.json"},
|
|
||||||
{"name":"bee.img","url":"app-icon.js","evaluate":true}
|
{"name":"bee.img","url":"app-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue