Пример #1
0
        /// <summary>
        /// Find the best fit grid based on the first child
        /// </summary>
        /// <param name="wordList"></param>
        private void GetBestWordData(List <String> wordList, int maxGroup)
        {
            if (wordList == null || maxGroup == 0)
            {
                return;
            }

            List <LetterInfo> traversedLetters = new List <LetterInfo>();
            List <String>     traversedWords   = new List <string>();

            List <LetterInfo> temp = new List <LetterInfo>();

            // Test which letter would be the most suitable insertion letter in current word
            foreach (LetterInfo letter in letters)
            {
                temp.Add(letter);
            }

            while (temp.Count > 0)
            {
                List <LetterInfo> IntersectionLetterList = new List <LetterInfo>();

                // Find out what letter in suitable for insertion letter
                foreach (LetterInfo letter in temp)
                {
                    IntersectionLetterList.Add(letter);
                }

                if (IntersectionLetterList.Count == 0)
                {
                    break;
                }

                // Test each word from remaining words in wordlist
                List <String> remainWordList = new List <String>();
                foreach (String word in wordList)
                {
                    remainWordList.Add(word);
                }
                foreach (String word in traversedWords)
                {
                    remainWordList.Remove(word);
                }

                // Find out the following best insertion words
                while (IntersectionLetterList.Count > 0 && remainWordList.Count > 0)
                {
                    int           baseScore   = -1;
                    List <String> insertWords = new List <string>();
                    foreach (String word in remainWordList)
                    {
                        bool IsInsertionLetter = false;

                        for (int i = 0; i < IntersectionLetterList.Count; i++)
                        {
                            foreach (char letter in word)
                            {
                                if (letter == IntersectionLetterList[i].Letter)
                                {
                                    IsInsertionLetter = true;
                                }
                            }
                            if (IsInsertionLetter == true)
                            {
                                int actualScore = WordInfo.GetBaseScore(word, IntersectionLetterList[i].Letter, maxGroup, IntersectingPointsPerLetter, NonIntersectingPointsPerLetter, pointsPerWord);
                                if (baseScore < actualScore)
                                {
                                    insertWords.Clear();
                                    baseScore = actualScore;
                                    insertWords.Add(word);
                                }
                                else if (baseScore == actualScore)
                                {
                                    insertWords.Add(word);
                                }
                            }
                        }
                    }

                    if (insertWords.Count == 0)
                    {
                        break;
                    }

                    for (int i = 0; i < IntersectionLetterList.Count; i++)
                    {
                        for (int j = 0; j < insertWords.Count; j++)
                        {
                            if (InsertWords(IntersectionLetterList[i], insertWords[j]))
                            {
                                traversedWords.Add(insertWords[j]);
                                remainWordList.Remove(insertWords[j]);
                                insertWords.Remove(insertWords[j]);

                                temp.Clear();
                                foreach (LetterInfo letter in letters)
                                {
                                    temp.Add(letter);
                                }

                                traversedLetters.Add(IntersectionLetterList[i]);
                                IntersectionLetterList.Remove(IntersectionLetterList[i]);
                                i--;
                                j--;

                                break;
                            }
                        }
                    }
                    for (int i = 0; i < insertWords.Count; i++)
                    {
                        remainWordList.Remove(insertWords[i]);
                    }
                }

                for (int i = 0; i < IntersectionLetterList.Count; i++)
                {
                    traversedLetters.Add(IntersectionLetterList[i]);
                }
                foreach (LetterInfo letter in traversedLetters)
                {
                    if (temp.Contains(letter))
                    {
                        temp.Remove(letter);
                    }
                }
            }
        }
Пример #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);
        }