solvers
This commit is contained in:
@@ -19,6 +19,20 @@ for (const raw of wordlistEnglish.english) {
|
||||
}
|
||||
}
|
||||
|
||||
// Commonness tiers for intelligent word quality ranking
|
||||
const t10 = new Set(wordlistEnglish['english/10'] || []);
|
||||
const t20 = new Set(wordlistEnglish['english/20'] || []);
|
||||
const t35 = new Set(wordlistEnglish['english/35'] || []);
|
||||
const t50 = new Set(wordlistEnglish['english/50'] || []);
|
||||
|
||||
function getCommonnessScore(word) {
|
||||
if (t10.has(word)) return 4;
|
||||
if (t20.has(word)) return 3;
|
||||
if (t35.has(word)) return 2;
|
||||
if (t50.has(word)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Build prefix set for super fast solver pruning (up to 6 letters)
|
||||
const prefixSet = new Set();
|
||||
for (const word of cleanWordSet) {
|
||||
@@ -28,7 +42,7 @@ for (const word of cleanWordSet) {
|
||||
}
|
||||
|
||||
// Function to solve a 20-tile board and return all valid words and paths
|
||||
export function solveBoard(quartets) {
|
||||
export function solveBoard(quartets, maxWords = 30) {
|
||||
const tiles = quartets.flat();
|
||||
const foundMap = new Map();
|
||||
|
||||
@@ -55,12 +69,10 @@ export function solveBoard(quartets) {
|
||||
|
||||
search('', []);
|
||||
|
||||
const quartilesList = quartets.map(q => q.join(''));
|
||||
const quartilesList = quartets.map(q => q.join('').toLowerCase());
|
||||
const quartileSet = new Set(quartilesList);
|
||||
|
||||
const words = [];
|
||||
let totalScore = 0;
|
||||
let quartileCount = 0;
|
||||
let words = [];
|
||||
|
||||
for (const [word, path] of foundMap.entries()) {
|
||||
const tileSegments = path.map(idx => tiles[idx]);
|
||||
@@ -69,9 +81,6 @@ export function solveBoard(quartets) {
|
||||
const isTargetQuartile = quartileSet.has(word);
|
||||
const isQuartile = tileCount === 4;
|
||||
|
||||
if (isQuartile) quartileCount++;
|
||||
totalScore += points;
|
||||
|
||||
words.push({
|
||||
word,
|
||||
points,
|
||||
@@ -83,16 +92,37 @@ export function solveBoard(quartets) {
|
||||
});
|
||||
}
|
||||
|
||||
// Add 40 bonus points for finding all 5 quartiles
|
||||
const maxPossibleScore = totalScore + 40;
|
||||
// Sort candidate words:
|
||||
// 1. Target quartiles always first (all 5 guaranteed)
|
||||
// 2. Tile count descending (4-tiles > 3-tiles > 2-tiles > 1-tile)
|
||||
// 3. Commonness score descending (familiar words first)
|
||||
// 4. Word length descending
|
||||
// 5. Alphabetical
|
||||
words.sort((a, b) => {
|
||||
if (a.isTargetQuartile !== b.isTargetQuartile) return a.isTargetQuartile ? -1 : 1;
|
||||
if (a.tileCount !== b.tileCount) return b.tileCount - a.tileCount;
|
||||
const ca = getCommonnessScore(a.word);
|
||||
const cb = getCommonnessScore(b.word);
|
||||
if (ca !== cb) return cb - ca;
|
||||
if (b.word.length !== a.word.length) return b.word.length - a.word.length;
|
||||
return a.word.localeCompare(b.word);
|
||||
});
|
||||
|
||||
// Sort words: Quartiles first, then by points descending, then alphabetically
|
||||
// Cap words at maxWords (default: 30)
|
||||
if (maxWords && words.length > maxWords) {
|
||||
words = words.slice(0, maxWords);
|
||||
}
|
||||
|
||||
// Final display sorting: Target quartiles first, then points desc, then alphabetical
|
||||
words.sort((a, b) => {
|
||||
if (a.isTargetQuartile !== b.isTargetQuartile) return a.isTargetQuartile ? -1 : 1;
|
||||
if (b.points !== a.points) return b.points - a.points;
|
||||
return a.word.localeCompare(b.word);
|
||||
});
|
||||
|
||||
const totalBaseScore = words.reduce((sum, w) => sum + w.points, 0);
|
||||
const maxPossibleScore = totalBaseScore + 40; // 40 bonus points for all 5 quartiles
|
||||
|
||||
return {
|
||||
tiles,
|
||||
quartets,
|
||||
@@ -100,7 +130,7 @@ export function solveBoard(quartets) {
|
||||
words,
|
||||
wordCount: words.length,
|
||||
quartileCount: 5,
|
||||
totalBaseScore: totalScore,
|
||||
totalBaseScore,
|
||||
maxPossibleScore
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user