public int VariantComparer(WordVariant x, WordVariant y) { if (x == null) { if (y == null) { return(0); } return(-1); } if (y == null) { return(1); } var retval = x.Branch.Word.Length.CompareTo(y.Branch.Word.Length); if (retval != 0) { return(retval); } var xstr = new string(x.Branch.Word); var ystr = new string(y.Branch.Word); return(String.Compare(xstr, ystr, StringComparison.Ordinal)); }
/// <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); }
/// <summary> /// создает новый вариант, на букву длиннее предыдущего /// </summary> /// <param name="start">предыдущий найденный вариант</param> /// <param name="branch">найденная для этого варианта ветка</param> public WordVariant(WordVariant start, LinkedChar branch) { //if (branch.LinkedChars.Length >= start.Branch.LinkedChars.Length) {//todo выяснить, зачем эта проверка UsedEmptyCell = start.UsedEmptyCell; //Completed = start.Completed; Branch = branch; Path = new CellIndex[start.Path.Length]; start.Path.CopyTo(Path, 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); }
public WordVariant GetLongestWord(char[,] playfield) { var filteredVariants = GetPossibleVariants(playfield, true); if (filteredVariants.Count > 0) { var longestWordLength = 0; WordVariant longestVariant = null; foreach (var variant in filteredVariants) { if (variant.Branch.Word.Length <= longestWordLength) { continue; } longestWordLength = variant.Branch.Word.Length; longestVariant = variant; } return(longestVariant); } return(null); }
public void HighlightWord(WordVariant wordVariant) { UnlightField(); foreach (Control c in panel1.Controls) { var b = c as BaldaFieldButton; if (b != null) { foreach (var idx in wordVariant.Path) { if (b.indexX == idx.X + 1 && b.indexY == idx.Y + 1) { b.Highlight(); if (idx == wordVariant.EmptyCellIndex) { b.HighLighter(); } } } } } }
public void AddWordInList(WordVariant word) { //textBox1.AppendText("\n" + word); listBox1.Items.Add(word); }