clone

a browser grid puzzle game where you push words around to rewrite the rules of each level

main
miau-is-true / src / scenes / warning-lines.js
warning-lines.js 3.9K
1function sentenceCase(value) {2 const text = String(value || '').trim();3 if (!text) return 'Unknown words';4 const normalized = /^[A-Z0-9 _-]+$/.test(text) ? text.toLowerCase() : text;5 return normalized.charAt(0).toUpperCase() + normalized.slice(1);6}78function warningProof(pack, warning) {9 const levels = Array.isArray(pack?.levels) ? pack.levels : [];10 const index = levels.findIndex(level => level?.id === warning?.levelId);11 const proof = index >= 0 ? `Proof ${index + 1}` : 'Proof';12 const title = sentenceCase(warning?.levelTitle || levels[index]?.title || warning?.levelId);13 return `${proof}, ${title}`;14}1516function warningBody(warning) {17 const word = String(warning?.word || '').toUpperCase();18 const sentence = String(warning?.sentence || '').trim();19 const message = String(warning?.message || '').replaceAll('\u00b7', ',');20 const propertyElsewhere = /declared as a property|property in another proof/i.test(message);21 const thingElsewhere = /thing in another proof|used as a thing here/i.test(message);22 if (sentence) {23 const parts = sentence.split(/\s+IS\s+/i);24 const subject = parts[0]?.trim();25 const predicate = parts[1]?.trim();26 if (subject && predicate && predicate.toUpperCase() === word) {27 const article = /^[AEIOU]/i.test(word) ? 'an' : 'a';28 const consequence = `${sentence} would turn every ${subject.toLowerCase()} into ${article} ${word}.`;29 if (propertyElsewhere && thingElsewhere) return `${word} is a rule word in one proof and a thing in another, so ${consequence}`;30 if (propertyElsewhere) return `${word} is a rule word in another proof but not here, so ${consequence}`;31 if (thingElsewhere) return `${word} is a thing in another proof, so ${consequence}`;32 return `${word} isn't a rule word here, so ${consequence}`;33 }34 }35 if (propertyElsewhere && thingElsewhere) return `${word} is a rule word in one proof and a thing in another.`;36 if (propertyElsewhere) return `${word} is a rule word in another proof but not here.`;37 if (thingElsewhere) return `${word} is a thing in another proof but not here.`;38 if (/not a known noun or declared property|not a declared property|not a known noun/i.test(message)) return `${word} isn't a rule word or a thing in this proof, so it can't do anything.`;39 return message || `${word} may not behave as a rule.`;40}4142/** Build the plain language lines shared by Gift and Workshop warning cards. */43export function warningLines(pack, warnings = []) {44 const lines = [];45 const loose = new Map();46 for (const warning of warnings) {47 // These notes describe pack or proof metadata, not loose rule words.48 // Preserve their authored copy, including punctuation used in validation hints.49 if (['RULES', 'TITLE', 'WORLD'].includes(String(warning?.word || '').toUpperCase()) && warning?.message) {50 const prefix = warning.levelId ? `${warningProof(pack, warning)}: ` : '';51 lines.push(`${prefix}${warning.message}`);52 continue;53 }54 if (!warning.sentence) {55 if (/thing in another proof|used as a thing here|declared as a property|property in another proof/i.test(String(warning.message || ''))) {56 lines.push(`${warningProof(pack, warning)}: ${warningBody(warning)}`);57 continue;58 }59 const key = `${warning.levelId || ''}\u0000${warning.levelTitle || ''}`;60 const group = loose.get(key) || { proof: warningProof(pack, warning), words: [] };61 group.words.push(String(warning.word || '').toUpperCase());62 loose.set(key, group);63 continue;64 }65 lines.push(`${warningProof(pack, warning)}: ${warningBody(warning)}`);66 }67 for (const group of loose.values()) {68 const words = [...new Set(group.words)];69 const joined = words.length > 1 ? `${words.slice(0, -1).join(', ')} and ${words.at(-1)}` : words[0];70 lines.push(`${group.proof}: ${joined} ${words.length === 1 ? "isn't" : "aren't"} rule words or things in this proof, so ${words.length === 1 ? "it can't" : "they can't"} do anything.`);71 }72 return lines;73}