예제 #1
0
        /// <summary>
        /// Метод формирует варианты из ближайших клеток к клетке, индекс которой передан в параметре startIdx, если в дереве есть подходящие ветки.
        /// Если попалась пустая клетка, то формирует варианты с любой возможной буквой (если в текуще ветке такие есть)
        /// Либо метод формирует один вариант, на клетке, с индексом startIdx
        /// </summary>
        /// <param name="startIdx"></param>
        /// <param name="wordStart"></param>
        /// <returns>список найденных вариантов</returns>
        private List <WordVariant> GetNearestVariants(CellIndex startIdx, WordVariant wordStart)
        {
            CellIndex[] nearestIndexes;
            if (wordStart.Branch.WordPart.Length == 0)
            {
                //индекс текущей клетки. Если только начал подбирать слова и вариант пока пустой
                nearestIndexes    = new CellIndex[1];
                nearestIndexes[0] = startIdx;
            }
            else
            {
                //индексы клеток справа, слева, выше и ниже от текущей клетки
                nearestIndexes    = new CellIndex[4];
                nearestIndexes[0] = new CellIndex(startIdx.X + 1, startIdx.Y);
                nearestIndexes[1] = new CellIndex(startIdx.X - 1, startIdx.Y);
                nearestIndexes[2] = new CellIndex(startIdx.X, startIdx.Y + 1);
                nearestIndexes[3] = new CellIndex(startIdx.X, startIdx.Y - 1);
            }
            var nearestVariants = new List <WordVariant>();

            foreach (CellIndex idx in nearestIndexes)   //check these variants for aviability
            //check if cell is not out of playfield bounds and check if I didn't use this cell
            {
                if (idx.X < playFieldSize && idx.Y < playFieldSize &&
                    idx.X >= 0 && idx.Y >= 0 &&
                    !CellIndex.ListHasIndex(idx, wordStart.Path))  //todo переделать для модификации балды "узелки"
                {
                    var c = PlayField[idx.X, idx.Y];

                    if (c == ' ' && !wordStart.UsedEmptyCell)
                    {
                        //ситуация, когда натолкнулся на пустую клетку, и могу использовать ее как "любую букву"
                        for (var i = 0; i < wordStart.Branch.LinkedChars.Length; i++)
                        {
                            var tmp = new WordVariant(wordStart, wordStart.Branch.Next[i])
                            {
                                UsedEmptyCell  = true,
                                EmptyCellIndex = idx
                            };
                            tmp.ExtendPath(idx);
                            nearestVariants.Add(tmp);
                        }
                    }
                    else if (c != ' ')
                    {
                        //клетка непустая. Ищу подходящую ветку
                        if (wordStart.Branch.LinkedChars.Contains(c))
                        {
                            var pos = Array.IndexOf(wordStart.Branch.LinkedChars, c);
                            var tmp = new WordVariant(wordStart, wordStart.Branch.Next[pos]);
                            tmp.ExtendPath(idx);
                            nearestVariants.Add(tmp);
                        }
                    }
                }
            }
            return(nearestVariants);
        }
예제 #2
0
 public static bool ListHasIndex(CellIndex searchedIndex, CellIndex[] indexList)
 {
     foreach (CellIndex idx in indexList)
     {
         if (searchedIndex.X == idx.X && searchedIndex.Y == idx.Y)
         {
             return(true);
         }
     }
     return(false);
 }
예제 #3
0
        private List <WordVariant> GetVariantsAt(CellIndex startIdx, WordVariant wordStart)
        {
            //сюда попадают слова, которые удалось собрать по полю
            var resVariants = new List <WordVariant>();

            //TODO: optimize search variants
            if (wordStart.Branch.LinkedChars.Length == 0 && PlayField[startIdx.X, startIdx.Y] == ' ')
            {
                wordStart.UsedEmptyCell  = true;
                wordStart.EmptyCellIndex = startIdx;
            }
            //к текущей имеющейся начальной части слова прибавляем букву,
            //которая есть в клетке по соседству (если есть). Если рядом три непустые клетки,
            //то получится три части, которые надо проверить по словарю
            var tempVars = GetNearestVariants(startIdx, wordStart);

            if (tempVars.Count > 0)
            {
                foreach (var tmp in tempVars)
                {
                    //если после поиска вариантов есть такие, что слово полностью собралось
                    //и была использована пустая клетка,
                    //то в рещультирующую выборку добавляю этот вариант
                    if (tmp.UsedEmptyCell && tmp.Branch.Word != null)
                    {
                        resVariants.Add(tmp);
                    }

                    var longerVariants = GetVariantsAt(tmp.Path[tmp.Path.Length - 1], tmp);
                    foreach (var newVariant in longerVariants)
                    {
                        var isRepeat = false;
                        var newWord  = new string(newVariant.Branch.Word);
                        foreach (var existingVariant in resVariants) //look for repeats in candidates
                        {
                            var existingWord = new string(existingVariant.Branch.Word);
                            if (existingWord == newWord)
                            {
                                isRepeat = true;
                                break;
                            }
                        }
                        if (!isRepeat)
                        {
                            resVariants.Add(newVariant);
                        }
                    }
                }
            }
            return(resVariants);
        }
예제 #4
0
 public void ExtendPath(CellIndex cellIndex)
 {
     Array.Resize(ref Path, Path.Length + 1);
     Path[Path.Length - 1] = cellIndex;
 }
예제 #5
0
        /// <summary>
        /// метод служит для поиска всех возможных вариантов на поле.
        /// </summary>
        /// <param name="playField">игровое поле</param>
        /// <param name="unusedOnly">смотреть ли на список использованных в игре слов</param>
        /// <returns>список слов в виде wordVariant</returns>
        public List <WordVariant> GetPossibleVariants(char[,] playField, bool unusedOnly)
        {
            PlayField = playField;
            var allVariants = new List <WordVariant>();

            for (var x = 0; x < 5; x++)
            {
                for (var y = 0; y < 5; y++)
                {
                    var idx = new CellIndex(x, y);
                    //поиск идет от любой заполненной клетки (т.е. первая буква не может быть на пустом слове)
                    if (PlayField[x, y] != ' ' || startAtEmptyCell)
                    {
                        allVariants.AddRange(GetVariantsAt(idx, new WordVariant(wordsTree)));
                    }
                }
            }

            allVariants = RemoveDuplicates(allVariants);

            if (!unusedOnly)
            {
                allVariants.Sort(VariantComparer);
                return(allVariants);
            }


            if (allVariants.Count > 0)
            {
                var filteredVariants = new List <WordVariant>();
                foreach (var variant in allVariants)
                {
                    var variantChars = new string(variant.Branch.Word);
                    foreach (var usedWord in usedWords)
                    {
                        //find repeats in already used words
                        if (usedWord == variantChars)
                        {
                            break;
                        }

                        //бывают одинаковые вариантыза один вызов. Тут они отсеиваются.
                        //todo чето в линк конвертнуть можно... хз
                        foreach (var notUsedVar in filteredVariants)
                        {
                            //find repeats in filtered variants
                            var filteredWord = new string(notUsedVar.Branch.Word);
                            if (filteredWord != variantChars)
                            {
                                continue;
                            }
                            break;
                        }
                        filteredVariants.Add(variant);
                    }
                }
                if (filteredVariants.Count > 0)
                {
                    filteredVariants.Sort(VariantComparer);
                }
                return(filteredVariants);
            }
            return(new List <WordVariant>());
        }