コード例 #1
0
ファイル: MainWindow.cs プロジェクト: katagis/win-crossword
 private void NewGame(CrosswordSize size = CrosswordSize.UsePrevious)
 {
     activeCrossword.GenerateNewCrossword(size);
     RemakeTable();
     RemakeWords();
 }
コード例 #2
0
ファイル: Crossword.cs プロジェクト: katagis/win-crossword
        public void GenerateNewCrossword(CrosswordSize newSize = CrosswordSize.UsePrevious)
        {
            if (newSize != CrosswordSize.UsePrevious)
            {
                size = newSize;
            }

            switch (size)
            {
            case CrosswordSize.Small:
                SizeX = SizeY = 17;
                break;

            case CrosswordSize.Normal:
                SizeX = SizeY = 24;
                break;

            case CrosswordSize.Large:
                SizeX = SizeY = 31;
                break;

            case CrosswordSize.VeryLarge:
                SizeX = SizeY = 45;
                break;
            }

            words.Clear();

            if (initialWords.Count < 4)
            {
                MessageBox.Show("Not enough words left for a new crossword. Reloading wordlist file.", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                InitialiseFromFile();
            }

            const float GenerationComplexityFactor = 2.0f;

            blocks = new IBlock[SizeX, SizeY];


            int InitialSizeWords = initialWords.Count;

            Random r = new Random();

            DateTime timeStart = DateTime.Now;

            // Place first word at random
            bool Placed = false;

            while (!Placed)
            {
                int x = r.Next((int)Math.Ceiling(SizeX * 0.30), (int)Math.Floor(SizeX * 0.70));
                int y = r.Next((int)Math.Ceiling(SizeY * 0.30), (int)Math.Floor(SizeY * 0.70));

                int  index = r.Next(initialWords.Count);
                Word w     = GenerateWord(index, r);

                if (TryPlace(w, new Point(x, y), 0))
                {
                    initialWords.RemoveAt(index);
                    Placed = true;
                }
            }


            int   LoopsWithoutProgress    = 0;
            float GenerationFactor        = InitialSizeWords * GenerationComplexityFactor;
            int   SingleIntersectionCount = 0;

            while (initialWords.Count > 0 && LoopsWithoutProgress < GenerationFactor)
            {
                int wordsPlaced = InitialSizeWords - initialWords.Count;

                float wordsPlacedPercent = wordsPlaced / InitialSizeWords;

                int  index = r.Next(initialWords.Count);
                Word w     = GenerateWord(index, r);


                int minIntersections = 1;

                if (wordsPlaced < 3)
                {
                    if (w.GetCorrectWord().Length > 5)
                    {
                        minIntersections = 1;
                    }
                    else
                    {
                        continue;
                    }
                }
                else if (LoopsWithoutProgress < GenerationFactor * 0.1)
                {
                    minIntersections = 4;
                }
                else if (LoopsWithoutProgress < GenerationFactor * 0.3)
                {
                    minIntersections = 3;
                }
                else if (LoopsWithoutProgress < GenerationFactor * 0.9)
                {
                    minIntersections = 2;
                }
                else
                {
                    minIntersections = 1;
                }

                LoopsWithoutProgress++;
                if (TryPlaceEverywhere(w, minIntersections, r))
                {
                    if (minIntersections == 1)
                    {
                        SingleIntersectionCount++;
                    }
                    LoopsWithoutProgress = 0;
                    initialWords.RemoveAt(index);
                }
            }


            TimeSpan ts = DateTime.Now - timeStart;

            int ms = (int)ts.TotalMilliseconds;

            if (ms > 3000)
            {
                MessageBox.Show("Took " + ms + "ms to make this crossword.", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }


            // Fill empty blocks
            for (int row = 0; row < blocks.GetLength(0); row++)
            {
                for (int col = 0; col < blocks.GetLength(1); col++)
                {
                    if (blocks[row, col] == null)
                    {
                        blocks[row, col] = new BlackBlock();
                    }
                }
            }
        }