public List <Play> ValidPlays() { List <Play> plays = new List <Play>(); #region //Implementation for IsSingle cases if (IsSingle()) { bool blankExists = false; int blankIndex = -1; List <Tile> tiles = Game.GetTray().Tiles; for (int i = 0; i < tiles.Count; i++) { if (tiles[i].GetLetter() == '?') { blankExists = true; blankIndex = i; continue; } Play thisPlay = new Play(new List <Tuple <Space, Tile> > { Tuple.Create(_spaceList[0], tiles[i]) }, Game); if (thisPlay.AreWordsValid()) { plays.Add(thisPlay); } } if (blankExists) { for (int i = 0; i < 26; i++) { char tempChar = (char)('A' + i); Tile blankTile = new Tile('?'); blankTile.SetBlank(tempChar); Play thisPlay = new Play(new List <Tuple <Space, Tile> > { Tuple.Create(_spaceList[0], blankTile) }, Game); if (thisPlay.AreWordsValid()) { plays.Add(thisPlay); } } } return(plays); } #endregion #region //Implementation for multi-Space Placements string tray = Game.GetTrayString(); PlacementMatrix placementMatrix = new PlacementMatrix(this); List <string> possiblePrimaryWords = new List <string>(); if (!placementMatrix.DoesExclude()) { possiblePrimaryWords = WordFind(placementMatrix); } //Now remove the anchors so the remaining letters can be matched up to the spaces in the Placement to form Play instances List <Tuple <int, char> > sortedAnchors = placementMatrix.AnchorTuples.OrderBy(x => x.Item1).ToList(); for (int i = 0; i < possiblePrimaryWords.Count; i++) { string newWord = possiblePrimaryWords[i]; for (int j = 0; j < sortedAnchors.Count; j++) { if (newWord[sortedAnchors[j].Item1 - j] != sortedAnchors[j].Item2) { throw new Exception("Bad design bro, your anchors aren't where you think they are!"); } newWord = newWord.Remove(sortedAnchors[j].Item1 - j, 1); } possiblePrimaryWords[i] = newWord; } //At this point possiblePrimaryWords should have been scrubbed of the anchor letters foreach (string word in possiblePrimaryWords) { if (word.Length != _spaceList.Count) { throw new Exception("You done messed up! You're Play ain't the same size as your Placement."); } List <string> possibleCombinations = word.WildCardCombinations(tray); foreach (string combo in possibleCombinations) { List <Tuple <Space, Tile> > newPlayList = new List <Tuple <Space, Tile> >(); for (int i = 0; i < _spaceList.Count; i++) { Tile thisTile = new Tile(combo[i]); if (combo[i] == '?') { thisTile.SetBlank(word[i]); } newPlayList.Add(Tuple.Create(_spaceList[i], thisTile)); } plays.Add(new Play(newPlayList, Game)); } } return(plays); #endregion }
private List <string> WordFind(PlacementMatrix placementMatrix) { string tray = Game.GetTrayString(); string[] dictionary = Game.GetDictionary(); List <Tuple <int, char> > anchorTuples = placementMatrix.AnchorTuples; List <Tuple <int, char> > exclusionTuples = placementMatrix.ExclusionTuples; int wordSize = placementMatrix.PrimaryWordSpaces.Count; HashSet <string> resultHashSet = new HashSet <string> { }; string letters = tray.Replace("?", ""); int numberOfBlanks = tray.Length - letters.Length; //Adding anchor letters to the letters string if (anchorTuples != null) { foreach (var anchor in anchorTuples) { letters += anchor.Item2; } } letters = letters.ToUpper(); int[] available = new int[26]; foreach (char c in letters) { int index = c - 'A'; available[index] += 1; } foreach (string word in dictionary) { //vet for length if (word.Length != wordSize) { continue; } //vet for anchors if (anchorTuples != null) { bool possible = true; foreach (var pair in anchorTuples) { if (word[pair.Item1] != pair.Item2) { possible = false; break; } } if (!possible) { continue; } } //vet exclusions if (exclusionTuples != null) { bool possible = true; foreach (var pair in exclusionTuples) { if (word[pair.Item1] == pair.Item2) { possible = false; break; } } if (!possible) { continue; } } //done vetting, proceed with normal search int[] tempAvailable = new int[26]; Array.Copy(available, tempAvailable, 26); int wildcardsLeft = numberOfBlanks; int[] count = new int[26]; bool ok = true; foreach (char c in word.ToCharArray()) { int index = c - 'A'; count[index] += 1; if (count[index] - tempAvailable[index] > wildcardsLeft) { ok = false; break; } else if (count[index] > tempAvailable[index]) { wildcardsLeft--; tempAvailable[index]++; } } if (ok) { resultHashSet.Add(word); } } return(resultHashSet.ToList()); }