private void TryEveryVariantIfNoSolusion() { int indexOfFirstElement = RowOrColumnToBeCalculated.GetIndexOfRowOrColumnByNumberInQueue(rowsAndColumnsToBeCalculated, 0); int variantsCount = rowsAndColumnsToBeCalculated[indexOfFirstElement].VariantsCount; CloneOfStaticsOfRowOrColumnToBeCalculated clone = new CloneOfStaticsOfRowOrColumnToBeCalculated(rowsAndColumnsToBeCalculated, indexOfFirstElement); for (int i = 0; i < variantsCount; i++) { RowOrColumnToBeCalculated.SetStatics(rowsAndColumnsToBeCalculated, clone); rowsAndColumnsToBeCalculated[indexOfFirstElement].possibleSolutions = new List <bool[]>(); rowsAndColumnsToBeCalculated[indexOfFirstElement].possibleSolutions.Add(clone.cloneRowOrColumnToBeCalculated[indexOfFirstElement].possibleSolutions[i]); rowsAndColumnsToBeCalculated[indexOfFirstElement].VariantsCount = 1; RowOrColumnToBeCalculated.Calculate(rowsAndColumnsToBeCalculated); if (RowOrColumnToBeCalculated.IsMainFieldFilled) { solutions.Add(RowOrColumnToBeCalculated.CloneMainField()); } else { if (!RowOrColumnToBeCalculated.IsError) { TryEveryVariantIfNoSolusion(); } } for (int j = 0; j < rowsAndColumnsToBeCalculated.Length; j++) { Task.WaitAll(rowsAndColumnsToBeCalculated[j].tasksForRemovingIrrelevantVariants.ToArray()); } } }
internal void SolveCrossword() { // создание всех элементов rowsAndColumnsToBeCalculated rowsAndColumnsToBeCalculated = new RowOrColumnToBeCalculated[mainFieldHeight + mainFieldWidth]; Task[] tasks = new Task[mainFieldHeight + mainFieldWidth]; for (int i = 0; i < mainFieldHeight; i++) { int j = i; tasks[j] = new Task(() => rowsAndColumnsToBeCalculated[j] = new RowOrColumnToBeCalculated(true, j, conditionRows[j].ToArray())); tasks[j].Start(); } for (int i = 0; i < mainFieldWidth; i++) { int j = i; tasks[j + mainFieldHeight] = new Task(() => rowsAndColumnsToBeCalculated[j + mainFieldHeight] = new RowOrColumnToBeCalculated(false, j, conditionColumns[j].ToArray())); tasks[j + mainFieldHeight].Start(); } Task.WaitAll(tasks); solutions = new List <Cell[, ]>(); // поиск решения RowOrColumnToBeCalculated.Calculate(rowsAndColumnsToBeCalculated); if (RowOrColumnToBeCalculated.IsMainFieldFilled) // если решение есть { rowsAndColumnsToBeCalculated = null; } else // если решения нет, начинаем перебор { MessageToAdd = Textes.severalSolutions[Textes.currentLang] + "\n"; TryEveryVariantIfNoSolusion(); FormMain.SetSolusions(solutions); MessageToAdd = Textes.solusionsFound[Textes.currentLang] + solutions.Count + "\n"; } }
internal RowOrColumnToBeCalculatedComparator(RowOrColumnToBeCalculated rowOrColumnToBeCalculated) { IsRow = rowOrColumnToBeCalculated.IsRow; IsFull = rowOrColumnToBeCalculated.IsFull; IsNeedToRemoveVariants = rowOrColumnToBeCalculated.IsNeedToRemoveVariants; VariantsCount = rowOrColumnToBeCalculated.VariantsCount; IndexOfRowOrColumn = rowOrColumnToBeCalculated.IndexOfRowOrColumn; }
internal CloneOfStaticsOfRowOrColumnToBeCalculated(RowOrColumnToBeCalculated[] rowOrColumnToBeCalculated, int index) { isMainFieldFilled = RowOrColumnToBeCalculated.IsMainFieldFilled; totalFilledCells = RowOrColumnToBeCalculated.TotalFilledCells; mainField = new Cell[RowOrColumnToBeCalculated.RowsCount, RowOrColumnToBeCalculated.ColumnsCount]; mainField = RowOrColumnToBeCalculated.CloneMainField(); possibleSolutions = new List <bool[]>(); cloneRowOrColumnToBeCalculated = new RowOrColumnToBeCalculated[RowOrColumnToBeCalculated.RowsCount + RowOrColumnToBeCalculated.ColumnsCount]; RowOrColumnToBeCalculated.CloneArray(rowOrColumnToBeCalculated, cloneRowOrColumnToBeCalculated); }
private void SetStaticsIfValidated(int sumRows, int sumColumns, int maxConditionRowLength, int maxConditionColumnLength) { if (sumRows != sumColumns) { AddError(Textes.errorConditionSumDifferent[Textes.currentLang]); } else { if (IsValidate) { RowOrColumnToBeCalculated.SetStatics(mainField, mainFieldHeight, mainFieldWidth, sumRows); Cell.UpdateMainFieldSizes(mainFieldWidth, mainFieldHeight, maxConditionRowLength, maxConditionColumnLength); Cell.SetupDGVs(conditionRows, conditionColumns); } } }
internal static void CloneArray(RowOrColumnToBeCalculated[] copyFrom, RowOrColumnToBeCalculated[] copyTo) { // возврат значений в случае перебора всех вариантов for (int i = 0; i < copyTo.Length; i++) { copyTo[i] = new RowOrColumnToBeCalculated(copyFrom[i].IsRow, copyFrom[i].IndexOfRowOrColumn, copyFrom[i].condition, false); copyTo[i].areAllVariantsCalculated = true; copyTo[i].IsFull = copyFrom[i].IsFull; copyTo[i].IsNeedToRemoveVariants = copyFrom[i].IsNeedToRemoveVariants; copyTo[i].VariantsCount = copyFrom[i].VariantsCount; copyTo[i].possibleSolutions = new List <bool[]>(); for (int j = 0; j < copyFrom[i].possibleSolutions.Count; j++) { bool[] massToAdd = new bool[copyFrom[i].possibleSolutions[j].Length]; for (int k = 0; k < copyFrom[i].possibleSolutions[j].Length; k++) { massToAdd[k] = copyFrom[i].possibleSolutions[j][k]; } copyTo[i].possibleSolutions.Add(massToAdd); } } }