Example #1
0
        // Will return -1 if the word cannot be placed.
        private int CountIntersections(Word word, Point start)
        {
            int intersections = 0;

            if (!CanWordFit(word, start))
            {
                return(-1);
            }

            for (int i = 0; i < word.GetLength(); ++i)
            {
                Point p = GetWordCoord(word, start, i);

                if (blocks[p.X, p.Y] != null)
                {
                    if (blocks[p.X, p.Y].GetAnswer() == word.GetCorrectWord()[i])
                    {
                        intersections++;
                    }
                    else if (!blocks[p.X, p.Y].CanOverwrite(word.GetDirection()))
                    {
                        return(-1);
                    }
                }
            }
            return(intersections);
        }
Example #2
0
        private bool TryPlace(Word w, Point start, int minIntersections)
        {
            int inters = CountIntersections(w, start);

            // "Useless" condition for a special case. Handled seperately for clarity.
            if (inters < 0)
            {
                return(false);
            }
            else if (inters < minIntersections)
            {
                return(false);
            }
            else if (inters == w.GetCorrectWord().Length)
            {
                return(false);
            }


            PlaceWord(w, start);
            return(true);
        }
Example #3
0
        // Excpects a word that can be placed
        private void PlaceWord(Word word, Point start)
        {
            Point before = GetWordCoord(word, start, -1);
            Point after  = GetWordCoord(word, start, word.GetLength());

            // Its ok to overwrite the old block here since black blocks do not get stored anywhere else than the block[,] array
            blocks[before.X, before.Y] = new BlackBlock(BlockOverwrite.None);
            blocks[after.X, after.Y]   = new BlackBlock(BlockOverwrite.None);


            for (int i = 0; i < word.GetLength(); i++)
            {
                Point p = GetWordCoord(word, start, i);
                if (blocks[p.X, p.Y] == null || blocks[p.X, p.Y] is BlackBlock)
                {
                    blocks[p.X, p.Y] = new CharacterBlock(word.GetCorrectWord()[i]);
                }
                word.SetSharedBlock(blocks[p.X, p.Y] as CharacterBlock, i);

                ProhibitOverwrite(GetWordCoord(word, start, i, 1), word.GetDirection());
                ProhibitOverwrite(GetWordCoord(word, start, i, -1), word.GetDirection());
            }
            words.Add(word);
        }
Example #4
0
        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();
                    }
                }
            }
        }