ercand
29-11-2011, 00:07
Ciao a tutti, sto cercando di scrivere un semplice generatore di cruciverba.
Credevo fosse più "facile" ed invece mi sono impantanato quasi subito e sono qui a chiedere un po di aiuto per sbloccarmi.
Pensavo di creare una funzione da richiamare ricorsivamente e, ad ogni ricorsione, aggiungere una nuova parola alla griglia.
Purtroppo applicare questa idea è più difficile di quanto pensassi, fino ad ora ho scritto il seguente codice
class Coordinate
{
public int X { get; set; }
public int Y { get; set; }
public Coordinate(int x, int y)
{
X = x;
Y = y;
}
}
public enum Orientation
{
Horizontal,
Vertical
}
class Crosswords
{
public delegate void DelegateUpgradeScheme(Scheme sender);
public event DelegateUpgradeScheme HandleUpdateScheme;
private List<String> dizionario;
private int nRow = 20;
private int nCoulumns = 20;
public char[][] _scheme;
public Crosswords()
{
ReadDictionary();
ResetGrid();
}
public void Fill()
{
Scheme tempScheme = new Scheme(20, 20);
Generate("", new Coordinate(0, 0), tempScheme, Orientation.Horizontal);
}
public void Generate(String lastWord, Coordinate coord, Scheme scheme, Orientation orient)
{
List<String> candidateWords = FindCandidates(lastWord, coord, scheme, orient);
for (int i = 0; i < candidateWords.Count; i++)
{
Scheme tempScheme = new Scheme(scheme);
WriteWord(candidateWords[i], tempScheme, coord, orient);
// Aggiorna il form
// HandleUpdateScheme.Invoke(tempScheme);
Generate(candidateWords[i][0].ToString(), coord, tempScheme, Orientation.Vertical);
}
return;
}
private void WriteWord(String word, Scheme scheme, Coordinate coord, Orientation orient)
{
if (orient == Orientation.Horizontal)
{
for (int i = 0; i < word.Length; i++)
{
scheme.crossword[coord.X][coord.Y + i] = word[i];
}
// Se c'è ancora una casella libera dopo l'ultima lettera la contrassegno come "cella nera"
if (coord.X + word.Length < scheme.Columns)
{
scheme.crossword[coord.X][coord.Y + word.Length] = '#';
}
}
else
{
for (int i = 0; i < word.Length; i++)
{
scheme.crossword[coord.X + i][coord.Y] = word[i];
}
// Se c'è ancora una casella libera dopo l'ultima lettera la contrassegno come "cella nera"
if (coord.X + word.Length < scheme.Rows)
{
scheme.crossword[coord.X + word.Length][coord.Y] = '#';
}
}
}
private List<String> FindCandidates(String word, Coordinate coord, Scheme scheme, Orientation orient)
{
List<String> candidateWords = new List<String>();
int lenght = 0;
// Controlla il numero massimo di caratteri ce la parola può contenere
if (orient == Orientation.Horizontal)
{
for (int i = 0 + coord.X; i < scheme.Columns; i++)
{
if (scheme.crossword[coord.X][i] == '.')
{
lenght++;
}
}
}
else
{
for (int i = 0 + coord.Y; i < scheme.Rows; i++)
{
if (scheme.crossword[i][coord.Y] == '.')
{
lenght++;
}
}
}
// Se la lunghezza è minore di 2 allora non ci sono possibili parole da inserire
if (lenght < 2)
return candidateWords;
// Cicla sulle parole del dizionario e controlla quali possono essere messe
foreach (String c in dizionario)
{
if (c.IndexOf(word) >= 0 && c.Length < lenght)
{
candidateWords.Add(c);
}
}
return candidateWords;
}
private void ResetGrid()
{
// Resetta la griglia riempendola di caratteri '.'
}
private void ReadDictionary()
{
//Legge da un file tutte le parole presenti nel mio dizionario
}
Questa è la classe Scheme, crea semplicemente una griglia
class Scheme
{
public int Rows { get; set; }
public int Columns { get; set; }
public char[][] crossword;
public Scheme(int rows, int columns)
{
Rows = rows;
Columns = columns;
ResetGrid();
}
public Scheme(Scheme scheme):this(scheme.Rows, scheme.Columns)
{
for (int i = 0; i < scheme.Rows;i++ )
{
for (int j = 0; j < scheme.Columns;j++ )
{
crossword[i][j] = scheme.crossword[i][j];
}
}
}
private void ResetGrid()
{
char[][] tempCrossword = new char[Rows][];
for (int i = 0; i < tempCrossword.Length; i++)
{
tempCrossword[i] = new char[Columns];
for (int j = 0; j < tempCrossword[i].Length; j++)
tempCrossword[i][j] = '.';
}
crossword = tempCrossword;
}
}
Qualunque consiglio per riuscire a farmi sbloccare sarebbe ben accetto, grazie a tutti per l'aiuto
Credevo fosse più "facile" ed invece mi sono impantanato quasi subito e sono qui a chiedere un po di aiuto per sbloccarmi.
Pensavo di creare una funzione da richiamare ricorsivamente e, ad ogni ricorsione, aggiungere una nuova parola alla griglia.
Purtroppo applicare questa idea è più difficile di quanto pensassi, fino ad ora ho scritto il seguente codice
class Coordinate
{
public int X { get; set; }
public int Y { get; set; }
public Coordinate(int x, int y)
{
X = x;
Y = y;
}
}
public enum Orientation
{
Horizontal,
Vertical
}
class Crosswords
{
public delegate void DelegateUpgradeScheme(Scheme sender);
public event DelegateUpgradeScheme HandleUpdateScheme;
private List<String> dizionario;
private int nRow = 20;
private int nCoulumns = 20;
public char[][] _scheme;
public Crosswords()
{
ReadDictionary();
ResetGrid();
}
public void Fill()
{
Scheme tempScheme = new Scheme(20, 20);
Generate("", new Coordinate(0, 0), tempScheme, Orientation.Horizontal);
}
public void Generate(String lastWord, Coordinate coord, Scheme scheme, Orientation orient)
{
List<String> candidateWords = FindCandidates(lastWord, coord, scheme, orient);
for (int i = 0; i < candidateWords.Count; i++)
{
Scheme tempScheme = new Scheme(scheme);
WriteWord(candidateWords[i], tempScheme, coord, orient);
// Aggiorna il form
// HandleUpdateScheme.Invoke(tempScheme);
Generate(candidateWords[i][0].ToString(), coord, tempScheme, Orientation.Vertical);
}
return;
}
private void WriteWord(String word, Scheme scheme, Coordinate coord, Orientation orient)
{
if (orient == Orientation.Horizontal)
{
for (int i = 0; i < word.Length; i++)
{
scheme.crossword[coord.X][coord.Y + i] = word[i];
}
// Se c'è ancora una casella libera dopo l'ultima lettera la contrassegno come "cella nera"
if (coord.X + word.Length < scheme.Columns)
{
scheme.crossword[coord.X][coord.Y + word.Length] = '#';
}
}
else
{
for (int i = 0; i < word.Length; i++)
{
scheme.crossword[coord.X + i][coord.Y] = word[i];
}
// Se c'è ancora una casella libera dopo l'ultima lettera la contrassegno come "cella nera"
if (coord.X + word.Length < scheme.Rows)
{
scheme.crossword[coord.X + word.Length][coord.Y] = '#';
}
}
}
private List<String> FindCandidates(String word, Coordinate coord, Scheme scheme, Orientation orient)
{
List<String> candidateWords = new List<String>();
int lenght = 0;
// Controlla il numero massimo di caratteri ce la parola può contenere
if (orient == Orientation.Horizontal)
{
for (int i = 0 + coord.X; i < scheme.Columns; i++)
{
if (scheme.crossword[coord.X][i] == '.')
{
lenght++;
}
}
}
else
{
for (int i = 0 + coord.Y; i < scheme.Rows; i++)
{
if (scheme.crossword[i][coord.Y] == '.')
{
lenght++;
}
}
}
// Se la lunghezza è minore di 2 allora non ci sono possibili parole da inserire
if (lenght < 2)
return candidateWords;
// Cicla sulle parole del dizionario e controlla quali possono essere messe
foreach (String c in dizionario)
{
if (c.IndexOf(word) >= 0 && c.Length < lenght)
{
candidateWords.Add(c);
}
}
return candidateWords;
}
private void ResetGrid()
{
// Resetta la griglia riempendola di caratteri '.'
}
private void ReadDictionary()
{
//Legge da un file tutte le parole presenti nel mio dizionario
}
Questa è la classe Scheme, crea semplicemente una griglia
class Scheme
{
public int Rows { get; set; }
public int Columns { get; set; }
public char[][] crossword;
public Scheme(int rows, int columns)
{
Rows = rows;
Columns = columns;
ResetGrid();
}
public Scheme(Scheme scheme):this(scheme.Rows, scheme.Columns)
{
for (int i = 0; i < scheme.Rows;i++ )
{
for (int j = 0; j < scheme.Columns;j++ )
{
crossword[i][j] = scheme.crossword[i][j];
}
}
}
private void ResetGrid()
{
char[][] tempCrossword = new char[Rows][];
for (int i = 0; i < tempCrossword.Length; i++)
{
tempCrossword[i] = new char[Columns];
for (int j = 0; j < tempCrossword[i].Length; j++)
tempCrossword[i][j] = '.';
}
crossword = tempCrossword;
}
}
Qualunque consiglio per riuscire a farmi sbloccare sarebbe ben accetto, grazie a tutti per l'aiuto