18 Words
Un gioco di parole semplice che ha conquistato Hacker News
Cosa fa
Un gioco di parole nel browser, con oltre mille voti su Hacker News: semplice da capire, da giocare ogni giorno.
Come guadagna
Presentato su Hacker News dal suo creatore, che non dichiara incassi. Idee nostre per guadagnare con un progetto simile: pubblicità leggera, versione premium con archivio delle partite.
Rendilo tuo
- In italiano, con parole e regole pensate per la nostra lingua.
- Sfida giornaliera uguale per tutti e risultato da condividere.
Le frasi da scrivere all'AI
1. Base del sito e grafica
Crea un'app web in italiano chiamata "Diciotto": un gioco di parole giornaliero in italiano: con le stesse 9 lettere del giorno bisogna trovare 18 parole, dalle più facili alle più difficili, come in un cruciverba veloce. Usa React, Vite, TypeScript e Tailwind CSS.
Pagine da creare:
1. La partita di oggi: le 9 lettere in cerchio, il campo per scrivere, le 18 caselle da riempire
2. Risultato con le parole trovate e quelle mancanti
3. Statistiche e serie di giorni
4. Archivio delle partite passate (Pro)
5. Come si gioca
Stile: pulito e rilassante: sfondo crema #FDFBF7, verde bottiglia #166534, oro #CA8A04 per la parola più lunga, carattere "DM Serif Display" per le lettere e "Inter" per il resto. Nessuna immagine generica di stock.
Tutto deve funzionare perfettamente da telefono. Tutti i testi in italiano, chiari e senza parole tecniche.
2. Database, account e sicurezza
Collega il progetto a Supabase e attiva la registrazione con email e password.
Crea queste tabelle:
- "partite": giorno, lettere, le 18 parole da trovare (scelte dalla redazione dal dizionario)
- "risultati": giorno, parole trovate, tempo, collegati all'utente o a un identificativo anonimo
Regole di sicurezza obbligatorie:
- le parole della partita non arrivano al browser prima che il giocatore le trovi
- una partita al giorno uguale per tutti
- il piano non si modifica dal browser
Usa esattamente il codice SQL che trovi nei "Dettagli tecnici" di questa scheda: eseguilo nel SQL Editor di Supabase prima di continuare, poi collega le pagine alle tabelle.
3. Le lettere del giorno
Ogni giorno 9 lettere in cerchio; ogni parola deve usare la lettera centrale e le altre al massimo una volta ciascuna, ed essere lunga almeno 4 lettere. Le 18 parole della partita sono scelte dalla redazione tra quelle possibili, dalle comuni alle rare, e compaiono come caselle vuote con il numero di lettere.
Per non svelare le soluzioni, il browser riceve solo le impronte delle parole (hash), non le parole: quando il giocatore scrive una parola, il browser ne calcola l'impronta e la confronta (codice nei Dettagli tecnici).
Il dizionario delle parole valide deve avere una licenza che ne permetta l'uso: usare una lista di parole libera o costruita dalla redazione.
4. Condivisione e statistiche
Fine partita con le parole trovate, quelle mancanti (svelate) e la condivisione con emoji senza spoiler ("Diciotto #87 🟩🟩🟩🟩⬜⬜ 14/18").
Statistiche: giorni giocati, media di parole trovate, serie. Pro: archivio delle partite passate, aiuti (prima lettera di una parola) e nessuna pubblicità.
5. Pagamenti con Stripe
Aggiungi un pagamento singolo di 2,99 € una volta sola. Il pagamento sblocca l'archivio delle partite, gli aiuti e toglie la pubblicità.
A pagamento riuscito il webhook imposta "piano" a "pro" nella tabella "profili", sulla riga dell'utente indicata in client_reference_id.
Per la sessione di pagamento e il webhook segui la guida "Pagamenti con Stripe" di Fattibile.
6. Controlli specifici di questo progetto
Oltre ai controlli della guida "Controllo finale", verifica in particolare:
1. Spoiler: apri gli strumenti del browser durante la partita e verifica che le 18 parole non compaiano in chiaro da nessuna parte.
Correggi quello che non va e scrivimi cosa hai cambiato.
Dettagli tecnici
Controllare le parole senza svelarle
Il server manda solo le impronte SHA-256 delle parole (con il giorno come "sale"); il browser calcola l'impronta di quello che scrive il giocatore e la confronta.
export async function impronta(parola: string, giorno: string): Promise<string> {
const testo = giorno + ":" + parola.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
const h = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(testo));
return [...new Uint8Array(h)].map((b) => b.toString(16).padStart(2, "0")).join("");
}
// La parola rispetta le regole del gioco?
export function valida(parola: string, lettere: string[], centrale: string): string | null {
const p = parola.toLowerCase();
if (p.length < 4) return "Almeno 4 lettere";
if (!p.includes(centrale)) return "Deve contenere la lettera centrale";
const disponibili = [...lettere];
for (const c of p) {
const i = disponibili.indexOf(c);
if (i === -1) return "Lettera non disponibile: " + c.toUpperCase();
disponibili.splice(i, 1); // ogni lettera una volta sola
}
return null;
}
export async function prova(parola: string, giorno: string, impronte: { hash: string; lunghezza: number }[]) {
const h = await impronta(parola, giorno);
return impronte.findIndex((x) => x.hash === h); // -1 = non è tra le 18
}
Pezzi comuni a tutti i progetti
Glossario
- Impronta (hash)
- Un codice calcolato da una parola: dal codice non si risale alla parola, ma la stessa parola dà sempre lo stesso codice.