Torna indietro   Hardware Upgrade Forum > Software > Programmazione

DJI Lito 1 e Lito X1 recensione: i nuovi droni per principianti che non si fanno mancare nulla
DJI Lito 1 e Lito X1 recensione: i nuovi droni per principianti che non si fanno mancare nulla
DJI ha appena ufficializzato la serie Lito, la sua nuova gamma di droni entry-level destinata a chi si avvicina per la prima volta alla fotografia aerea. Al centro dell'annuncio ci sono due modelli ben distinti per fascia di prezzo e specifiche tecniche: DJI Lito 1 e DJI Lito X1. Entrambi si collocano sotto la soglia regolamentare dei 249 grammi, che permette di volare con requisiti burocratici più semplici rispetto ai droni più pesanti.
Sony World Photography Awards 2026: i premiati, anche italiani, il punto sulla fotografia di oggi
Sony World Photography Awards 2026: i premiati, anche italiani, il punto sulla fotografia di oggi
Siamo stati a Londra per la premiazione dei Sony World Photography Awards 2026, l'evento a tema fotografia più prestigioso. Fra sorprese e novità, ne approfittiamo per fare il punto sulla fotografia contemporanea, in cui la didascalia è sempre più necessaria a cogliere il senso della quasi totalità degli scatti.
Una settimana con Hyundai Ioniq 5 N-Line: diverte e convince
Una settimana con Hyundai Ioniq 5 N-Line: diverte e convince
L'elettrica di casa Hyundai propone una versione AWD con estetica derivata dalla famiglia N. L'abbiamo provata per diversi giorni, per scoprire tutti i dettagli e la vera autonomia in autostrada
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 28-11-2011, 23:07   #1
ercand
Member
 
Iscritto dal: Sep 2004
Messaggi: 216
[C#]Algoritmo per generare un cruciverba

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

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
Codice:
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

Ultima modifica di ercand : 28-11-2011 alle 23:11.
ercand è offline   Rispondi citando il messaggio o parte di esso
Old 29-11-2011, 04:38   #2
Floris
Senior Member
 
L'Avatar di Floris
 
Iscritto dal: Jan 2007
Messaggi: 2267
Ma le parole devono essere prese da un insieme predefinito o possono essere qualunque?
__________________
Concluso con:...
Floris è offline   Rispondi citando il messaggio o parte di esso
Old 29-11-2011, 13:41   #3
ercand
Member
 
Iscritto dal: Sep 2004
Messaggi: 216
Le parole le prendo da un file txt dove sono elencato poco più di 100k parole.
ercand è offline   Rispondi citando il messaggio o parte di esso
Old 03-12-2011, 21:34   #4
ercand
Member
 
Iscritto dal: Sep 2004
Messaggi: 216
Ho sperimentato un poco questi giorni e sono arrivato a scriveere questo

Codice:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Text.RegularExpressions;

namespace CruciverbaNet
{
    class Coordinate
    {
        public int Row { get; set; }
        public int Column { get; set; }

        public Coordinate(int row, int column)
        {
            Row = row;
            Column = column;
        }

        public Coordinate(Coordinate coord) : this(coord.Row, coord.Column)
        {}

        public int CompareTo(Coordinate coord)
        {
            if (Column < coord.Column){
                return -1;
            }
            if (Column > coord.Column){
                return 1;
            }
            
            // Le coordinate sono sulla stessa colonne, controlla le riga
            if (Row < coord.Row){
                return -1;
            }
            if (Row > coord.Row){
                return 1;
            }
            return 0;
        }
    }

    public enum EnumOrientation
    {
        Horizontal,
        Vertical
    }

    class Orientation
    {
        public EnumOrientation Orient;

        public Orientation(EnumOrientation orient)
        {
            Orient = orient;
        }

        public Orientation(Orientation orient)
            : this(orient.Orient)
        {

        }
    }

    class Crosswords
    {
        public delegate void DelegateUpgradeScheme(Scheme sender);
        public event DelegateUpgradeScheme HandleUpdateScheme;

        private List<String> dizionario;
        private Dictionary<int, List<String>> dizionarioAlfabetico;
        private List<String> busyWords;
        private int nRow = 20;
        private int nCoulumns = 20;
        public char[][] _scheme;

        public Crosswords()
        {
            ReadDictionary();
            ResetGrid();
            busyWords = new List<String>();
        }

        public void Fill()
        {
            Scheme tempScheme = new Scheme(20, 20);
            Generate("", new Coordinate(0, 0), tempScheme, new Orientation(EnumOrientation.Vertical));
        }

        public bool Generate(String lastWord, Coordinate coord, Scheme scheme, Orientation orient)
        {
            Orientation tempOrient = new Orientation(orient);

            // Troviamo la prima cella libera
            Coordinate tempCoord = FindNextFreeSPace(tempOrient, scheme);

            // Se è null non ci sono piu celle libere, cruciverba riempito
            if (tempCoord == null){
                return true;
            }

            // Recuperiamo la parola che passa per la coordinata specificata
            String tempWord = intersectingWord(tempCoord, tempOrient.Orient, scheme);
            int tempWordLength = tempWord.Length;

            // Cerco le possibili parole candidate
            List<String> candidatesWord = new List<String>();

            while (tempWord.Length > 1 && tempWord[tempWord.Length - 1] == '.'){
                tempWord = tempWord.Substring(0, tempWord.Length - 1);
            }

            // Trovo le possibili parole che possono essere usate
            for (int i = 0; i < dizionario.Count; i++)
            {
                if (Regex.IsMatch(dizionario[i], "^" + tempWord) && dizionario[i].Length < tempWordLength)
                    if (busyWords.Contains(dizionario[i]) == false) // Controlliamo che non sia tra le parole gia usate
                        candidatesWord.Add(dizionario[i]);
            }

            Scheme tempScheme = new Scheme(scheme);
            for (int i = 0; i < candidatesWord.Count; i++)
            {
                if (WriteWord(candidatesWord[i], tempScheme, tempCoord, tempOrient.Orient))
                {
                    // Aggiorna il form
                    HandleUpdateScheme.Invoke(tempScheme);

                    // Aggiungo la parola lla lista di quelle gia usate
                    busyWords.Add(candidatesWord[i]);

                    // Se le parole non si interseca torna un passo indietro
                    if (Generate(candidatesWord[i][0].ToString(), new Coordinate(0, 0), tempScheme, new Orientation(EnumOrientation.Vertical)) == false)
                    {
                        tempScheme = new Scheme(scheme);
                        HandleUpdateScheme.Invoke(tempScheme);
                        busyWords.Remove(candidatesWord[i]);
                    }
                }

            }

            // Non è stata trovata nessuna combinazione, ritorno false
            return false;
        }

        public Coordinate FindNextFreeSPace(Orientation orient, Scheme scheme)
        {
            Coordinate coordVert = FindNextOrientedFreeSpace(EnumOrientation.Vertical, scheme);
            Coordinate coordHori = FindNextOrientedFreeSpace(EnumOrientation.Horizontal, scheme);

            // Se non sono state trovare ne spazi verticali ne orizzontali
            if (coordHori == null && coordVert == null) {
                return null;
            }
            else if ((coordHori == null || coordVert != null) && coordVert.CompareTo(coordHori) < 0) {
                orient.Orient = EnumOrientation.Vertical;
                return coordVert;
            }
            orient.Orient = EnumOrientation.Horizontal;
            return coordHori;
        }

        public Coordinate FindNextOrientedFreeSpace(EnumOrientation orient, Scheme scheme)
        {
            for (int i = 0; i < scheme.Rows; i++)
            {
                for (int j = 0; j < scheme.Columns; j++)
                {
                    String temp = intersectingWord(new Coordinate(i, j), orient, scheme);
                    if (temp != null && temp.IndexOf(".") >= 0)
                        return new Coordinate(i, j);
                }
            }
            return null;
        }

        /// <summary>
        /// Cerca la stringa passante per la coordinata e con l'orientamento specificato
        /// </summary>
        /// <param name="coord"></param>
        /// <param name="orient"></param>
        /// <param name="scheme"></param>
        /// <returns></returns>
        private String intersectingWord(Coordinate coord, EnumOrientation orient, Scheme scheme)
        {
            // E' una cella nera
            if (getSchemaChar(coord, scheme) == '#')
                return null;

            String result = "" + getSchemaChar(coord, scheme);
            Coordinate tempCoord = new Coordinate(coord.Row, coord.Column);
            if (orient == EnumOrientation.Vertical)
            {	//Se è in verticale concateno i caratteri in colonna spostandomi di riga
                tempCoord.Row--;
                while (tempCoord.Row >= 0 && getSchemaChar(tempCoord, scheme) != '#')
                {
                    result = getSchemaChar(tempCoord, scheme) + result;
                    tempCoord.Row--;
                }
                tempCoord.Row = coord.Row + 1;
                while (tempCoord.Row < scheme.crossword.Length && getSchemaChar(tempCoord, scheme) != '#')
                {
                    result = result + getSchemaChar(tempCoord, scheme);
                    tempCoord.Row++;
                }
            }
            else
            {	//Se è in orizzontale concateno i caratteri in riga spostandomi di colonna
                tempCoord.Column--;
                while (tempCoord.Column >= 0 && getSchemaChar(tempCoord, scheme) != '#')
                {
                    result = getSchemaChar(tempCoord, scheme) + result;
                    tempCoord.Column--;
                }
                tempCoord.Column = coord.Column + 1;
                while (tempCoord.Column < scheme.crossword[coord.Row].Length && getSchemaChar(tempCoord, scheme) != '#')
                {
                    result = result + getSchemaChar(tempCoord, scheme);
                    tempCoord.Column++;
                }
            }
            // Una sola lettera
            if (result.Length == 1)
                return null;

            return result;
        }

        private char getSchemaChar(Coordinate coord, Scheme scheme)
        {
            return scheme.crossword[coord.Row][coord.Column];
        }


        private bool WriteWord(String word, Scheme scheme, Coordinate coord, EnumOrientation orient)
        {
            if (orient == EnumOrientation.Horizontal)
            {
                bool ok = true;

                for (int i = 0; i < word.Length; i++)
                {
                    String intersectedWord = intersectingWord(new Coordinate(coord.Row, coord.Column + i), EnumOrientation.Vertical, scheme);

                    while (intersectedWord.Length > 0 && intersectedWord[intersectedWord.Length - 1] == '.')
                    {
                        intersectedWord = intersectedWord.Substring(0, intersectedWord.Length - 1);
                    }
                    int howManyMatch = 0;

                    // Controlla se esistono parole compatibili con quella che incrociamo
                    for (int j = 0; j < dizionario.Count && howManyMatch == 0; j++)
                    {
                        if (Regex.IsMatch(dizionario[j], intersectedWord))
                        {
                            howManyMatch++;
                        }
                    }
                    if (howManyMatch == 0)
                    {
                        ok = false;
                    }
                }
				
                // La parola è compatibile, la scrivo nello schema
                if (ok == true)
                {
                    for (int i = 0; i < word.Length; i++)
                        scheme.crossword[coord.Row][coord.Column + i] = word[i];

                    // Se c'è ancora una casella libera dopo l'ultima lettera la contrassegno come "cella nera"
                    if (coord.Row + word.Length < scheme.Columns)
                    {
                        scheme.crossword[coord.Row][coord.Column + word.Length] = '#';
                    }
                }
                else
                    return false;

            }
            else
            {
                bool ok = true;

                for (int i = 0; i < word.Length; i++)
                {
                    String intersectedWord = intersectingWord(new Coordinate(coord.Row + i, coord.Column), EnumOrientation.Horizontal, scheme); // Parola che interseca la coordinata attuale

                    if (intersectedWord.IndexOf(".") < 0) // Se le celle sono tutte occupate
                        continue;

                    int toSubtract = 0;
                    while (intersectedWord.Length -toSubtract> 0 && intersectedWord[intersectedWord.Length - 1 - toSubtract] == '.') {
                        ++toSubtract;
                    }
                    intersectedWord = intersectedWord.Substring(0, intersectedWord.Length - toSubtract);

                    int howManyMatch = 0;

                    if (intersectedWord.Length > 0 && intersectedWord[0]!= '.')
                    {
                        int codeChar = Convert.ToInt32(intersectedWord[0]);
                        int wordCount = dizionarioAlfabetico[codeChar].Count;
                        String regExpWord = "^" + intersectedWord + word[i];

                        // Controlla se esistono parole compatibili con quella che incrociamo
                        for (int j = 0; j < wordCount && howManyMatch == 0; j++)
                        {
                            if (Regex.IsMatch(dizionarioAlfabetico[codeChar][j], regExpWord))
                            {
                                howManyMatch++;
                            }
                        }
                    }
                    else
                    {
                        int codeChar = Convert.ToInt32(word[i]);
                        int wordCount = dizionarioAlfabetico[codeChar].Count;
                        String regExpWord = "^" + intersectedWord + word[i];

                        // Controlla se esistono parole compatibili con quella che incrociamo
                        for (int j = 0; j < wordCount && howManyMatch == 0; j++)
                        {
                            if (Regex.IsMatch(dizionarioAlfabetico[codeChar][j], regExpWord))
                            {
                                howManyMatch++;
                            }
                        }
                    }

                    if (howManyMatch == 0) {
                        ok = false;
						return false;
                    }
                }

                

                // La parola è compatibile, la scrivo nello schema
                if (ok == true) {
                    for (int i = 0; i < word.Length; i++)
                        scheme.crossword[coord.Row + i][coord.Column] = word[i];

                    // Se c'è ancora una casella libera dopo l'ultima lettera la contrassegno come "cella nera"
                    if (coord.Row + word.Length < scheme.Columns) {
                        scheme.crossword[coord.Row + word.Length][coord.Column] = '#';
                    }
                }
                else
                    return false;
            }

            // é la parola è stata inserita correttamente
            return true;
        }
    }
}
Purtroppo questo codice è LENTO, infatti non sono riusco a portare a termine neanche un cruciverba, purtroppo questo non mi permette neanche di capire se quello che ho scritto funzioni o meno.
Se qualcuno avesse qualche suggerimento da darmi o indirizzarmi su una via "migliore" sarebbe molto gradito .

Grazie per l'aiuto
ercand è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


DJI Lito 1 e Lito X1 recensione: i nuovi droni per principianti che non si fanno mancare nulla DJI Lito 1 e Lito X1 recensione: i nuovi droni p...
Sony World Photography Awards 2026: i premiati, anche italiani, il punto sulla fotografia di oggi Sony World Photography Awards 2026: i premiati, ...
Una settimana con Hyundai Ioniq 5 N-Line: diverte e convince Una settimana con Hyundai Ioniq 5 N-Line: divert...
Recensione OPPO Find X9 Ultra: è lui il cameraphone definitivo Recensione OPPO Find X9 Ultra: è lui il c...
Ecovacs Deebot X12 OmniCyclone: lava grazie a FocusJet Ecovacs Deebot X12 OmniCyclone: lava grazie a Fo...
Apple prepara un restyling per la linea ...
Il MacBook Neo trascinerà Apple: ...
I genitori potranno verificare gli argom...
ESA e Northrop Grumman confermano la cor...
Il telescopio spaziale Nancy Grace Roman...
iPhone Ultra, periodo di lancio conferma...
Un anno fa debuttava Clair Obscur:&...
Tutte le offerte sugli smartphone ora pi...
Tutte le offerte sui TV ora su Amazon: u...
Xbox Game Pass sarà disponibile a...
La serie HONOR 600 avrà presto un...
Mova Viax 250 in prova: il robot tagliae...
Fat e-bike per tutti: sconti Engwe, pi&u...
Google conferma l'arrivo della nuova ver...
Apple ha trovato il modo per abbassare i...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 00:55.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v