public int CalculatePoints(PotentialTurn turn) { int pointCount = 0; int multiplier = 1; int letterIndex = 0; for (int i = 0; i < turn.Cells.Count(); i++) { if (turn.Cells[i].Letter == null) { int pointsForNewLetter = turn.Letters[letterIndex].Value; if (turn.Cells[i].Modifier != null) { if (turn.Cells[i].Modifier.AffectsWholeString) { multiplier = multiplier * turn.Cells[i].Modifier.ModifierValue; } else { pointsForNewLetter = pointsForNewLetter * turn.Cells[i].Modifier.ModifierValue; } } pointCount += pointsForNewLetter; letterIndex++; } else { pointCount += turn.Cells[i].Letter.Value; } } return(pointCount * multiplier); }
/// <summary> /// Checks all possible permutations for given list of empty cells /// </summary> /// <param name="permutations">The list of permutations to check</param> /// <param name="cells">The row/column</param> /// <param name="perpendicularLists">The list of perpendicular cells</param> /// <param name="perpendicularIndex">If checking a row, this should be the row index. Otherwise, it should be the column index.</param> /// <param name="emptyCellIndices">The list of empty cells to fill</param> /// <param name="invalidCharsPerCell">The list of invalid characters</param> /// <param name="progress">The progress</param> /// <returns>The list of potential turns</returns> private List <PotentialTurn> CheckPermutations( IEnumerable <List <Letter> > permutations, List <BoardCell> cells, List <List <BoardCell> > perpendicularLists, int perpendicularIndex, List <int> emptyCellIndices, HashSet <char>[] invalidCharsPerCell, ProgressReport progress) { List <PotentialTurn> potentialTurns = new List <PotentialTurn>(); List <BoardCell> cellRange = GetCompleteWord(cells, emptyCellIndices[0], emptyCellIndices[emptyCellIndices.Count() - 1]); List <Letter> cellLetters = cellRange.Select(x => x.Letter).ToList(); // check each permutation foreach (List <Letter> permutation in permutations) { int placedLetterIndex = 0; bool isValid = true; List <char> finalLetters = new List <char>(); // for each cell that is about to be filled in for (var i = 0; i < cellLetters.Count(); i++) { // if the letter is empty, place the first letter if (cellLetters[i] == null) { char character = permutation[placedLetterIndex].Character; int emptyCellIndex = emptyCellIndices[placedLetterIndex]; // check to see if the list of invalid characters contains this letter that's being placed if (invalidCharsPerCell[emptyCellIndex] != null && invalidCharsPerCell[emptyCellIndex].Contains(character)) { isValid = false; break; } finalLetters.Add(character); placedLetterIndex++; } else { finalLetters.Add((char)cellLetters[i].Character); } } if (!isValid) { continue; } string word = new string(finalLetters.ToArray()); // check to see if the word is valid, and also if that any perpendicular cells are valid with the placed letters if (dictionary.SearchWord(word) && DoesFitWithPerpendicularLists(permutation, emptyCellIndices, perpendicularLists, perpendicularIndex, invalidCharsPerCell)) { progress.WordsChecked++; PotentialTurn potentialTurn = new PotentialTurn() { Word = word, Cells = cellRange, Letters = permutation }; // calculate the points potentialTurn.Points = pointCalculatorLogic.CalculatePoints(potentialTurn); potentialTurns.Add(potentialTurn); } } return(potentialTurns); }
static void Main(string[] args) { var factory = new ScrabbleLogicFactory(); var turnCalculator = factory.GetTurnCalculator(); var board = factory.GetBoardBuilder().BuildBoard(); var bagLogic = factory.GetLetterBagLogic(); var bag = factory.GetLetterBagBuilder().GenerateLetterBag(); var csvFile = ReadCsvFile(); for (int rowIndex = 0; rowIndex < csvFile.Count(); rowIndex++) { for (int columnIndex = 0; columnIndex < csvFile[rowIndex].Count; columnIndex++) { if (!string.IsNullOrWhiteSpace(csvFile[rowIndex][columnIndex])) { char character = csvFile[rowIndex][columnIndex][0]; var letter = bag.First(x => x.Character == character); board.Cells[rowIndex][columnIndex].Letter = letter; } } } var chars = new List <Letter>() { bag.First(x => x.Character == 'u'), bag.First(x => x.Character == 'g'), bag.First(x => x.Character == 'y'), bag.First(x => x.Character == 'g'), bag.First(x => x.Character == 'r'), bag.First(x => x.Character == 'l'), bag.First(x => x.Character == 'u') }; Stopwatch watch = new Stopwatch(); watch.Start(); ProgressReport progress = new ProgressReport(); var turnTask = turnCalculator.CalculateTurnAsync(board, new LetterRack() { Letters = chars }, progress); while (!progress.IsProgressInitialized) { } while (!turnTask.IsCompleted) { //double percentDone = progress.CellsChecked / (double)progress.TotalCells * 100.0; //Console.WriteLine(string.Format("{0}% done, {1} words checked, {2}/{3} cells checked", percentDone, progress.WordsChecked, progress.CellsChecked, progress.TotalCells)); //Thread.Sleep(100); } var turns = turnTask.Result; watch.Stop(); Console.WriteLine("Discovered " + turns.Count() + " turns in " + watch.ElapsedMilliseconds + " ms."); turns = turns.Take(10).ToList(); int turnNum = 1; foreach (var turn in turns) { StringBuilder builder = new StringBuilder(); builder.Append(turnNum + " -Letters: "); builder.Append(string.Join(",", turn.Letters.Select(x => x.Character))); builder.Append(", total points: "); builder.Append(turn.Points); builder.Append(", to create word: "); builder.Append(turn.Word); Console.WriteLine(builder.ToString()); turnNum++; } string next = Console.ReadLine(); while (next != "e") { int selectedNum; if (!Int32.TryParse(next, out selectedNum)) { continue; } var copiedBoard = new char[board.Cells.Count()][]; int cellIndex = 0; foreach (var row in board.Cells) { copiedBoard[cellIndex] = board.Cells[cellIndex].Select(x => x.Letter == null ? '.' : x.Letter.Character).ToArray(); cellIndex++; } PotentialTurn selectedTurn = turns.ElementAt(selectedNum - 1); int letterIndex = 0; foreach (var cell in selectedTurn.Cells) { copiedBoard[cell.Row][cell.Column] = selectedTurn.Word[letterIndex]; letterIndex++; } foreach (var row in copiedBoard) { Console.WriteLine(string.Join(" ", row)); } next = Console.ReadLine(); } }