Пример #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>
        /// 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);
        }
Пример #3
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);
        }