Пример #1
0
        /// <summary>
        /// Determin whether the insert word could insert into the letter in insert letter list, and process insertion if positive
        /// </summary>
        /// <param name="insertionLetter"></param>
        /// <param name="word"></param>
        /// <returns></returns>
        private bool InsertWords(LetterInfo insertionLetter, String word)
        {
            if (IsEmpty())
            {
                return(false);
            }

            List <int> locations = new List <int>();

            for (int i = 0; i < word.Length; i++)
            {
                if (word[i] == insertionLetter.Letter)
                {
                    locations.Add(i);
                }
            }

            if (locations.Count == 0)
            {
                return(false);
            }

            String direction   = vertical;
            int    insertIndex = -1;
            int    decrease    = -1;
            int    plus        = -1;

            // Determine if it could be inserted horizontally
            foreach (int location in locations)
            {
                decrease = location;
                plus     = word.Length - location;

                if (insertionLetter.Column - decrease < 0 || insertionLetter.Column + plus > CrozzleColumn)
                {
                    continue;
                }
                bool Continue = false;
                for (int gLocation = insertionLetter.Column - decrease; gLocation < insertionLetter.Column + plus; gLocation++)
                {
                    if (gLocation == insertionLetter.Column)
                    {
                        continue;
                    }

                    if (GridContent[insertionLetter.Row, gLocation] != ' ')
                    {
                        Continue = true;
                        break;
                    }

                    if (gLocation == insertionLetter.Column - 1 || gLocation == insertionLetter.Column + 1)
                    {
                        // The 4 direction of inserted letter only allows 1 letter
                        if (CheckSurrounding(insertionLetter.Row, gLocation) > 1)
                        {
                            Continue = true;
                            break;
                        }

                        LetterInfo testLetter = new LetterInfo(insertionLetter.Row, gLocation, word[gLocation - (insertionLetter.Column - decrease)]);

                        // Check surrounding specific circumstances (2 letters around)
                        if (LetterInfo.HasAdjacentLetters(testLetter, insertionLetter, CrozzleRow, CrozzleColumn, GridContent))
                        {
                            Continue = true;
                            break;
                        }
                    }
                    else
                    {
                        if (CheckSurrounding(insertionLetter.Row, gLocation) > 0)
                        {
                            Continue = true;
                            break;
                        }
                    }
                }
                if (Continue == true)
                {
                    continue;
                }
                else
                {
                    // The word could be inserted horizontaly
                    direction   = horizontal;
                    insertIndex = location;
                    break;
                }
            }

            if (direction == vertical)
            {
                foreach (int location in locations)
                {
                    decrease = location;
                    plus     = word.Length - location;

                    if (insertionLetter.Row - decrease < 0 || insertionLetter.Row + plus > CrozzleRow)
                    {
                        continue;
                    }
                    bool Continue = false;
                    for (int gLocation = insertionLetter.Row - decrease; gLocation < insertionLetter.Row + plus; gLocation++)
                    {
                        if (gLocation == insertionLetter.Row)
                        {
                            continue;
                        }

                        if (GridContent[gLocation, insertionLetter.Column] != ' ')
                        {
                            Continue = true;
                            break;
                        }

                        if (gLocation == insertionLetter.Row - 1 || gLocation == insertionLetter.Row + 1)
                        {
                            // the same as vertical
                            if (CheckSurrounding(gLocation, insertionLetter.Column) > 1)
                            {
                                Continue = true;
                                break;
                            }

                            LetterInfo testLetter = new LetterInfo(gLocation, insertionLetter.Column, word[gLocation - (insertionLetter.Row - decrease)]);

                            if (LetterInfo.HasAdjacentLetters(testLetter, insertionLetter, CrozzleRow, CrozzleColumn, GridContent))
                            {
                                Continue = true;
                                break;
                            }
                        }
                        else
                        {
                            if (CheckSurrounding(gLocation, insertionLetter.Column) > 0)
                            {
                                Continue = true;
                                break;
                            }
                        }
                    }
                    if (Continue == true)
                    {
                        continue;
                    }
                    else
                    {
                        // The word can be inserted vertically
                        direction   = vertical;
                        insertIndex = location;
                        break;
                    }
                }
            }
            // If thw word can't be inserted
            if (insertIndex == -1)
            {
                return(false);
            }

            if (direction == horizontal)
            {
                for (int gLocation = insertionLetter.Column - decrease, i = 0; gLocation < insertionLetter.Column + plus; gLocation++, i++)
                {
                    GridContent[insertionLetter.Row, gLocation] = word[i];
                }
            }
            else if (direction == vertical)
            {
                for (int gLocation = insertionLetter.Row - decrease, i = 0; gLocation < insertionLetter.Row + plus; gLocation++, i++)
                {
                    GridContent[gLocation, insertionLetter.Column] = word[i];
                }
            }
            SaveLetters();
            score = WordInfo.CalculateScore(pointsPerWord, CrozzleRow, CrozzleColumn, GridContent, IntersectingPointsPerLetter, NonIntersectingPointsPerLetter);
            return(true);
        }
Пример #2
0
        /// <summary>
        /// Contains Greedy Algorithm which searches the best fit grid
        /// </summary>
        /// <param name="wordlist"></param>
        /// <returns></returns>
        public List <String> GreedyAlgorithm(List <String> wordlist, int maxGroup, int minGroup, out TimeSpan timeConsume)
        {
            // Set timer
            timer = new Stopwatch();
            timer.Start();

            Grid maxGrid = null;
            Grid grid    = new Grid(CrozzleRow, CrozzleColumn, IntersectingPointsPerLetter, NonIntersectingPointsPerLetter, pointsPerWord);

            List <String> temp = new List <string>();


            // Get all posibilities of the first insertion word lication and orientations
            List <Grid> firstChilds = new List <Grid>();

            if (IsEmpty())
            {
                // Get the first inserted letter or letters under multiple group circumstances
                int    currentScore             = -1;
                String firstInsertedWord        = null;
                String firstInsertedWord2       = null;
                char   firstIntersectiveLetter  = '\0';
                char   firstIntersectiveLetter2 = '\0';
                foreach (char key in IntersectingPointsPerLetter.Keys)
                {
                    temp.Clear();
                    temp.AddRange(wordlist);

                    firstIntersectiveLetter = key;

                    currentScore = -1;
                    foreach (String word in wordlist)
                    {
                        int baseScore = WordInfo.GetBaseScore(word, firstIntersectiveLetter, maxGroup, IntersectingPointsPerLetter, NonIntersectingPointsPerLetter, pointsPerWord);
                        if (currentScore < baseScore)
                        {
                            currentScore      = baseScore;
                            firstInsertedWord = word;
                        }
                    }
                    temp.Remove(firstInsertedWord);

                    if (maxGroup >= 2 && minGroup != 1)
                    {
                        int currentScore2 = -1;

                        foreach (char key1 in IntersectingPointsPerLetter.Keys)
                        {
                            if (currentScore2 < IntersectingPointsPerLetter[key1])
                            {
                                currentScore2            = IntersectingPointsPerLetter[key1];
                                firstIntersectiveLetter2 = key1;
                            }
                        }

                        currentScore2 = -1;
                        foreach (String word in temp)
                        {
                            int basescore = WordInfo.GetBaseScore(word, firstIntersectiveLetter2, maxGroup, IntersectingPointsPerLetter, NonIntersectingPointsPerLetter, pointsPerWord);
                            if (currentScore2 < basescore)
                            {
                                currentScore2      = basescore;
                                firstInsertedWord2 = word;
                            }
                        }
                        temp.Remove(firstInsertedWord2);
                    }

                    // All horizental insertions posibilities
                    for (int r = 0; r <= CrozzleRow - 1; r++)
                    {
                        for (int c = 0; c <= CrozzleColumn - firstInsertedWord.Length; c++)
                        {
                            Grid tempGrid = new Grid(CrozzleRow, CrozzleColumn, IntersectingPointsPerLetter, NonIntersectingPointsPerLetter, PointsPerWord);
                            tempGrid.subWordList = new List <string>();
                            if (maxGroup > 1 && minGroup != 1)
                            {
                                if (r <= 1)
                                {
                                    if (c + firstInsertedWord.Length >= CrozzleColumn - firstInsertedWord2.Length - 1)
                                    {
                                        continue;
                                    }
                                }
                                for (int i = 0; i < firstInsertedWord2.Length; i++)
                                {
                                    if (CrozzleColumn - firstInsertedWord2.Length + i < 0)
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        tempGrid.GridCoordinate[0, CrozzleColumn - firstInsertedWord2.Length + i] = firstInsertedWord2[i];
                                    }
                                }
                            }

                            for (int lp = 0; lp < firstInsertedWord.Length; lp++)
                            {
                                tempGrid.GridCoordinate[r, c + lp] = firstInsertedWord[lp];
                                tempGrid.SaveLetters();
                                score = WordInfo.CalculateScore(pointsPerWord, CrozzleRow, CrozzleColumn, GridContent, IntersectingPointsPerLetter, NonIntersectingPointsPerLetter);
                            }
                            if (!tempGrid.IsEmpty())
                            {
                                tempGrid.subWordList.AddRange(temp);
                                firstChilds.Add(tempGrid);
                            }
                        }
                    }

                    // All vertical insertions posibilities
                    for (int c = 0; c < CrozzleColumn; c++)
                    {
                        for (int r = 0; r <= CrozzleRow - firstInsertedWord.Length; r++)
                        {
                            Grid tempGrid = new Grid(CrozzleRow, CrozzleColumn, IntersectingPointsPerLetter, NonIntersectingPointsPerLetter, PointsPerWord);
                            tempGrid.subWordList = new List <string>();
                            if (maxGroup > 1 && minGroup != 1)
                            {
                                if (r <= 2)
                                {
                                    if (c >= CrozzleColumn - firstInsertedWord2.Length - 1)
                                    {
                                        continue;
                                    }
                                }

                                for (int i = 0; i < firstInsertedWord2.Length; i++)
                                {
                                    if (CrozzleColumn - firstInsertedWord2.Length + i < 0)
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        tempGrid.GridCoordinate[0, CrozzleColumn - firstInsertedWord2.Length + i] = firstInsertedWord2[i];
                                    }
                                }
                            }

                            for (int lp = 0; lp < firstInsertedWord.Length; lp++)
                            {
                                tempGrid.GridCoordinate[r + lp, c] = firstInsertedWord[lp];
                                tempGrid.SaveLetters();
                                score = WordInfo.CalculateScore(pointsPerWord, CrozzleRow, CrozzleColumn, GridContent, IntersectingPointsPerLetter, NonIntersectingPointsPerLetter);
                            }
                            if (!tempGrid.IsEmpty())
                            {
                                tempGrid.subWordList.AddRange(temp);
                                firstChilds.Add(tempGrid);
                            }
                        }
                    }
                }
            }

            // Find the rest insertions, get the best grid
            for (int i = 0; i < firstChilds.Count && timer.Elapsed.TotalMilliseconds < 400000; i++)
            {
                if (minGroup != 1)
                {
                    firstChilds[i].GetBestWordData(firstChilds[i].subWordList, maxGroup);
                }
                else
                {
                    firstChilds[i].GetBestWordData(firstChilds[i].subWordList, 1);
                }

                // Validate each generated crozzle
                CrozzleValid = Validate(firstChilds[i]);
                if (firstChilds[i].Score > grid.Score && CrozzleValid)
                {
                    grid = firstChilds[i];
                }
            }

            // Generate the newKeyValue to replace the origialKeyValue
            maxGrid = grid;
            List <String>   GenerateKeyValueGroup = new List <string>();
            List <WordInfo> list    = WordInfo.GetWordInfo(grid.GridContent, CrozzleRow, CrozzleColumn);
            String          newLine = null;

            foreach (WordInfo word in list)
            {
                if (word.direction == horizontal)
                {
                    newLine = "ROW=" + (word.startRow + 1) + "," + word.word + "," + (word.startCol + 1);
                    GenerateKeyValueGroup.Add(newLine);
                }
            }
            foreach (WordInfo word in list)
            {
                if (word.direction == vertical)
                {
                    newLine = "COLUMN=" + (word.startCol + 1) + "," + word.word + "," + (word.startRow + 1);
                    GenerateKeyValueGroup.Add(newLine);
                }
            }

            // Stop the time after calculation
            timer.Stop();
            // If the time has passed the limit
            if (timer.Elapsed.TotalMilliseconds >= 400000)
            {
                timeConsume = TimeSpan.Zero;
            }
            else
            {
                timeConsume = timer.Elapsed;
            }

            return(GenerateKeyValueGroup);
        }