-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfound.htm
More file actions
314 lines (293 loc) · 8.07 KB
/
found.htm
File metadata and controls
314 lines (293 loc) · 8.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> Found words in a Boggle </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="manifest" xxhref="site.webmanifest">
<link rel="apple-touch-icon" sizes="180x180" xxhref="apple-touch-icon.png">
<!-- https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html -->
<meta name="apple-mobile-web-app-title" content="Found words in a Boggle">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="format-detection" content="telephone=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="keywords" content="boggle, solitaire, puzzle, JavaScript">
<meta name="description" content="free printable boggle worksheets and boggle boards with solutions">
<script>
window.boggleVersion = '0.1';
</script>
<style>
:root {
--varOne: 10;
}
p {
word-spacing: 1vw;
}
.line {
font-weight: 100;
}
.board {
margin: auto;
color: blue;
font-weight: bold;
width: 25%; /* beware: render in print preview shifts to left */
border: 1px solid black
padding: 10px;
xxfont-size: 2.5vw;
font-size: 250%;
letter-spacing: 2.6vw;
}
.grid {
margin-left: auto;
margin-right: auto;
margin: auto;
width: 50%;
display: grid;
xxgrid-template-columns: 3.8vw 3.8vw 3.8vw 3.8vw;
grid-template-columns: 4.8vw 4.8vw 4.8vw 4.8vw;
}
.item {
color: blue;
font-weight: bold;
xxborder: 1px solid green;
font-family: monospace;
font-size: 250%;
text-align: center;
}
.answer {
line-height: 180%;
}
.pagebreak {
page-break-after: always;
}
</style>
</head>
<body onload="bodyLoaded()">
<!--[if IE]>
<h1> Internet Explorer is not supported </h1>
<![endif]-->
<noscript><h1> JavaScript is not enabled </h1></noscript>
<h4>Found words for a Boggle™ </h4>
<h5>https://roytobin.github.io/ebs/ </h5>
Found words in the grid using Boggle™ rules.
<br>
</span>
<br>
<pre id="grid1" class="board">
</pre>
<p class="solution"><span class=found1></span> words found — <span id=solution1></span>
<h5>Feedback: <a href="https://github.com/roytobin/ebs/issues/">
https://github.com/roytobin/ebs/issues/ </a></h5>
<script defer src="encdict.js"></script>
<script>
"use strict"
// BEGIN
function mk_solver() {
const Move = [];
Move[0] = [1, 5, 4];
Move[1] = [0, 2, 6, 5, 4];
Move[2] = [1, 3, 7, 6, 5];
Move[3] = [2, 6, 7];
Move[4] = [0, 1, 5, 9, 8];
Move[5] = [1, 2, 6, 10, 9, 8, 4, 0];
Move[6] = [2, 3, 7, 11, 10, 9, 5, 1];
Move[7] = [3, 11, 10, 6, 2];
Move[8] = [4, 5, 9, 13, 12];
Move[9] = [5, 6, 10, 14, 13, 12, 8, 4];
Move[10] = [6, 7, 11, 15, 14, 13, 9, 5];
Move[11] = [7, 15, 14, 10, 6];
Move[12] = [8, 9, 13];
Move[13] = [9, 10, 14, 12, 8];
Move[14] = [10, 11, 15, 13, 9];
Move[15] = [11, 14, 10];
const STlead = Symbol();
const STgap = Symbol();
const ST1 = Symbol();
const ST2 = Symbol();
const ST3 = Symbol();
const STerr = Symbol();
const Term_mask = 2**31;
const ord_of_A = 'A'.charCodeAt(0);
const ord_of_U = 'U'.charCodeAt(0);
let ready = false
let Dict = [];
let Game = '';
let All_found = {};
let deadman = 0;
function traverse(base, word) {
let ref, off;
const alpha = 'abcdefghijklmnopqrstuvwxyz';
if (deadman > 50) // only do a few, in case running browser
return;
for (let off = 0; off < 26; ++off) {
ref = Dict[base+off];
if ( undefined === ref )
continue;
if ( ref >= Term_mask) {
console.log(word + alpha[off]); // concatenation
ref = ref - Term_mask; // clear bit arithmetically
++deadman;
}
if (0 !== ref)
traverse(ref, word + alpha[off]); // recur after concatenation
}
}
function insert(i, n) {
Dict[i] = n;
//console.log("insert ", i, n);
}
function init() {
let septet; // a group of 7 bits, encoded as a single ASCII character
let term, j, n;
let offset; // offset is the index increment to the next defined reference
let state = STlead;
let index = 0;
for (j=0; j < encDict.length; ++j) {
septet = encDict.charCodeAt(j);
//console.log("septet", septet);
switch(state) {
case STlead:
// The msb of the septet indicates if this ref is word termination
if (septet < 64) {
term = false;
}
else {
term = true;
septet = septet - 64; // clear the msb arithmetically
}
if (septet < 52) {
n = 0;
offset = septet;
state = ST1;
}
else if (septet < 61) {
console.log("error: bad lead-in of", septet);
state = STerr;
}
else {
n = (64-septet) * 128**3;
//gap (actually index offset) is determined in the "gap" state
state = STgap;
}
continue;
case STgap:
offset = septet;
state = ST1;
continue;
case ST1:
n += septet * 128**2;
state = ST2;
continue;
case ST2:
n += septet * 128**1;
state = ST3;
continue;
case ST3:
n += septet * 128**0;
n += (term) ? Term_mask : 0;
insert(index, n);
index += offset;
state = STlead;
continue;
case STerr:
// Stay in this state until the end of processing since there
// is no way to resynchronize.
alert("A syncing error occurred decoding the dictionary used to find words");
continue;
}
}
}
function detect (word) {
if (All_found[word]) return;
All_found[word] = 1;
}
function wordfind (base, pos, word, verboten) {
let letter = Game[pos];
let off = letter.charCodeAt(0) - ord_of_A;
let ref = Dict[base+off];
/*
If the letter is Q, then need to inject or intercede a U because the
boggle die side is labeled "Qu." Thus, no non-Qu words are permitted.
Out, for example, are words "qat" and "qiviut." Debatable if
any non-Qu words are common US English.
*/
/* perl comment: Begin a BLOCK here that may possibly be redo'd to accommodate the
# "QU" digraph. This technique is employed to have the code for the
# "detect" and recursion-ending statements written only once in one
# place. The redo works here because in perl a BLOCK is semantically
# equivalent to a loop that executes once.
// javascript comment: hack to simulate a redo
*/
{let once=1;
while (once) {
if ( undefined === ref ) return;
if ( ref >= Term_mask) {
detect(word+letter);
ref = ref - Term_mask;
}
if (0 === ref) return;
if ('Q' === letter) {
ref = Dict[ref + ord_of_U - ord_of_A];
letter = letter + 'U';
continue; // surrogate "redo"
}
--once;
}}
verboten = verboten | (1<<pos);
for (let next_move of Move[pos]) {
if (verboten & (1<<next_move))
continue;
wordfind(ref, next_move, word+letter, verboten); // recur
}
}
return function(game) {
Game = game;
if (!ready) {
init();
ready = true;
}
All_found = {};
for (let pos = 0; pos < 16; ++pos) {
wordfind(0, pos, "", 0);
}
return Object.keys(All_found).sort();
}
}
// END
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
function checkGame() {
let game = getUrlVars()["game"];
if ( undefined === game ) {
window.location.href = "index.html";
}
return game.toUpperCase();
}
function populateDOM(idx, puz, sol) {
let elem, found;
let res = puz.split(/(\w{4})/);
elem = document.getElementById(`grid${idx}`);
elem.innerHTML = [res[1], res[3], res[5], res[7]].join("\n");
found = sol.length;
for (elem of document.querySelectorAll(`.found${idx}`)) {
elem.innerHTML = found.toString();
}
elem = document.getElementById(`solution${idx}`);
elem.innerHTML = sol.join(' ').toLowerCase();
}
function bodyLoaded() {
let game = checkGame();
if ( undefined === game )
return;
let solve = mk_solver();
populateDOM(1, game, solve(game));
}
</script>
</body>
</html>