2010-02-15 18 views
13

Sto facendo un gioco di parole simile a boggle. L'utente riceve una griglia di lettere simili:Algoritmo per scegliere lettere casuali per il gioco di ricerca di parole che consente di scrivere molte parole

O V Z W X 
S T A C K 
Y R F L Q 

L'utente sceglie una parola utilizzando qualsiasi catene adiacenti di lettere, come la parola "STACK" attraverso la linea di mezzo. Le lettere utilizzate vengono quindi sostituite dalla macchina, ad es. (nuove lettere in minuscolo):

O V Z W X 
z e x o p 
Y R F L Q 

Avviso è ora possibile incantesimo "troppo pieno", utilizzando le nuove lettere. Il mio problema è: quale algoritmo posso utilizzare per selezionare nuove lettere che massimizzano il numero di parole lunghe che l'utente può pronunciare? Voglio che il gioco sia divertente e coinvolga l'ortografia, ad es. Parole a 6 lettere a volte ma, se scegli lettere sbagliate, i giochi coinvolgono solo l'ortografia di 3 lettere e non riescono a trovare parole più grandi.

Ad esempio:

  • Si può solo scegliere a caso le nuove lettere dell'alfabeto. Questo non funziona bene.

  • Allo stesso modo, ho trovato la scelta casuale ma utilizzando le frequenze lettera di Scrabble non ha funzionato bene. Funziona meglio in Scrabble, penso che tu sia meno vincolato all'ordine in cui usi le lettere.

  • Ho provato ad avere una serie di elenchi, ognuno dei quali rappresenta uno degli stampi del gioco Boggle e ogni lettera sarebbe scelto da un lato del dado casuale (mi chiedo anche se posso usare legalmente questi dati in un prodotto). Non ho notato che funziona bene. Immagino che i lati dei dadi di Boggle siano stati scelti in modo ragionevole, ma non riesco a trovare come è stato fatto.

Alcune idee che ho in considerazione:

  • Fai un tavolo di quanto spesso si verificano insieme coppie di lettere nel dizionario. Per amor di discussione, dì che E è visto accanto ad A il 30% delle volte. Quando scegli una nuova lettera, selezionerei casualmente una lettera in base alla frequenza di questa lettera che si verifica accanto a una lettera adiacente scelta casualmente sulla griglia. Ad esempio, se la lettera vicina era E, la nuova lettera sarebbe "A" il 30% delle volte. Il che dovrebbe significare che ci sono molte coppie decenti da usare sparse per la mappa. Potrei forse migliorare questo facendo delle tabelle di probabilità di una lettera che si verificano tra due altre lettere.

  • In qualche modo effettuare una ricerca per quali parole possono essere digitate sulla griglia corrente, prendendo le nuove lettere come caratteri jolly. Sostituirei i caratteri jolly con lettere che permettevano di scrivere le parole più grandi. Non sono sicuro di come lo faresti in modo efficiente comunque.

Altre idee sono apprezzate. Mi chiedo se esiste un modo comune per risolvere questo problema e quali altri giochi di parole utilizzano.

Modifica: Grazie per le grandi risposte finora! Ho dimenticato di menzionare, sto puntando molto a requisiti di memoria bassa/CPU, se possibile, probabilmente userò il dizionario SOWPODS (circa 250.000) e la mia griglia sarà 6 x 6.

+1

Mi piace l'idea di utilizzare le probabilità di giustapposizione delle lettere. Potresti espanderlo ulteriormente: per ogni posizione di una determinata lettera, calcola la probabilità che ogni lettera sia adiacente alle sue lettere immediatamente circostanti e media queste probabilità in una sola, quindi scegli una lettera casuale usando le probabilità medie come pesi. – Cameron

risposta

1

Io no conoscere un algoritmo precurato per questo, ma ...

C'è un file dizionario in UNIX e immagino ci sia qualcosa di simile disponibile su altre piattaforme (forse anche nelle librerie java? - google it). Ad ogni modo, usa i file usati dal correttore ortografico.

Dopo aver eseguito lo spelling di una parola, viene eliminato, sono presenti lettere e spazi vuoti.

1) Da ogni lettera esistente, andare a destra, a sinistra, in alto, in basso (sarà necessario comprendere gli algoritmi ricorsivi). Finché la stringa che hai costruito fino ad ora si trova all'inizio delle parole o al contrario dalla fine delle parole nel file dizionario, continua. Quando ti imbatti in uno spazio vuoto, conta la frequenza delle lettere che ti servono dopo. Usa le lettere più frequenti.

Non garantirà una parola poiché non hai controllato il finale o l'inizio corrispondenti, ma penso che sarebbe molto più facile da implementare di una ricerca esaustiva e ottenere risultati piuttosto buoni.

+0

Potresti fare un breve esempio? Non sono sicuro di come funzionerebbe. – BobbyJim

7

Ecco un metodo semplice:

Scrivi un risolutore veloce per il gioco utilizzando lo stesso elenco di parole che il giocatore userà. Genera diciamo 100 diverse schede possibili a caso (utilizzando le frequenze lettera è probabilmente una buona idea qui, ma non essenziale). Per ogni scheda, calcola tutte le parole che possono essere generate e assegna un punteggio alla scheda in base al numero di parole trovate o al conteggio ponderato in base alla lunghezza della parola (cioè la somma totale delle lunghezze delle parole di tutte le parole trovate). Quindi scegli il miglior tabellone dalle 100 possibilità e assegnalo al giocatore.

Inoltre, invece di scegliere sempre il tabellone più alto (cioè la scheda più semplice), potresti avere soglie di punteggio diverse per rendere il gioco più difficile per gli esperti.

+0

Grazie. Questa è probabilmente l'idea più a prova di proiettile in quanto potresti, ad es. garanzia (il più delle volte) che ci sarà sempre un certo numero di parole grandi da scegliere. La mia scheda sarà 6x6 e usare un trie richiede troppa memoria, quindi non sono sicuro di come potrei usarlo in modo efficiente. – BobbyJim

+0

L'uso di un elenco di prefissi di parole (trie) offre le migliori prestazioni se si dispone della memoria. Se conservi il trie compresso, probabilmente potresti creare un trie completo in pochi MB che immagino. In caso contrario, è comunque possibile ottenere un elenco di prefissi di parole fino alla lunghezza 5 in memoria, quindi passare alla ricerca binaria (o interpolata) dell'intero elenco di parole per verificare le corrispondenze superiori a 5. In alternativa ... contare i prefissi in alto alla lunghezza 5 e supponiamo che molte piccole parole parziali abbiano una buona probabilità di una lunga parola senza controllare esplicitamente le parole lunghe. –

+1

Se stai osando potresti usare un DAWG che è memorizzato in un array. C'è un'eccellente video conferenza da Stanford su quello trovato qui: http://www.youtube.com/watch?v=TJ8SkcUSdbU Il racconto è che è riuscita a memorizzare 250.000 parole in .32 MB –

2

Una piccola variazione dell'approccio a coppie di lettere: usa la frequenza delle coppie di lettere nelle parole lunghe, ad esempio 6 lettere o più lunghe, poiché questo è il tuo obiettivo. Potresti anche sviluppare una ponderazione che includesse tutte le lettere adiacenti, non solo una a caso.

+0

È bello usare le parole lunghe 6 lettere! Ho preso in considerazione l'utilizzo di trigrammi (considero solo la frequenza di 3 coppie di lettere) ma la tua idea sembra più vicina a ciò che voglio veramente. – BobbyJim

2

This wordgame Ho eseguito uno schiaffo un po 'indietro, che si comporta in modo molto simile a quello che descrivi, utilizza le tabelle di frequenza inglese per selezionare le lettere, ma decide prima se generare una vocale o consonante, permettendomi di garantire una determinata velocità delle vocali il bordo. Questo sembra funzionare abbastanza bene.

+0

Grazie. Che cosa hai usato per la frequenza vocale/consonantica? I miei sentimenti sono, in ogni griglia 2x2 locale, probabilmente dovresti avere almeno una vocale. Altrimenti, potresti ottenere gruppi di consonanti "intrappolati" negli angoli che non puoi usare a parole. Hai usato solo le normali tabelle di frequenza delle lettere e non ad es. frequenze di lettere accoppiate? – BobbyJim

+0

@Bobby: poiché la scacchiera muta dopo ogni parola, il giocatore può "spazzare via" a gruppi di lettere difficili nel tempo - si potrebbe pensare a ciò come parte della strategia di gioco. La velocità vocale/consonantica è cablata a 0.559 - Ho ottenuto quel valore e le frequenze lettera raccogliendo statistiche su alcuni ebook che avevo mentito :) – moonshadow

+0

OK, grazie. Ho effettivamente testato il mio gioco con il comportamento calante, ma ho notato che i giocatori tendono a ignorare le lettere in fondo quando le lettere non sono molto buone e passano tutto il loro tempo in cima.Stavo pensando a lettere che arrivano da tutte le direzioni in qualche modo. O renderlo un requisito per disporre di vecchie lettere. Inoltre, le lettere che cadono rendono difficile ad es. fissare il numero di vocali nelle posizioni della griglia locale. Potrei pensarci troppo. :) Mi piacerebbe molto se ad es. ogni griglia aveva almeno una parola lunga in modo che gli esperti potessero mettersi in mostra. – BobbyJim

2

Si dovrebbe cercare n-gramming e modelli markoviani.

La tua prima idea è molto legata agli algoritmi di Markovian. Fondamentalmente, se si dispone di un corpus di testo di grandi dimensioni, si parla di 1000 parole. Quello che puoi fare è analizzare ogni lettera e creare una tabella per conoscere la probabilità di una certa lettera che segue la lettera corrente.

Ad esempio, so che la lettera Q delle mie 1000 parole (4000 lettere in totale) viene utilizzata solo 40 volte. Poi calcolo le lettere probabili che seguono usando la mia tabella hash markov.

Ad esempio, QU accade il 100% delle volte, quindi so che Q dovrebbe essere scelto a caso dalla tua applicazione che ho bisogno di assicurarmi che sia inclusa anche la lettera U. Quindi, la lettera "I" viene utilizzata il 50% delle volte e "A" il 25% delle volte e "O" il 25% delle volte.

In realtà è davvero complicato da spiegare e scommetto che ci sono altre spiegazioni là fuori che sono molto meglio di questo.

Ma l'idea è che dato un corpus di testo legittimamente grande è possibile creare una catena di lettere X che sono probabilmente coerenti con la lingua inglese e quindi dovrebbe essere facile per gli utenti di creare parole. Puoi scegliere di guardare avanti ad un valore di n-grammo, il più alto è il numero più facile puoi fare il tuo gioco. Ad esempio, un n-grammo di due probabilmente renderebbe molto difficile creare parole su 6, ma un n-grammo di 4 sarebbe molto semplice.

La Wikipedia lo spiega davvero male, quindi non lo seguirò.

Date un'occhiata a questo generatore di Markov:

http://www.haykranen.nl/projects/markov/demo/

+0

Grazie, sembra interessante. Potresti elaborare un po 'di più sull'n-grammo di 4 idee? Vorrei ad es. scegli una catena adiacente di 4 lettere, pronuncia "C-H-A-N", vicino alla mia posizione casuale della lettera, quindi chiedi a un tavolo di scegliere una lettera che di solito segue le 3 lettere "CHAN" ad es. "G" come in "MODIFICA"? – BobbyJim

+0

Ho sempre avuto paura delle catene di Markov. L'articolo principale della wiki è confuso, ma questo è abbastanza buono: http://en.wikipedia.org/wiki/Examples_of_Markov_chains – BobbyJim

+0

La n-gramming è proprio dove si abbatte qualcosa in N numero di grammi. Ad esempio, su un 1 grammo parola Boggle è 1 grammo BOGGLE 2 grammi (comunemente chiamato bigram) Sarebbe B BO OG GG GL LE E 3 grammi (comunemente chiamato trigramma) sarebbe B BO BOG OGG GGL GLE LE E Su un 4 grammi (Appena chiamato un n-grammi) sarebbe B BO BOG Bogg OGGL GGLE GLE LE E È possibile vedere come se si utilizza una catena markov con un particolare n-grammo è possibile raggruppare particolari sequenze di caratteri speciali in corso. Per inciso, man mano che aumenti il ​​n-grammo troverai che il gioco diventa più facile. – Layke

0

Si potrebbe guardare a questo Java implementation del Jumble algorithm per trovare gruppi di lettere che permute a più parole del dizionario:

 
$ java -jar dist/jumble.jar | sort -nr | head 
11 Orang Ronga angor argon goran grano groan nagor orang organ rogan 
10 Elaps Lepas Pales lapse salep saple sepal slape spale speal 
9 ester estre reest reset steer stere stree terse tsere 
9 caret carte cater crate creat creta react recta trace 
9 Easter Eastre asteer easter reseat saeter seater staree teaser 
9 Canari Carian Crania acinar arnica canari carina crania narica 
8 leapt palet patel pelta petal plate pleat tepal 
8 laster lastre rastle relast resalt salter slater stelar 
8 Trias arist astir sitar stair stria tarsi tisar 
8 Trema armet mater metra ramet tamer terma trame 
... 
Problemi correlati