public void SearchWords(string substr, ref List<Pair<char, int>> ret) { ret.Clear(); if (substr.Length > 0) { char c = char.ToLower(substr[0]); int start = c - 'a'; for (int i = 0; i < words[start].Count; ++i) { if (words[start][i].word.StartsWith(substr)) { ret.Add(Pairs.MakePair(c, i)); } } } if (ret.Count > 0) { ret.OrderBy(x => x.Right); } }
static Pair <WordBlock, int> PlaceVertical(ref List <WordBlock> data, Alphaword word, int i, int width, int height) { List <Pair <WordBlock, int> > results = new List <Pair <WordBlock, int> >(); for (int l = 0; l < data[i].Length; ++l) { Coordinates cell = data[i][l]; for (int j = 0; j < word.Length; ++j) { if (word.word[j] != data[i][cell]) { // cant overlap continue; } // check if vertical word can fit in grid. Coordinates v_start = new Coordinates(cell.x, cell.y - j); Coordinates v_end = new Coordinates(cell.x, cell.y + (word.Length - j - 1)); bool v_front_ok = !(v_start.y < 0); bool v_back_ok = !(v_end.y >= height); if (!v_front_ok) { // because word is pushed "upwards" to test whole word, // if word leaves top of board then it will definitely be // invalid for the rest. break; } else if (!v_back_ok) { // no space below, try next new word letter. continue; } else { int score = 1; bool placeOK = true; // try placement. check if all other words overlap properly, if any overlap occurs. for (int w = 0; w < data.Count && placeOK; ++w) { if (w == i) { continue; } // check if word clashes with other word for (int y = 0; y < word.Length; ++y) { int x = cell.x; Coordinates pos = new Coordinates(x, v_start.y + y); char other = data[w][pos]; if (other == Cell.Empty) { // not clashing Coordinates[] dir = new Coordinates[] { new Coordinates(pos.x + 1, pos.y), new Coordinates(pos.x - 1, pos.y), new Coordinates(pos.x, pos.y + 1), new Coordinates(pos.x, pos.y - 1) }; bool near = false; // cannot be right beside the word. for (int d = 0; d < dir.Length && !near; ++d) { char test = data[w][dir[d]]; if (test != Cell.Empty) { near = true; } } if (near) { placeOK = false; } continue; } else if (other == word.word[y] && data[w].IsHorizontal) { // overlap same character break; } else { // fail placeOK = false; } } } if (placeOK) { // add word block and score. results.Add(Pairs.MakePair(new WordBlock(word, v_start, v_end), score)); } } } } if (results.Count == 0) { return(null); } results.Sort((x, y) => x.Right.CompareTo(y.Right)); return(results[results.Count - 1]); }
static Pair <List <WordBlock>, Coordinates> GenerateWordBlocksOnly(List <Alphaword> words, out int width, out int height, int max_tries = 1000) { if (words.Count < 2) { Debug.Log("no words!"); width = 0; height = 0; return(null); } if (words.Count > 10) { words.RemoveRange(10, words.Count - 10); } List <Alphaword> sorted_words = CopyWordList(words); SortWordListDescending(ref sorted_words); int base_width = width = sorted_words[0].Length + sorted_words[sorted_words.Count - 1].Length; int base_height = height = width; int base_dim = base_width * base_height; int best_score = 0; Pair <List <WordBlock>, Coordinates> best_gen_words = null; var rng = new System.Random(); for (int i = 0; i < max_tries; ++i) { var result = sorted_words.OrderBy(x => rng.Next()); sorted_words = new List <Alphaword>(result); List <WordBlock> gen_words = new List <WordBlock>(); int curr_score = 0; bool curr_tryOK = true; int currWidth = 0; int currHeight = 0; int MinWidth = int.MaxValue; int MinHeight = int.MaxValue; for (int curr_word = 0; curr_word < sorted_words.Count && curr_tryOK; ++curr_word) { if (gen_words.Count == 0) { // place first word int dx = Random.Range(0, 2); int dy = (dx == 0) ? 1 : 0; int range_x = width - sorted_words[curr_word].Length; int range_y = height - sorted_words[curr_word].Length; int start_x = Random.Range(0, range_x); int start_y = Random.Range(0, range_y); Coordinates first_start = new Coordinates(start_x, start_y); Coordinates first_end = new Coordinates(first_start.x + (sorted_words[curr_word].Length - 1) * dx, (first_start.y + sorted_words[curr_word].Length - 1) * dy); currWidth = first_end.x + 1; currHeight = first_end.y + 1; MinWidth = first_start.x; MinHeight = first_start.y; gen_words.Add(new WordBlock(sorted_words[curr_word], first_start, first_end)); } else { // place every other word // test overlap var curr_result = PlaceWord(ref gen_words, sorted_words[curr_word], width, height); if (curr_result != null) { gen_words.Add(curr_result.Left); currWidth = Mathf.Max(currWidth, curr_result.Left.End.x + 1); currHeight = Mathf.Max(currHeight, curr_result.Left.End.y + 1); MinWidth = Mathf.Min(MinWidth, curr_result.Left.Start.x); MinHeight = Mathf.Min(MinHeight, curr_result.Left.Start.y); curr_score += curr_result.Right; } else { curr_tryOK = false; } } } if (curr_tryOK) { // offset to zero. for (int curr = 0; curr < gen_words.Count; ++curr) { Coordinates curr_start = gen_words[curr].Start; Coordinates curr_end = gen_words[curr].End; gen_words[curr].Place(new Coordinates(curr_start.x - MinWidth, curr_start.y - MinHeight), new Coordinates(curr_end.x - MinWidth, curr_end.y - MinHeight)); } currWidth -= MinWidth; currHeight -= MinHeight; int curr_dim = currWidth * currHeight; // the smaller the board, the better the score. curr_score += (base_dim - curr_dim); if (curr_score > best_score) { best_gen_words = Pairs.MakePair(gen_words, new Coordinates(currWidth, currHeight)); best_score = curr_score; } } } // setup board using gen_words and return return(best_gen_words); }