gta and more words
This commit is contained in:
69
index.html
69
index.html
@@ -1,34 +1,49 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
|
||||||
<title>Quartiles — Daily Word Puzzle Game</title>
|
|
||||||
<meta name="description" content="Play Quartiles, the addictive daily word fragment puzzle game. Combine letter tiles into words, chase the five 4-tile Quartiles, and score 100 points for Expert rank!" />
|
|
||||||
|
|
||||||
<!-- PWA & Theme Colors -->
|
<head>
|
||||||
<meta name="theme-color" content="#1c1c1e" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="mobile-web-app-capable" content="yes" />
|
<meta name="viewport"
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<title>Quartiles — Daily Word Puzzle Game</title>
|
||||||
<meta name="apple-mobile-web-app-title" content="Quartiles" />
|
<meta name="description"
|
||||||
<meta name="application-name" content="Quartiles" />
|
content="Play Quartiles, the addictive daily word fragment puzzle game. Combine letter tiles into words, chase the five 4-tile Quartiles, and score 100 points for Expert rank!" />
|
||||||
<meta name="msapplication-TileColor" content="#d97706" />
|
|
||||||
|
|
||||||
<!-- Web App Manifest -->
|
<!-- PWA & Theme Colors -->
|
||||||
<link rel="manifest" href="/manifest.webmanifest" />
|
<meta name="theme-color" content="#1c1c1e" />
|
||||||
|
<meta name="mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
|
<meta name="apple-mobile-web-app-title" content="Quartiles" />
|
||||||
|
<meta name="application-name" content="Quartiles" />
|
||||||
|
<meta name="msapplication-TileColor" content="#d97706" />
|
||||||
|
|
||||||
<!-- Icons -->
|
<!-- Web App Manifest -->
|
||||||
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
|
<link rel="manifest" href="/manifest.webmanifest" />
|
||||||
<link rel="apple-touch-icon" href="/icon.svg" />
|
|
||||||
|
<!-- Icons -->
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
|
||||||
|
<link rel="apple-touch-icon" href="/icon.svg" />
|
||||||
|
|
||||||
|
<!-- Google Fonts: Inter -->
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap"
|
||||||
|
rel="stylesheet" />
|
||||||
|
<!-- Google tag (gtag.js) -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-VB6LB7H9KS"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag() { dataLayer.push(arguments); }
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'G-VB6LB7H9KS');
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
<!-- Google Fonts: Inter -->
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap" rel="stylesheet" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module" src="/src/main.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
@@ -3,195 +3,10 @@ import path from 'node:path';
|
|||||||
import { extraWords } from './extra-words.mjs';
|
import { extraWords } from './extra-words.mjs';
|
||||||
import { DICTIONARY_SET } from '../src/data/lexicon.js';
|
import { DICTIONARY_SET } from '../src/data/lexicon.js';
|
||||||
|
|
||||||
export const targetWordsPool = [
|
// Build and validate target words pool for Quartiles
|
||||||
// Wonder & Exploration
|
export const targetWordsPool = [];
|
||||||
{ word: 'remarkable', tiles: ['re', 'mar', 'ka', 'ble'], theme: 'wonder', clue: 'Worthy of attention; striking' },
|
|
||||||
{ word: 'unforgettable', tiles: ['un', 'for', 'get', 'table'], theme: 'wonder', clue: 'Impossible to forget; memorable' },
|
|
||||||
{ word: 'photography', tiles: ['pho', 'to', 'gra', 'phy'], theme: 'wonder', clue: 'The art or practice of taking photos' },
|
|
||||||
{ word: 'adventurous', tiles: ['ad', 'ven', 'tur', 'ous'], theme: 'wonder', clue: 'Willing to take risks or try new things' },
|
|
||||||
{ word: 'inspiration', tiles: ['in', 'spi', 'ra', 'tion'], theme: 'wonder', clue: 'A stimulus to creative thought or action' },
|
|
||||||
|
|
||||||
// Space & Cosmos
|
|
||||||
{ word: 'astronomy', tiles: ['as', 'tro', 'no', 'my'], theme: 'space', clue: 'The branch of science dealing with space' },
|
|
||||||
{ word: 'gravitation', tiles: ['gra', 'vi', 'ta', 'tion'], theme: 'space', clue: 'The force that attracts bodies toward mass' },
|
|
||||||
{ word: 'atmosphere', tiles: ['at', 'mo', 'sph', 'ere'], theme: 'space', clue: 'The envelope of gases surrounding a planet' },
|
|
||||||
{ word: 'interstellar', tiles: ['in', 'ter', 'ste', 'llar'], theme: 'space', clue: 'Occurring between stars' },
|
|
||||||
{ word: 'telescopic', tiles: ['tel', 'es', 'co', 'pic'], theme: 'space', clue: 'Having the power for viewing distant objects' },
|
|
||||||
{ word: 'constellation', tiles: ['con', 'ste', 'lla', 'tion'], theme: 'space', clue: 'A group of stars forming a pattern' },
|
|
||||||
{ word: 'stratosphere', tiles: ['stra', 'tos', 'phe', 're'], theme: 'space', clue: 'Layer of the atmosphere above troposphere' },
|
|
||||||
|
|
||||||
// Mind & Philosophy
|
|
||||||
{ word: 'imagination', tiles: ['im', 'agi', 'na', 'tion'], theme: 'mind', clue: 'The faculty of forming new ideas or images' },
|
|
||||||
{ word: 'understanding', tiles: ['un', 'der', 'stan', 'ding'], theme: 'mind', clue: 'The ability to comprehend something' },
|
|
||||||
{ word: 'psychology', tiles: ['psy', 'cho', 'lo', 'gy'], theme: 'mind', clue: 'The scientific study of mind and behavior' },
|
|
||||||
{ word: 'intelligence', tiles: ['in', 'tel', 'li', 'gence'], theme: 'mind', clue: 'The ability to acquire and apply knowledge' },
|
|
||||||
{ word: 'consciousness', tiles: ['con', 'sci', 'ous', 'ness'], theme: 'mind', clue: 'The state of being aware of surroundings' },
|
|
||||||
{ word: 'philosophy', tiles: ['phi', 'los', 'op', 'hy'], theme: 'mind', clue: 'The study of fundamental nature of knowledge' },
|
|
||||||
{ word: 'thoughtfulness', tiles: ['thou', 'ght', 'ful', 'ness'], theme: 'mind', clue: 'The state of thinking deeply or being caring' },
|
|
||||||
|
|
||||||
// Architecture & City
|
|
||||||
{ word: 'architecture', tiles: ['ar', 'chi', 'tec', 'ture'], theme: 'city', clue: 'The art and practice of designing buildings' },
|
|
||||||
{ word: 'metropolitan', tiles: ['me', 'tro', 'pol', 'itan'], theme: 'city', clue: 'Relating to a large, busy city' },
|
|
||||||
{ word: 'construction', tiles: ['con', 'stru', 'cti', 'on'], theme: 'city', clue: 'The building of something typically large' },
|
|
||||||
{ word: 'neighborhood', tiles: ['neigh', 'bor', 'ho', 'od'], theme: 'city', clue: 'A district or area forming a community' },
|
|
||||||
{ word: 'skyscraper', tiles: ['sky', 'sc', 'ra', 'per'], theme: 'city', clue: 'A very tall building with many stories' },
|
|
||||||
|
|
||||||
// Music & Arts
|
|
||||||
{ word: 'masterpiece', tiles: ['mas', 'ter', 'pie', 'ce'], theme: 'arts', clue: 'A work of outstanding artistry or skill' },
|
|
||||||
{ word: 'calligraphy', tiles: ['cal', 'lig', 'ra', 'phy'], theme: 'arts', clue: 'Decorative handwriting or handwritten lettering' },
|
|
||||||
{ word: 'exhibition', tiles: ['ex', 'hi', 'bi', 'tion'], theme: 'arts', clue: 'A public display of works of art or items' },
|
|
||||||
{ word: 'creativity', tiles: ['cre', 'at', 'iv', 'ity'], theme: 'arts', clue: 'The use of the imagination or original ideas' },
|
|
||||||
{ word: 'choreography', tiles: ['cho', 'reo', 'gra', 'phy'], theme: 'arts', clue: 'The sequence of steps and movements in dance' },
|
|
||||||
|
|
||||||
// Technology & Future
|
|
||||||
{ word: 'technology', tiles: ['tec', 'hno', 'lo', 'gy'], theme: 'tech', clue: 'Application of scientific knowledge for practical aims' },
|
|
||||||
{ word: 'electronic', tiles: ['el', 'ect', 'ro', 'nic'], theme: 'tech', clue: 'Having components like microchips or transistors' },
|
|
||||||
{ word: 'automation', tiles: ['au', 'to', 'ma', 'tion'], theme: 'tech', clue: 'The use of largely automatic equipment in a system' },
|
|
||||||
{ word: 'cybersecurity', tiles: ['cy', 'ber', 'sec', 'urity'], theme: 'tech', clue: 'Protection of computer systems from attack or theft' },
|
|
||||||
{ word: 'motherboard', tiles: ['mo', 'ther', 'bo', 'ard'], theme: 'tech', clue: 'A printed circuit board containing principal components' },
|
|
||||||
|
|
||||||
// Celebrations & Community
|
|
||||||
{ word: 'celebration', tiles: ['cel', 'eb', 'ra', 'tion'], theme: 'society', clue: 'The action of marking pleasure at an event' },
|
|
||||||
{ word: 'fellowship', tiles: ['fel', 'low', 'sh', 'ip'], theme: 'society', clue: 'Friendly association, especially with shared interests' },
|
|
||||||
{ word: 'generosity', tiles: ['gen', 'ero', 'si', 'ty'], theme: 'society', clue: 'The quality of being kind and generous' },
|
|
||||||
{ word: 'opportunity', tiles: ['op', 'por', 'tu', 'nity'], theme: 'society', clue: 'A set of circumstances making something possible' },
|
|
||||||
{ word: 'marshmallow', tiles: ['mar', 'shm', 'all', 'ow'], theme: 'society', clue: 'A sweet chewy confection made of sugar and gelatin' },
|
|
||||||
{ word: 'hospitality', tiles: ['hos', 'pit', 'al', 'ity'], theme: 'society', clue: 'Friendly and generous reception of guests' },
|
|
||||||
{ word: 'friendship', tiles: ['fri', 'end', 'sh', 'ip'], theme: 'society', clue: 'A state of mutual trust and support between people' },
|
|
||||||
|
|
||||||
// Nature & Wild Kingdom
|
|
||||||
{ word: 'biodiversity', tiles: ['bio', 'di', 'ver', 'sity'], theme: 'nature', clue: 'The variety of life in the world or habitat' },
|
|
||||||
{ word: 'environment', tiles: ['en', 'vi', 'ron', 'ment'], theme: 'nature', clue: 'The surroundings or conditions in which one lives' },
|
|
||||||
{ word: 'caterpillar', tiles: ['cat', 'er', 'pil', 'lar'], theme: 'nature', clue: 'The larval stage of a butterfly or moth' },
|
|
||||||
{ word: 'wilderness', tiles: ['wil', 'der', 'ne', 'ss'], theme: 'nature', clue: 'An uncultivated, uninhabited, and hospitable region' },
|
|
||||||
{ word: 'chameleon', tiles: ['cha', 'me', 'le', 'on'], theme: 'nature', clue: 'A lizard capable of changing skin color' },
|
|
||||||
{ word: 'hummingbird', tiles: ['hum', 'ming', 'bi', 'rd'], theme: 'nature', clue: 'Small nectar-feeding bird with hovering flight' },
|
|
||||||
{ word: 'woodpecker', tiles: ['wood', 'pe', 'ck', 'er'], theme: 'nature', clue: 'A bird with a strong beak for drilling into wood' },
|
|
||||||
{ word: 'butterflies', tiles: ['but', 'ter', 'fli', 'es'], theme: 'nature', clue: 'Insects with large, often brightly colored wings' },
|
|
||||||
{ word: 'grasshoppers', tiles: ['grass', 'hop', 'pe', 'rs'], theme: 'nature', clue: 'Plant-eating insect with powerful hind legs for jumping' },
|
|
||||||
|
|
||||||
// Mysteries & Legends
|
|
||||||
{ word: 'mysterious', tiles: ['mys', 'ter', 'io', 'us'], theme: 'mystery', clue: 'Difficult or impossible to understand or explain' },
|
|
||||||
{ word: 'supernatural', tiles: ['su', 'per', 'nat', 'ural'], theme: 'mystery', clue: 'Attributed to some force beyond scientific understanding' },
|
|
||||||
{ word: 'enchanted', tiles: ['en', 'cha', 'nt', 'ed'], theme: 'mystery', clue: 'Placed under a spell; bewitched' },
|
|
||||||
{ word: 'miraculous', tiles: ['mi', 'rac', 'ul', 'ous'], theme: 'mystery', clue: 'Occurring through divine or extraordinary intervention' },
|
|
||||||
|
|
||||||
// Science & Discovery
|
|
||||||
{ word: 'equivalent', tiles: ['equ', 'iv', 'al', 'ent'], theme: 'science', clue: 'Equal in value, amount, function, or meaning' },
|
|
||||||
{ word: 'hypothesis', tiles: ['hy', 'pot', 'he', 'sis'], theme: 'science', clue: 'A proposed explanation made on limited evidence' },
|
|
||||||
{ word: 'laboratory', tiles: ['lab', 'ora', 'to', 'ry'], theme: 'science', clue: 'A room or building equipped for scientific experiments' },
|
|
||||||
{ word: 'microscope', tiles: ['mi', 'cro', 'sco', 'pe'], theme: 'science', clue: 'Optical instrument for magnifying tiny objects' },
|
|
||||||
{ word: 'phenomenon', tiles: ['phe', 'nom', 'en', 'on'], theme: 'science', clue: 'A remarkable fact or situation that is observed to happen' },
|
|
||||||
|
|
||||||
// Literature & Wordsmith
|
|
||||||
{ word: 'dictionary', tiles: ['dic', 'tio', 'na', 'ry'], theme: 'words', clue: 'A reference book on words and definitions' },
|
|
||||||
{ word: 'manuscript', tiles: ['man', 'us', 'cr', 'ipt'], theme: 'words', clue: 'An author text that has not yet been printed' },
|
|
||||||
{ word: 'encyclopedia', tiles: ['en', 'cy', 'clo', 'pedia'], theme: 'words', clue: 'A book or set providing information on many subjects' },
|
|
||||||
{ word: 'literature', tiles: ['li', 'ter', 'at', 'ure'], theme: 'words', clue: 'Written works, especially those considered of superior merit' },
|
|
||||||
|
|
||||||
// Travel & Geography
|
|
||||||
{ word: 'backpacker', tiles: ['back', 'pa', 'ck', 'er'], theme: 'travel', clue: 'A traveler who journeys carrying their belongings' },
|
|
||||||
{ word: 'locomotive', tiles: ['lo', 'co', 'mo', 'tive'], theme: 'travel', clue: 'A powered rail vehicle used for pulling trains' },
|
|
||||||
{ word: 'continental', tiles: ['con', 'tin', 'en', 'tal'], theme: 'travel', clue: 'Forming or belonging to a continent' },
|
|
||||||
{ word: 'navigation', tiles: ['na', 'vi', 'ga', 'tion'], theme: 'travel', clue: 'The process of accurately ascertaining one position and course' },
|
|
||||||
{ word: 'voyagers', tiles: ['vo', 'ya', 'ge', 'rs'], theme: 'travel', clue: 'People who go on a long journey, typically by sea or space' },
|
|
||||||
|
|
||||||
// Weather & Atmosphere
|
|
||||||
{ word: 'meteorology', tiles: ['me', 'teo', 'rol', 'ogy'], theme: 'weather', clue: 'The science of atmospheric processes and forecasting' },
|
|
||||||
{ word: 'temperatures', tiles: ['tem', 'per', 'at', 'ures'], theme: 'weather', clue: 'The degrees of heat present in substance or area' },
|
|
||||||
{ word: 'precipitation', tiles: ['pre', 'cip', 'ita', 'tion'], theme: 'weather', clue: 'Rain, snow, sleet, or hail falling to the ground' },
|
|
||||||
{ word: 'cloudburst', tiles: ['clo', 'ud', 'bur', 'st'], theme: 'weather', clue: 'A sudden, violent rainstorm' },
|
|
||||||
{ word: 'thunderstorm', tiles: ['thun', 'der', 'sto', 'rm'], theme: 'weather', clue: 'A storm with thunder and lightning and heavy rain' },
|
|
||||||
|
|
||||||
// Botany & Plants
|
|
||||||
{ word: 'photosynthesis', tiles: ['pho', 'tos', 'yn', 'thesis'], theme: 'plants', clue: 'Process by which green plants synthesize nutrients' },
|
|
||||||
{ word: 'evergreen', tiles: ['ev', 'er', 'gre', 'en'], theme: 'plants', clue: 'A plant that retains green leaves throughout the year' },
|
|
||||||
{ word: 'germination', tiles: ['ger', 'mi', 'na', 'tion'], theme: 'plants', clue: 'The development of a plant from a seed or spore' },
|
|
||||||
{ word: 'sunflowers', tiles: ['sun', 'flo', 'we', 'rs'], theme: 'plants', clue: 'Tall plants with very large, daisy-like yellow flowers' },
|
|
||||||
|
|
||||||
// Grit & Endeavor
|
|
||||||
{ word: 'determination', tiles: ['de', 'ter', 'mi', 'nation'], theme: 'endeavor', clue: 'Firmness of purpose; resoluteness' },
|
|
||||||
{ word: 'courageous', tiles: ['cou', 'rag', 'eo', 'us'], theme: 'endeavor', clue: 'Not deterred by danger or pain; brave' },
|
|
||||||
{ word: 'championship', tiles: ['cham', 'pion', 'sh', 'ip'], theme: 'endeavor', clue: 'A competition to decide the victor or champion' },
|
|
||||||
{ word: 'achievement', tiles: ['ach', 'iev', 'em', 'ent'], theme: 'endeavor', clue: 'A thing done successfully with effort, skill, or courage' },
|
|
||||||
{ word: 'perseverance', tiles: ['per', 'sev', 'era', 'nce'], theme: 'endeavor', clue: 'Persistence in doing something despite difficulty' },
|
|
||||||
|
|
||||||
// Oceanic Depths
|
|
||||||
{ word: 'oceanography', tiles: ['oce', 'ano', 'gra', 'phy'], theme: 'ocean', clue: 'The branch of science that deals with physical oceans' },
|
|
||||||
{ word: 'underwater', tiles: ['un', 'der', 'wa', 'ter'], theme: 'ocean', clue: 'Situated or occurring below water surface' },
|
|
||||||
{ word: 'exploration', tiles: ['ex', 'plo', 'ra', 'tion'], theme: 'ocean', clue: 'The action of traveling through an unfamiliar area' },
|
|
||||||
|
|
||||||
// Physics & Energy
|
|
||||||
{ word: 'electricity', tiles: ['el', 'ect', 'ri', 'city'], theme: 'physics', clue: 'Form of energy from charged elementary particles' },
|
|
||||||
{ word: 'radioactive', tiles: ['rad', 'ioa', 'cti', 've'], theme: 'physics', clue: 'Emitting ionizing radiation from nuclei' },
|
|
||||||
{ word: 'magnetism', tiles: ['mag', 'ne', 'ti', 'sm'], theme: 'physics', clue: 'A physical phenomenon produced by the motion of electric charge' },
|
|
||||||
|
|
||||||
// Additional 100+ unique words for Random Unlimited Generator
|
|
||||||
{ word: 'kaleidoscope', tiles: ['kal', 'eid', 'osc', 'ope'], theme: 'arts', clue: 'Optical instrument with reflective surfaces showing patterns' },
|
|
||||||
{ word: 'rollercoaster', tiles: ['rol', 'ler', 'coas', 'ter'], theme: 'fun', clue: 'Amusement park ride with steep slopes and curves' },
|
|
||||||
{ word: 'firecracker', tiles: ['fi', 'rec', 'rac', 'ker'], theme: 'fun', clue: 'A loud explosive firework' },
|
|
||||||
{ word: 'helicopter', tiles: ['he', 'li', 'cop', 'ter'], theme: 'travel', clue: 'Aircraft with horizontally rotating blades' },
|
|
||||||
{ word: 'motorcycle', tiles: ['mo', 'tor', 'cy', 'cle'], theme: 'travel', clue: 'Two-wheeled vehicle powered by an engine' },
|
|
||||||
{ word: 'candlestick', tiles: ['can', 'dle', 'sti', 'ck'], theme: 'craft', clue: 'A holder with a socket or spike for a candle' },
|
|
||||||
{ word: 'peppermint', tiles: ['pep', 'per', 'mi', 'nt'], theme: 'food', clue: 'A pungent herb or sweet flavoring' },
|
|
||||||
{ word: 'cheesecake', tiles: ['chee', 'se', 'ca', 'ke'], theme: 'food', clue: 'A rich sweet dessert made with soft cheese' },
|
|
||||||
{ word: 'gingerbread', tiles: ['gin', 'ger', 'bre', 'ad'], theme: 'food', clue: 'A cake or cookie flavored with ginger and molasses' },
|
|
||||||
{ word: 'blueberries', tiles: ['blue', 'ber', 'ri', 'es'], theme: 'food', clue: 'Small sweet blue-colored edible berries' },
|
|
||||||
{ word: 'strawberries', tiles: ['straw', 'ber', 'ri', 'es'], theme: 'food', clue: 'Sweet juicy red fruit with seeds on surface' },
|
|
||||||
{ word: 'waterproofing', tiles: ['wa', 'ter', 'pro', 'ofing'], theme: 'craft', clue: 'Making an object impervious to water' },
|
|
||||||
{ word: 'troubleshooter', tiles: ['trou', 'ble', 'shoo', 'ter'], theme: 'tech', clue: 'Someone who identifies and solves problems' },
|
|
||||||
{ word: 'heartwarming', tiles: ['hea', 'rtw', 'arm', 'ing'], theme: 'emotion', clue: 'Evoking feelings of happiness and contentment' },
|
|
||||||
{ word: 'groundbreaking', tiles: ['gro', 'und', 'bre', 'aking'], theme: 'endeavor', clue: 'Innovative; applying new ideas' },
|
|
||||||
{ word: 'brainstorming', tiles: ['bra', 'inst', 'orm', 'ing'], theme: 'mind', clue: 'Spontaneous group discussion to produce ideas' },
|
|
||||||
{ word: 'superpower', tiles: ['su', 'per', 'po', 'wer'], theme: 'society', clue: 'An exceptionally powerful nation or ability' },
|
|
||||||
{ word: 'leadership', tiles: ['lead', 'er', 'sh', 'ip'], theme: 'society', clue: 'The action of leading a group or organization' },
|
|
||||||
{ word: 'brotherhood', tiles: ['bro', 'ther', 'ho', 'od'], theme: 'society', clue: 'An association or community of people' },
|
|
||||||
{ word: 'windsurfers', tiles: ['wind', 'sur', 'fe', 'rs'], theme: 'sports', clue: 'Person who engages in board sailing' },
|
|
||||||
{ word: 'thermometer', tiles: ['ther', 'mo', 'me', 'ter'], theme: 'science', clue: 'Instrument for measuring temperature' },
|
|
||||||
{ word: 'barometer', tiles: ['ba', 'rom', 'et', 'er'], theme: 'science', clue: 'Instrument measuring atmospheric pressure' },
|
|
||||||
{ word: 'speedometer', tiles: ['spee', 'dom', 'et', 'er'], theme: 'science', clue: 'Instrument on a vehicle indicating speed' },
|
|
||||||
{ word: 'oceanfront', tiles: ['oce', 'anf', 'ro', 'nt'], theme: 'nature', clue: 'Land facing directly toward the ocean' },
|
|
||||||
{ word: 'rainforest', tiles: ['rain', 'fo', 're', 'st'], theme: 'nature', clue: 'A dense forest rich in biodiversity' },
|
|
||||||
{ word: 'waterfalls', tiles: ['wa', 'ter', 'fa', 'lls'], theme: 'nature', clue: 'Cascade of water falling from a height' },
|
|
||||||
{ word: 'dragonflies', tiles: ['dra', 'gon', 'fli', 'es'], theme: 'nature', clue: 'Fast-flying insects with long bodies and two pairs of wings' },
|
|
||||||
{ word: 'sandwiches', tiles: ['sand', 'wi', 'ch', 'es'], theme: 'food', clue: 'Slices of bread with filling between them' },
|
|
||||||
{ word: 'shortbread', tiles: ['sho', 'rtb', 're', 'ad'], theme: 'food', clue: 'A crisp rich crumbly biscuit' },
|
|
||||||
{ word: 'blacksmith', tiles: ['bla', 'cks', 'mi', 'th'], theme: 'craft', clue: 'A person who makes and repairs things in iron' },
|
|
||||||
{ word: 'silversmith', tiles: ['sil', 'ver', 'smi', 'th'], theme: 'craft', clue: 'A person who crafts objects out of silver' },
|
|
||||||
{ word: 'locksmiths', tiles: ['loc', 'ksm', 'it', 'hs'], theme: 'craft', clue: 'People who make and repair locks' },
|
|
||||||
{ word: 'woodworking', tiles: ['wood', 'wor', 'ki', 'ng'], theme: 'craft', clue: 'The activity or skill of making items from wood' },
|
|
||||||
{ word: 'shipbuilder', tiles: ['ship', 'bui', 'ld', 'er'], theme: 'craft', clue: 'A person or business that designs and constructs ships' },
|
|
||||||
{ word: 'watchmakers', tiles: ['wat', 'chm', 'ake', 'rs'], theme: 'craft', clue: 'Artisans who make and repair watches' },
|
|
||||||
{ word: 'matchmakers', tiles: ['mat', 'chm', 'ake', 'rs'], theme: 'society', clue: 'People who arrange marriages or partnerships' },
|
|
||||||
{ word: 'homemakers', tiles: ['hom', 'em', 'ake', 'rs'], theme: 'society', clue: 'People who manage a household' },
|
|
||||||
{ word: 'gatekeepers', tiles: ['gat', 'eke', 'ep', 'ers'], theme: 'society', clue: 'Attendants controlling access through an entrance' },
|
|
||||||
{ word: 'peacekeeper', tiles: ['pea', 'cek', 'eep', 'er'], theme: 'society', clue: 'A person maintaining peace, especially in conflict zones' },
|
|
||||||
{ word: 'bookkeeper', tiles: ['boo', 'kke', 'ep', 'er'], theme: 'business', clue: 'A person whose job is to keep financial records' },
|
|
||||||
{ word: 'shopkeeper', tiles: ['sho', 'pke', 'ep', 'er'], theme: 'business', clue: 'An owner or manager of a small shop' },
|
|
||||||
{ word: 'cheerleader', tiles: ['che', 'erl', 'ead', 'er'], theme: 'sports', clue: 'A member of a team that leads cheering' },
|
|
||||||
{ word: 'trendsetter', tiles: ['tre', 'nds', 'ett', 'er'], theme: 'society', clue: 'A person who leads the way in fashion or ideas' },
|
|
||||||
{ word: 'ghostwriter', tiles: ['gho', 'stw', 'rit', 'er'], theme: 'words', clue: 'A person hired to write literary or journalistic work' },
|
|
||||||
{ word: 'screenwriter', tiles: ['scr', 'een', 'wri', 'ter'], theme: 'arts', clue: 'A person who writes screenplays for films' },
|
|
||||||
{ word: 'playwrights', tiles: ['pla', 'ywr', 'igh', 'ts'], theme: 'arts', clue: 'People who write plays' },
|
|
||||||
{ word: 'songwriters', tiles: ['son', 'gwr', 'ite', 'rs'], theme: 'arts', clue: 'Musicians who write musical compositions and lyrics' },
|
|
||||||
{ word: 'headmasters', tiles: ['hea', 'dma', 'ste', 'rs'], theme: 'education', clue: 'Teachers in charge of a school' },
|
|
||||||
{ word: 'grandmaster', tiles: ['gra', 'ndm', 'ast', 'er'], theme: 'games', clue: 'The highest title awarded to a chess player' },
|
|
||||||
{ word: 'quarterback', tiles: ['qua', 'rte', 'rba', 'ck'], theme: 'sports', clue: 'A player in American football directing play' },
|
|
||||||
{ word: 'sweatshirts', tiles: ['swe', 'atsh', 'ir', 'ts'], theme: 'clothes', clue: 'Loose warm casual cotton pullover shirts' },
|
|
||||||
{ word: 'turtlenecks', tiles: ['tur', 'tle', 'nec', 'ks'], theme: 'clothes', clue: 'High, close-fitting turned-over collars' },
|
|
||||||
{ word: 'windbreaker', tiles: ['win', 'dbr', 'eak', 'er'], theme: 'clothes', clue: 'A wind-resistant lightweight jacket' },
|
|
||||||
{ word: 'silverback', tiles: ['sil', 'ver', 'ba', 'ck'], theme: 'nature', clue: 'An older mature male mountain gorilla' },
|
|
||||||
{ word: 'paddleboard', tiles: ['pad', 'dle', 'bo', 'ard'], theme: 'sports', clue: 'A long board propelled with a paddle' },
|
|
||||||
{ word: 'springboard', tiles: ['spr', 'ing', 'bo', 'ard'], theme: 'sports', clue: 'A flexible board used in diving or gymnastics' },
|
|
||||||
{ word: 'checkerboard', tiles: ['che', 'cke', 'rbo', 'ard'], theme: 'games', clue: 'A game board divided into sixty-four squares' },
|
|
||||||
{ word: 'blackboards', tiles: ['bla', 'ckb', 'oar', 'ds'], theme: 'education', clue: 'Dark reusable writing surfaces for chalk' },
|
|
||||||
{ word: 'whiteboards', tiles: ['whi', 'teb', 'oar', 'ds'], theme: 'education', clue: 'Glossy white boards for nonpermanent markers' },
|
|
||||||
{ word: 'noticeboards', tiles: ['not', 'ice', 'boa', 'rds'], theme: 'society', clue: 'Boards for displaying notices or advertisements' },
|
|
||||||
];
|
|
||||||
|
|
||||||
// Merge expanded word list (skip invalid entries with a warning instead of failing)
|
|
||||||
{
|
{
|
||||||
const existing = new Set(targetWordsPool.map(w => w.word));
|
const existing = new Set();
|
||||||
let added = 0;
|
let added = 0;
|
||||||
for (const item of extraWords) {
|
for (const item of extraWords) {
|
||||||
const problems = [];
|
const problems = [];
|
||||||
@@ -202,14 +17,14 @@ export const targetWordsPool = [
|
|||||||
if (new Set(item.tiles).size !== item.tiles.length) problems.push('repeated tile within word');
|
if (new Set(item.tiles).size !== item.tiles.length) problems.push('repeated tile within word');
|
||||||
if (!DICTIONARY_SET.has(item.word)) problems.push('not in runtime dictionary');
|
if (!DICTIONARY_SET.has(item.word)) problems.push('not in runtime dictionary');
|
||||||
if (problems.length) {
|
if (problems.length) {
|
||||||
console.warn(` Skipping extra word "${item.word}": ${problems.join(', ')}`);
|
console.warn(` Skipping target word "${item.word}": ${problems.join(', ')}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
existing.add(item.word);
|
existing.add(item.word);
|
||||||
targetWordsPool.push(item);
|
targetWordsPool.push(item);
|
||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
console.log(`Merged ${added} extra target words.`);
|
console.log(`Loaded and validated ${added} target words.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate pool integrity
|
// Validate pool integrity
|
||||||
|
|||||||
@@ -18985,7 +18985,6 @@ cyberpet
|
|||||||
cyberpets
|
cyberpets
|
||||||
cyberporn
|
cyberporn
|
||||||
cyberporns
|
cyberporns
|
||||||
cybersecurity
|
|
||||||
cyberspaces
|
cyberspaces
|
||||||
cyberwar
|
cyberwar
|
||||||
cyberwars
|
cyberwars
|
||||||
@@ -64439,7 +64438,6 @@ raindate
|
|||||||
raindates
|
raindates
|
||||||
raine
|
raine
|
||||||
raines
|
raines
|
||||||
rainforest
|
|
||||||
rainforests
|
rainforests
|
||||||
rainily
|
rainily
|
||||||
raininesses
|
raininesses
|
||||||
@@ -73098,7 +73096,6 @@ siluroid
|
|||||||
siluroids
|
siluroids
|
||||||
silvans
|
silvans
|
||||||
silvatic
|
silvatic
|
||||||
silverback
|
|
||||||
silverbacks
|
silverbacks
|
||||||
silverberries
|
silverberries
|
||||||
silverberry
|
silverberry
|
||||||
|
|||||||
@@ -5,6 +5,154 @@
|
|||||||
// - exactly 4 tiles, each >= 2 letters
|
// - exactly 4 tiles, each >= 2 letters
|
||||||
// - no repeated tile within a single word
|
// - no repeated tile within a single word
|
||||||
const RAW = `
|
const RAW = `
|
||||||
|
remarkable|re-mar-ka-ble|wonder|Worthy of attention; striking
|
||||||
|
unforgettable|un-for-get-table|wonder|Impossible to forget; memorable
|
||||||
|
photography|pho-to-gra-phy|wonder|The art or practice of taking photos
|
||||||
|
adventurous|ad-ven-tur-ous|wonder|Willing to take risks or try new things
|
||||||
|
inspiration|in-spi-ra-tion|wonder|A stimulus to creative thought or action
|
||||||
|
astronomy|as-tro-no-my|space|The branch of science dealing with space
|
||||||
|
gravitation|gra-vi-ta-tion|space|The force that attracts bodies toward mass
|
||||||
|
atmosphere|at-mo-sph-ere|space|The envelope of gases surrounding a planet
|
||||||
|
interstellar|in-ter-ste-llar|space|Occurring between stars
|
||||||
|
telescopic|tel-es-co-pic|space|Having the power for viewing distant objects
|
||||||
|
constellation|con-ste-lla-tion|space|A group of stars forming a pattern
|
||||||
|
stratosphere|stra-tos-phe-re|space|Layer of the atmosphere above troposphere
|
||||||
|
imagination|im-agi-na-tion|mind|The faculty of forming new ideas or images
|
||||||
|
understanding|un-der-stan-ding|mind|The ability to comprehend something
|
||||||
|
psychology|psy-cho-lo-gy|mind|The scientific study of mind and behavior
|
||||||
|
intelligence|in-tel-li-gence|mind|The ability to acquire and apply knowledge
|
||||||
|
consciousness|con-sci-ous-ness|mind|The state of being aware of surroundings
|
||||||
|
philosophy|phi-los-op-hy|mind|The study of fundamental nature of knowledge
|
||||||
|
thoughtfulness|thou-ght-ful-ness|mind|The state of thinking deeply or being caring
|
||||||
|
architecture|ar-chi-tec-ture|city|The art and practice of designing buildings
|
||||||
|
metropolitan|me-tro-pol-itan|city|Relating to a large, busy city
|
||||||
|
construction|con-stru-cti-on|city|The building of something typically large
|
||||||
|
neighborhood|neigh-bor-ho-od|city|A district or area forming a community
|
||||||
|
skyscraper|sky-sc-ra-per|city|A very tall building with many stories
|
||||||
|
masterpiece|mas-ter-pie-ce|arts|A work of outstanding artistry or skill
|
||||||
|
calligraphy|cal-lig-ra-phy|arts|Decorative handwriting or handwritten lettering
|
||||||
|
exhibition|ex-hi-bi-tion|arts|A public display of works of art or items
|
||||||
|
creativity|cre-at-iv-ity|arts|The use of the imagination or original ideas
|
||||||
|
choreography|cho-reo-gra-phy|arts|The sequence of steps and movements in dance
|
||||||
|
technology|tec-hno-lo-gy|tech|Application of scientific knowledge for practical aims
|
||||||
|
electronic|el-ect-ro-nic|tech|Having components like microchips or transistors
|
||||||
|
automation|au-to-ma-tion|tech|The use of largely automatic equipment in a system
|
||||||
|
cybersecurity|cy-ber-sec-urity|tech|Protection of computer systems from attack or theft
|
||||||
|
motherboard|mo-ther-bo-ard|tech|A printed circuit board containing principal components
|
||||||
|
celebration|cel-eb-ra-tion|society|The action of marking pleasure at an event
|
||||||
|
fellowship|fel-low-sh-ip|society|Friendly association, especially with shared interests
|
||||||
|
generosity|gen-ero-si-ty|society|The quality of being kind and generous
|
||||||
|
opportunity|op-por-tu-nity|society|A set of circumstances making something possible
|
||||||
|
marshmallow|mar-shm-all-ow|society|A sweet chewy confection made of sugar and gelatin
|
||||||
|
hospitality|hos-pit-al-ity|society|Friendly and generous reception of guests
|
||||||
|
friendship|fri-end-sh-ip|society|A state of mutual trust and support between people
|
||||||
|
biodiversity|bio-di-ver-sity|nature|The variety of life in the world or habitat
|
||||||
|
environment|en-vi-ron-ment|nature|The surroundings or conditions in which one lives
|
||||||
|
caterpillar|cat-er-pil-lar|nature|The larval stage of a butterfly or moth
|
||||||
|
wilderness|wil-der-ne-ss|nature|An uncultivated, uninhabited, and hospitable region
|
||||||
|
chameleon|cha-me-le-on|nature|A lizard capable of changing skin color
|
||||||
|
hummingbird|hum-ming-bi-rd|nature|Small nectar-feeding bird with hovering flight
|
||||||
|
woodpecker|wood-pe-ck-er|nature|A bird with a strong beak for drilling into wood
|
||||||
|
butterflies|but-ter-fli-es|nature|Insects with large, often brightly colored wings
|
||||||
|
grasshoppers|grass-hop-pe-rs|nature|Plant-eating insect with powerful hind legs for jumping
|
||||||
|
mysterious|mys-ter-io-us|mystery|Difficult or impossible to understand or explain
|
||||||
|
supernatural|su-per-nat-ural|mystery|Attributed to some force beyond scientific understanding
|
||||||
|
enchanted|en-cha-nt-ed|mystery|Placed under a spell; bewitched
|
||||||
|
miraculous|mi-rac-ul-ous|mystery|Occurring through divine or extraordinary intervention
|
||||||
|
equivalent|equ-iv-al-ent|science|Equal in value, amount, function, or meaning
|
||||||
|
hypothesis|hy-pot-he-sis|science|A proposed explanation made on limited evidence
|
||||||
|
laboratory|lab-ora-to-ry|science|A room or building equipped for scientific experiments
|
||||||
|
microscope|mi-cro-sco-pe|science|Optical instrument for magnifying tiny objects
|
||||||
|
phenomenon|phe-nom-en-on|science|A remarkable fact or situation that is observed to happen
|
||||||
|
dictionary|dic-tio-na-ry|words|A reference book on words and definitions
|
||||||
|
manuscript|man-us-cr-ipt|words|An author text that has not yet been printed
|
||||||
|
encyclopedia|en-cy-clo-pedia|words|A book or set providing information on many subjects
|
||||||
|
literature|li-ter-at-ure|words|Written works, especially those considered of superior merit
|
||||||
|
backpacker|back-pa-ck-er|travel|A traveler who journeys carrying their belongings
|
||||||
|
locomotive|lo-co-mo-tive|travel|A powered rail vehicle used for pulling trains
|
||||||
|
continental|con-tin-en-tal|travel|Forming or belonging to a continent
|
||||||
|
navigation|na-vi-ga-tion|travel|The process of accurately ascertaining one position and course
|
||||||
|
voyagers|vo-ya-ge-rs|travel|People who go on a long journey, typically by sea or space
|
||||||
|
meteorology|me-teo-rol-ogy|weather|The science of atmospheric processes and forecasting
|
||||||
|
temperatures|tem-per-at-ures|weather|The degrees of heat present in substance or area
|
||||||
|
precipitation|pre-cip-ita-tion|weather|Rain, snow, sleet, or hail falling to the ground
|
||||||
|
cloudburst|clo-ud-bur-st|weather|A sudden, violent rainstorm
|
||||||
|
thunderstorm|thun-der-sto-rm|weather|A storm with thunder and lightning and heavy rain
|
||||||
|
photosynthesis|pho-tos-yn-thesis|plants|Process by which green plants synthesize nutrients
|
||||||
|
evergreen|ev-er-gre-en|plants|A plant that retains green leaves throughout the year
|
||||||
|
germination|ger-mi-na-tion|plants|The development of a plant from a seed or spore
|
||||||
|
sunflowers|sun-flo-we-rs|plants|Tall plants with very large, daisy-like yellow flowers
|
||||||
|
determination|de-ter-mi-nation|endeavor|Firmness of purpose; resoluteness
|
||||||
|
courageous|cou-rag-eo-us|endeavor|Not deterred by danger or pain; brave
|
||||||
|
championship|cham-pion-sh-ip|endeavor|A competition to decide the victor or champion
|
||||||
|
achievement|ach-iev-em-ent|endeavor|A thing done successfully with effort, skill, or courage
|
||||||
|
perseverance|per-sev-era-nce|endeavor|Persistence in doing something despite difficulty
|
||||||
|
oceanography|oce-ano-gra-phy|ocean|The branch of science that deals with physical oceans
|
||||||
|
underwater|un-der-wa-ter|ocean|Situated or occurring below water surface
|
||||||
|
exploration|ex-plo-ra-tion|ocean|The action of traveling through an unfamiliar area
|
||||||
|
electricity|el-ect-ri-city|physics|Form of energy from charged elementary particles
|
||||||
|
radioactive|rad-ioa-cti-ve|physics|Emitting ionizing radiation from nuclei
|
||||||
|
magnetism|mag-ne-ti-sm|physics|A physical phenomenon produced by the motion of electric charge
|
||||||
|
kaleidoscope|kal-eid-osc-ope|arts|Optical instrument with reflective surfaces showing patterns
|
||||||
|
rollercoaster|rol-ler-coas-ter|fun|Amusement park ride with steep slopes and curves
|
||||||
|
firecracker|fi-rec-rac-ker|fun|A loud explosive firework
|
||||||
|
helicopter|he-li-cop-ter|travel|Aircraft with horizontally rotating blades
|
||||||
|
motorcycle|mo-tor-cy-cle|travel|Two-wheeled vehicle powered by an engine
|
||||||
|
candlestick|can-dle-sti-ck|craft|A holder with a socket or spike for a candle
|
||||||
|
peppermint|pep-per-mi-nt|food|A pungent herb or sweet flavoring
|
||||||
|
cheesecake|chee-se-ca-ke|food|A rich sweet dessert made with soft cheese
|
||||||
|
gingerbread|gin-ger-bre-ad|food|A cake or cookie flavored with ginger and molasses
|
||||||
|
blueberries|blue-ber-ri-es|food|Small sweet blue-colored edible berries
|
||||||
|
strawberries|straw-ber-ri-es|food|Sweet juicy red fruit with seeds on surface
|
||||||
|
waterproofing|wa-ter-pro-ofing|craft|Making an object impervious to water
|
||||||
|
troubleshooter|trou-ble-shoo-ter|tech|Someone who identifies and solves problems
|
||||||
|
heartwarming|hea-rtw-arm-ing|emotion|Evoking feelings of happiness and contentment
|
||||||
|
groundbreaking|gro-und-bre-aking|endeavor|Innovative; applying new ideas
|
||||||
|
brainstorming|bra-inst-orm-ing|mind|Spontaneous group discussion to produce ideas
|
||||||
|
superpower|su-per-po-wer|society|An exceptionally powerful nation or ability
|
||||||
|
leadership|lead-er-sh-ip|society|The action of leading a group or organization
|
||||||
|
brotherhood|bro-ther-ho-od|society|An association or community of people
|
||||||
|
windsurfers|wind-sur-fe-rs|sports|Person who engages in board sailing
|
||||||
|
thermometer|ther-mo-me-ter|science|Instrument for measuring temperature
|
||||||
|
barometer|ba-rom-et-er|science|Instrument measuring atmospheric pressure
|
||||||
|
speedometer|spee-dom-et-er|science|Instrument on a vehicle indicating speed
|
||||||
|
oceanfront|oce-anf-ro-nt|nature|Land facing directly toward the ocean
|
||||||
|
rainforest|rain-fo-re-st|nature|A dense forest rich in biodiversity
|
||||||
|
waterfalls|wa-ter-fa-lls|nature|Cascade of water falling from a height
|
||||||
|
dragonflies|dra-gon-fli-es|nature|Fast-flying insects with long bodies and two pairs of wings
|
||||||
|
sandwiches|sand-wi-ch-es|food|Slices of bread with filling between them
|
||||||
|
shortbread|sho-rtb-re-ad|food|A crisp rich crumbly biscuit
|
||||||
|
blacksmith|bla-cks-mi-th|craft|A person who makes and repairs things in iron
|
||||||
|
silversmith|sil-ver-smi-th|craft|A person who crafts objects out of silver
|
||||||
|
locksmiths|loc-ksm-it-hs|craft|People who make and repair locks
|
||||||
|
woodworking|wood-wor-ki-ng|craft|The activity or skill of making items from wood
|
||||||
|
shipbuilder|ship-bui-ld-er|craft|A person or business that designs and constructs ships
|
||||||
|
watchmakers|wat-chm-ake-rs|craft|Artisans who make and repair watches
|
||||||
|
matchmakers|mat-chm-ake-rs|society|People who arrange marriages or partnerships
|
||||||
|
homemakers|hom-em-ake-rs|society|People who manage a household
|
||||||
|
gatekeepers|gat-eke-ep-ers|society|Attendants controlling access through an entrance
|
||||||
|
peacekeeper|pea-cek-eep-er|society|A person maintaining peace, especially in conflict zones
|
||||||
|
bookkeeper|boo-kke-ep-er|business|A person whose job is to keep financial records
|
||||||
|
shopkeeper|sho-pke-ep-er|business|An owner or manager of a small shop
|
||||||
|
cheerleader|che-erl-ead-er|sports|A member of a team that leads cheering
|
||||||
|
trendsetter|tre-nds-ett-er|society|A person who leads the way in fashion or ideas
|
||||||
|
ghostwriter|gho-stw-rit-er|words|A person hired to write literary or journalistic work
|
||||||
|
screenwriter|scr-een-wri-ter|arts|A person who writes screenplays for films
|
||||||
|
playwrights|pla-ywr-igh-ts|arts|People who write plays
|
||||||
|
songwriters|son-gwr-ite-rs|arts|Musicians who write musical compositions and lyrics
|
||||||
|
headmasters|hea-dma-ste-rs|education|Teachers in charge of a school
|
||||||
|
grandmaster|gra-ndm-ast-er|games|The highest title awarded to a chess player
|
||||||
|
quarterback|qua-rte-rba-ck|sports|A player in American football directing play
|
||||||
|
sweatshirts|swe-atsh-ir-ts|clothes|Loose warm casual cotton pullover shirts
|
||||||
|
turtlenecks|tur-tle-nec-ks|clothes|High, close-fitting turned-over collars
|
||||||
|
windbreaker|win-dbr-eak-er|clothes|A wind-resistant lightweight jacket
|
||||||
|
silverback|sil-ver-ba-ck|nature|An older mature male mountain gorilla
|
||||||
|
paddleboard|pad-dle-bo-ard|sports|A long board propelled with a paddle
|
||||||
|
springboard|spr-ing-bo-ard|sports|A flexible board used in diving or gymnastics
|
||||||
|
checkerboard|che-cke-rbo-ard|games|A game board divided into sixty-four squares
|
||||||
|
blackboards|bla-ckb-oar-ds|education|Dark reusable writing surfaces for chalk
|
||||||
|
whiteboards|whi-teb-oar-ds|education|Glossy white boards for nonpermanent markers
|
||||||
|
noticeboards|not-ice-boa-rds|society|Boards for displaying notices or advertisements
|
||||||
alligator|al-li-ga-tor|animals|Large reptile of southern swamps
|
alligator|al-li-ga-tor|animals|Large reptile of southern swamps
|
||||||
armadillo|ar-ma-dil-lo|animals|Burrowing mammal with a bony armored shell
|
armadillo|ar-ma-dil-lo|animals|Burrowing mammal with a bony armored shell
|
||||||
crocodile|cro-co-di-le|animals|Large aquatic reptile with powerful jaws
|
crocodile|cro-co-di-le|animals|Large aquatic reptile with powerful jaws
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import wordlistEnglish from 'wordlist-english';
|
import wordlistEnglish from 'wordlist-english';
|
||||||
|
import { extraWords } from './extra-words.mjs';
|
||||||
|
|
||||||
const COMBO_WORDS_FILE = new URL('./combo-words.txt', import.meta.url);
|
const COMBO_WORDS_FILE = new URL('./combo-words.txt', import.meta.url);
|
||||||
|
|
||||||
@@ -64,6 +65,10 @@ export function buildWordSet({ includeComboWords = false } = {}) {
|
|||||||
for (const w of PROPER_WORD_ALLOWLIST) {
|
for (const w of PROPER_WORD_ALLOWLIST) {
|
||||||
if (isAcceptable(w)) set.add(w);
|
if (isAcceptable(w)) set.add(w);
|
||||||
}
|
}
|
||||||
|
for (const item of extraWords) {
|
||||||
|
const w = item.word.toLowerCase();
|
||||||
|
if (isAcceptable(w)) set.add(w);
|
||||||
|
}
|
||||||
if (includeComboWords) {
|
if (includeComboWords) {
|
||||||
for (const w of loadComboWords()) {
|
for (const w of loadComboWords()) {
|
||||||
if (isAcceptable(w)) set.add(w);
|
if (isAcceptable(w)) set.add(w);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
126
src/engine/analytics.js
Normal file
126
src/engine/analytics.js
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* Google Analytics (gtag.js) Event Tracking for Quartiles
|
||||||
|
* Supports both standard GA4 recommended gaming events (level_start, level_end)
|
||||||
|
* and custom events (game_start, game_finish).
|
||||||
|
*/
|
||||||
|
|
||||||
|
let currentPuzzleId = null;
|
||||||
|
let puzzleStartTime = Date.now();
|
||||||
|
const completedMilestones = new Set();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Categorizes a puzzle into daily, unlimited, or custom
|
||||||
|
*/
|
||||||
|
export function getPuzzleType(puzzle) {
|
||||||
|
if (!puzzle?.id) return 'unknown';
|
||||||
|
if (puzzle.id.startsWith('daily-')) return 'daily';
|
||||||
|
if (puzzle.id.startsWith('custom-') || puzzle.id.startsWith('unlimited-')) return 'unlimited';
|
||||||
|
if (puzzle.id.startsWith('user-')) return 'custom';
|
||||||
|
return 'daily';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely calls window.gtag if defined
|
||||||
|
*/
|
||||||
|
function sendGtag(command, eventName, params = {}) {
|
||||||
|
try {
|
||||||
|
if (typeof window !== 'undefined' && typeof window.gtag === 'function') {
|
||||||
|
window.gtag(command, eventName, params);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Analytics tracking error:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks when a player starts or resumes a puzzle
|
||||||
|
* @param {Object} puzzle - The puzzle object
|
||||||
|
* @param {Object} options - Options including isResumed
|
||||||
|
*/
|
||||||
|
export function trackGameStart(puzzle, { isResumed = false, isCompleted = false } = {}) {
|
||||||
|
if (!puzzle?.id) return;
|
||||||
|
|
||||||
|
// If loading the exact same puzzle instance and already tracked, skip duplicate start
|
||||||
|
if (currentPuzzleId === puzzle.id && isResumed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPuzzleId = puzzle.id;
|
||||||
|
puzzleStartTime = Date.now();
|
||||||
|
completedMilestones.clear();
|
||||||
|
|
||||||
|
// If resumed and already completed in past session, record milestone to prevent duplicate finish
|
||||||
|
if (isCompleted) {
|
||||||
|
completedMilestones.add(`${puzzle.id}:expert`);
|
||||||
|
completedMilestones.add(`${puzzle.id}:perfect`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const puzzleType = getPuzzleType(puzzle);
|
||||||
|
const totalWords = puzzle.words?.length || puzzle.wordCount || 0;
|
||||||
|
const maxScore = puzzle.maxPossibleScore || 0;
|
||||||
|
|
||||||
|
// Custom event: game_start
|
||||||
|
sendGtag('event', 'game_start', {
|
||||||
|
puzzle_id: puzzle.id,
|
||||||
|
puzzle_type: puzzleType,
|
||||||
|
puzzle_title: puzzle.title || puzzle.id,
|
||||||
|
puzzle_theme: puzzle.theme || 'General',
|
||||||
|
puzzle_difficulty: puzzle.difficulty || 'Normal',
|
||||||
|
total_words: totalWords,
|
||||||
|
max_score: maxScore,
|
||||||
|
is_resumed: isResumed
|
||||||
|
});
|
||||||
|
|
||||||
|
// Standard GA4 event: level_start
|
||||||
|
sendGtag('event', 'level_start', {
|
||||||
|
level_name: puzzle.title || puzzle.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks when a player finishes a puzzle
|
||||||
|
* @param {Object} gameState - The GameStateManager instance
|
||||||
|
* @param {'perfect' | 'expert' | 'revealed'} completionType - The type of completion
|
||||||
|
*/
|
||||||
|
export function trackGameFinish(gameState, completionType) {
|
||||||
|
const puzzle = gameState?.currentPuzzle;
|
||||||
|
if (!puzzle?.id) return;
|
||||||
|
|
||||||
|
const milestoneKey = `${puzzle.id}:${completionType}`;
|
||||||
|
if (completedMilestones.has(milestoneKey)) return;
|
||||||
|
completedMilestones.add(milestoneKey);
|
||||||
|
|
||||||
|
const puzzleType = getPuzzleType(puzzle);
|
||||||
|
const totalWords = puzzle.words?.length || puzzle.wordCount || 0;
|
||||||
|
const maxScore = puzzle.maxPossibleScore || 0;
|
||||||
|
const wordsFound = gameState.foundWords ? gameState.foundWords.size : 0;
|
||||||
|
const quartilesFound = typeof gameState.getTargetQuartilesSolvedCount === 'function'
|
||||||
|
? gameState.getTargetQuartilesSolvedCount()
|
||||||
|
: 0;
|
||||||
|
const rank = typeof gameState.getRank === 'function'
|
||||||
|
? gameState.getRank()?.current?.name || 'Unknown'
|
||||||
|
: 'Unknown';
|
||||||
|
const durationSeconds = Math.max(1, Math.round((Date.now() - puzzleStartTime) / 1000));
|
||||||
|
|
||||||
|
// Custom event: game_finish
|
||||||
|
sendGtag('event', 'game_finish', {
|
||||||
|
puzzle_id: puzzle.id,
|
||||||
|
puzzle_type: puzzleType,
|
||||||
|
puzzle_title: puzzle.title || puzzle.id,
|
||||||
|
completion_type: completionType,
|
||||||
|
score: gameState.score || 0,
|
||||||
|
max_score: maxScore,
|
||||||
|
words_found: wordsFound,
|
||||||
|
total_words: totalWords,
|
||||||
|
quartiles_found: quartilesFound,
|
||||||
|
rank: rank,
|
||||||
|
duration_seconds: durationSeconds
|
||||||
|
});
|
||||||
|
|
||||||
|
// Standard GA4 event: level_end
|
||||||
|
sendGtag('event', 'level_end', {
|
||||||
|
level_name: puzzle.title || puzzle.id,
|
||||||
|
success: completionType !== 'revealed',
|
||||||
|
score: gameState.score || 0
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import { gameState } from './state/game-state.js';
|
|||||||
import { getDailyPuzzle, resolveBuiltInPuzzle, toDateString } from './engine/daily.js';
|
import { getDailyPuzzle, resolveBuiltInPuzzle, toDateString } from './engine/daily.js';
|
||||||
import { sound } from './engine/audio.js';
|
import { sound } from './engine/audio.js';
|
||||||
import { fireConfetti, fireConfettiShow } from './engine/confetti.js';
|
import { fireConfetti, fireConfettiShow } from './engine/confetti.js';
|
||||||
|
import { trackGameFinish } from './engine/analytics.js';
|
||||||
|
|
||||||
import { createHeader } from './components/Header.js';
|
import { createHeader } from './components/Header.js';
|
||||||
import { createScoreRankBar } from './components/ScoreRankBar.js';
|
import { createScoreRankBar } from './components/ScoreRankBar.js';
|
||||||
@@ -249,9 +250,11 @@ async function initApp() {
|
|||||||
// Check rank progression
|
// Check rank progression
|
||||||
const currentRank = gameState.getRank();
|
const currentRank = gameState.getRank();
|
||||||
if (!prevRank.isPerfect && currentRank.isPerfect) {
|
if (!prevRank.isPerfect && currentRank.isPerfect) {
|
||||||
|
trackGameFinish(gameState, 'perfect');
|
||||||
// Perfect outranks Expert; let the 5/5 bonus fanfare finish first if it just played
|
// Perfect outranks Expert; let the 5/5 bonus fanfare finish first if it just played
|
||||||
setTimeout(celebratePerfect, result.bonusUnlocked ? 1600 : 500);
|
setTimeout(celebratePerfect, result.bonusUnlocked ? 1600 : 500);
|
||||||
} else if (!prevRank.isExpert && currentRank.isExpert) {
|
} else if (!prevRank.isExpert && currentRank.isExpert) {
|
||||||
|
trackGameFinish(gameState, 'expert');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
sound.playRankUp();
|
sound.playRankUp();
|
||||||
gameState.notifyToast('🏆 EXPERT RANK ACHIEVED! Outstanding!', 'quartile', 4000);
|
gameState.notifyToast('🏆 EXPERT RANK ACHIEVED! Outstanding!', 'quartile', 4000);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { getRankInfo, QUARTILE_COMPLETION_BONUS, POINTS_BY_TILE_COUNT } from '../engine/constants.js';
|
import { getRankInfo, QUARTILE_COMPLETION_BONUS, POINTS_BY_TILE_COUNT } from '../engine/constants.js';
|
||||||
import { isAcceptedWord } from '../data/lexicon.js';
|
import { isAcceptedWord } from '../data/lexicon.js';
|
||||||
import { resolveBuiltInPuzzle, isBuiltInPuzzleId, getDailyPuzzle, toDateString } from '../engine/daily.js';
|
import { resolveBuiltInPuzzle, isBuiltInPuzzleId, getDailyPuzzle, toDateString } from '../engine/daily.js';
|
||||||
|
import { trackGameStart, trackGameFinish } from '../engine/analytics.js';
|
||||||
|
|
||||||
// Identifies the exact board, so saves from an older version of a puzzle id are ignored
|
// Identifies the exact board, so saves from an older version of a puzzle id are ignored
|
||||||
function boardSignature(puzzle) {
|
function boardSignature(puzzle) {
|
||||||
@@ -80,6 +81,14 @@ class GameStateManager {
|
|||||||
// Organize board tiles according to lock state
|
// Organize board tiles according to lock state
|
||||||
this.reorganizeBoard();
|
this.reorganizeBoard();
|
||||||
|
|
||||||
|
// Track game start in analytics
|
||||||
|
const rank = this.getRank();
|
||||||
|
const isCompleted = rank.isPerfect || this.isRevealed;
|
||||||
|
trackGameStart(puzzle, {
|
||||||
|
isResumed: this.foundWords.size > 0,
|
||||||
|
isCompleted
|
||||||
|
});
|
||||||
|
|
||||||
this.notify();
|
this.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,6 +621,7 @@ class GameStateManager {
|
|||||||
revealAllWords() {
|
revealAllWords() {
|
||||||
this.isRevealed = true;
|
this.isRevealed = true;
|
||||||
this.saveProgress();
|
this.saveProgress();
|
||||||
|
trackGameFinish(this, 'revealed');
|
||||||
this.notify();
|
this.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"version": "1.0.4"
|
"version": "1.0.5"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user