Compare commits

...

4 Commits

Author SHA1 Message Date
Hördle Bot
223eb62973 Bump version to 0.1.6.15 2025-12-05 20:13:31 +01:00
Hördle Bot
dc4bdd36c7 Fix textarea alignment: add box-sizing border-box to prevent overflow 2025-12-05 20:13:27 +01:00
Hördle Bot
136f881252 Bump version to 0.1.6.14 2025-12-05 18:43:15 +01:00
Hördle Bot
fd11048f2c Fix daily puzzle selection: always select from songs with minimum activations 2025-12-05 18:43:09 +01:00
3 changed files with 33 additions and 38 deletions

View File

@@ -681,7 +681,8 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
fontFamily: 'inherit', fontFamily: 'inherit',
resize: 'vertical', resize: 'vertical',
marginBottom: '0.5rem', marginBottom: '0.5rem',
display: 'block' // Ensure block display for proper alignment display: 'block',
boxSizing: 'border-box' // Ensure padding and border are included in width
}} }}
disabled={commentSending} disabled={commentSending}
/> />

View File

@@ -29,9 +29,7 @@ export async function getOrCreateDailyPuzzle(genre: Genre | null = null) {
const allSongs = await prisma.song.findMany({ const allSongs = await prisma.song.findMany({
where: whereClause, where: whereClause,
include: { include: {
puzzles: { puzzles: true, // Load ALL puzzles, not just for this genre (to use total activations)
where: { genreId: genreId }
},
}, },
}); });
@@ -40,28 +38,24 @@ export async function getOrCreateDailyPuzzle(genre: Genre | null = null) {
return null; return null;
} }
// Calculate weights // Find songs with the minimum number of activations (all puzzles, not just for this genre)
const weightedSongs = allSongs.map(song => ({ // Only select from songs with the fewest activations to ensure fair distribution
const songsWithActivations = allSongs.map(song => ({
song, song,
weight: 1.0 / (song.puzzles.length + 1), activations: song.puzzles.length,
})); }));
// Calculate total weight // Find minimum activations
const totalWeight = weightedSongs.reduce((sum, item) => sum + item.weight, 0); const minActivations = Math.min(...songsWithActivations.map(item => item.activations));
// Pick a random song based on weights using cumulative weights // Filter to only songs with minimum activations
// This ensures proper distribution and handles edge cases const songsWithMinActivations = songsWithActivations
let random = Math.random() * totalWeight; .filter(item => item.activations === minActivations)
let selectedSong = weightedSongs[weightedSongs.length - 1].song; // Fallback to last song .map(item => item.song);
let cumulativeWeight = 0; // Randomly select from songs with minimum activations
for (const item of weightedSongs) { const randomIndex = Math.floor(Math.random() * songsWithMinActivations.length);
cumulativeWeight += item.weight; const selectedSong = songsWithMinActivations[randomIndex];
if (random <= cumulativeWeight) {
selectedSong = item.song;
break;
}
}
// Create the daily puzzle // Create the daily puzzle
try { try {
@@ -141,7 +135,7 @@ export async function getOrCreateSpecialPuzzle(special: Special) {
song: { song: {
include: { include: {
puzzles: { puzzles: {
where: { specialId: special.id } where: { specialId: special.id } // For specials, only count puzzles within this special
} }
} }
} }
@@ -150,25 +144,25 @@ export async function getOrCreateSpecialPuzzle(special: Special) {
if (specialSongs.length === 0) return null; if (specialSongs.length === 0) return null;
// Calculate weights // Find songs with the minimum number of activations within this special
const weightedSongs = specialSongs.map(specialSong => ({ // Note: For specials, we only count puzzles within the special (not all puzzles),
// since specials are curated, separate lists
const songsWithActivations = specialSongs.map(specialSong => ({
specialSong, specialSong,
weight: 1.0 / (specialSong.song.puzzles.length + 1), activations: specialSong.song.puzzles.length,
})); }));
const totalWeight = weightedSongs.reduce((sum, item) => sum + item.weight, 0); // Find minimum activations
let random = Math.random() * totalWeight; const minActivations = Math.min(...songsWithActivations.map(item => item.activations));
let selectedSpecialSong = weightedSongs[weightedSongs.length - 1].specialSong; // Fallback to last song
// Pick a random song based on weights using cumulative weights // Filter to only songs with minimum activations
let cumulativeWeight = 0; const songsWithMinActivations = songsWithActivations
for (const item of weightedSongs) { .filter(item => item.activations === minActivations)
cumulativeWeight += item.weight; .map(item => item.specialSong);
if (random <= cumulativeWeight) {
selectedSpecialSong = item.specialSong; // Randomly select from songs with minimum activations
break; const randomIndex = Math.floor(Math.random() * songsWithMinActivations.length);
} const selectedSpecialSong = songsWithMinActivations[randomIndex];
}
try { try {
dailyPuzzle = await prisma.dailyPuzzle.create({ dailyPuzzle = await prisma.dailyPuzzle.create({

View File

@@ -1,6 +1,6 @@
{ {
"name": "hoerdle", "name": "hoerdle",
"version": "0.1.6.13", "version": "0.1.6.15",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",