Public
Edited
Apr 22, 2022
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
mutable clicked = 0
Insert cell
drawBoard = (sideLength, cur, color) => {
let n = cur.word.length
let angle = Math.PI * 2 / n
const pts = []
for (let i = 0; i < n; i++) {
pts.push({
x: 50 + 39 * Math.cos(i*angle),
y: 50 + 39 * Math.sin(i*angle)
})
}
let r = 10
if (n > 12) r = 7
if (n > 17) r = 5
const onClick = function(i) {
mutable clicked = i
}
return svg`<svg height="${sideLength}" width="${sideLength}" viewbox="0 0 100 100">
<style>
.letter { font: 9px sans-serif; fill: ${color}; alignment-baseline:middle; text-anchor: middle; }
.guessed { font: 9px sans-serif; fill: ${guessedColor}; alignment-baseline:middle; text-anchor: middle; }
.timer { font: 6px sans-serif; fill: "#635a5a"; alignment-baseline:middle; text-anchor: middle; }
</style>
<circle cx="50" cy="50" r="39" stroke="#635a5a" stroke-width="3" fill="none"/>

${pts.map((x,i)=> svg`<g>
<circle cx="${x.x}" cy="${x.y}" r="${r}" stroke="#635a5a" stroke-width="2" fill="white"/>
<text x="${x.x}" y="${x.y}" class="letter">${cur.shuffle[i]}</text>
</g>`)}
`
}
Insert cell
drawRecord = (x) => {
return html.fragment `<tr>
<td></td>
<td style="color:${x.isGoodGuess ? correctColor : incorrectColor}">${x.guess}</td>
<td>${x.word}</td>
<td>${x.word.length}</td>

</tr>
`
}
Insert cell
viewof correctColor = color("#16a716")
Insert cell
viewof incorrectColor = color("#BB0000")
Insert cell
viewof guessedColor = color("#999999")
Insert cell
viewof boardColor = color("#338ddb")
Insert cell
validStructure = {
const first = guessValue ? guessValue[0] == current.first : false
const last = guessValue ? guessValue[guessValue.length - 1] == current.last : false
if(!first) return `invalid`
if (last) return 'structurally valid'
else return 'incomplete'
}
Insert cell
Insert cell
Insert cell
mutable current = getWord(wordLengthBounds[0],wordLengthBounds[1])
Insert cell
getWord = (minLength, maxLength) => {
const filteredWords = words.filter(w => w.length >= minLength && w.length <= maxLength)
return shuffle(filteredWords[d3.randomInt(0, filteredWords.length)()])
}
Insert cell
shuffle = w => {
const output = {}
output.word = w
const order = d3.randomInt(0, 2)()
let shuffleIndex = d3.randomInt(0, w.length)()
let outword = w
if (order) outword = w.split('').reverse().join('')
outword = outword.slice(shuffleIndex,w.length) + outword.slice(0, shuffleIndex)
output.shuffle = outword
return output
}
Insert cell
validateGuess = (guess, cur) => {
const out =
// is a rotation
(isRotationOf(cur.word, guess) ||
// or reverse is a rotation
isRotationOf(cur.word, guess.split('').reverse().join(''))) &&
// is in the dictionary
words.includes(guess)

return out;
}
Insert cell
isRotationOf = (s1, s2) => {
if (s1.length != s2.length) return false
let candidate = s2
for (let i = 0; i < candidate.length; i++) {
if (s1 === candidate) return true
candidate = candidate.slice(1,s1.length) + candidate[0]
}
return false
}
Insert cell
isRotationOrReverseRotationOf = (s1, s2) => isRotationOf(s1,s2) ||
isRotationOf(s1, s2.split('').reverse().join(''))
Insert cell
log = (data) => {
mutable history = [data, ...history]
}
Insert cell
mutable history = []
Insert cell
import {words} from '@a-lexwein/find-a-big-word'
Insert cell
d3 = require('d3@6')
Insert cell
import {aq, op} from '@uwdata/arquero'
Insert cell
import {color} from '@jashkenas/inputs'
Insert cell
import {html, svg} from "@observablehq/htl"
Insert cell
import {rangeSlider} from '@mootari/range-slider@1312'
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more