//Фильтрация решений, которые больше не подходят для данной доски //Принимает ситуацию на доске на данный момент public Problem Prune(KenKenBoard board) { var result = new Problem(); //Для всех регионов for (int i = 1; i < AllRegions.Count; i++) { //Объявляем данный регион var region = AllRegions[i]; //Для данного региона отбрасываем недоходящие решения var resultRegion = region.Prune(board); //Если для данного региона не найдено решений //То такой вариант решения не подошел if (resultRegion == null) { return(null); } //Иначе добавляем решение такого региона в список result.AllRegions.Add(resultRegion); } return(result); }
//Эта функция решает задачу, когда найдены доступные решения, отсортированы, отфильтрованы public KenKenBoard Solve(KenKenBoard board) { //Есть ли в списке регионы if (!AllRegions.Any()) { return(board); } //Берем один регион var region = AllRegions[0]; //Берем его клетки var cells = region.Cells; //Проходим через все возможные решения для данного региона foreach (var solution in region.Solutions) { //Проходим по каждому отдельному предлагаемому значению for (int i = 0; i < solution.Count; i++) { //Пробуем расположить данное значение на поле board.TryPlace(cells[i], solution[i]); } //Отфильтруем доску с данным решением var newProb = Prune(board); //Если полученное решенное задание не пустое if (newProb != null) { newProb.Sort(); //Рекурсивно продолжаем искать решения для следующих областей var ret = newProb.Solve(board); if (ret != null) { return(ret); } } //Если вышло так, что алгоритм не смог найти подходящее решение //То все, что осталось от него на доске, очищаем foreach (Point p in cells) { board.UnsetPlace(p); } } return(null); }
//Фильтрация и уменьшение количества решений в соответствии с данным полем public Region Prune(KenKenBoard board) { //Берем новый регион var result = new Region(Operator, Value); //Создаем для данного региона новый список решений result.Solutions = new List <List <int> >(); //Создаем новые ячейки в данном регионе result.Cells = Cells; //Просмотр каждого решения foreach (var solution in Solutions) { bool success = true; //Проходимся по клеткам данного региона for (int i = 0; i < Cells.Count; i++) { //Если хоть одну клетку решения нельзя расположить на доске if (!board.CanPlace(Cells[i], solution[i])) { //То выходим из цикла, это решение не подошло //Его не добавим к списку отфильтрованных success = false; break; } } //Если получилось расположить, то добавялем в список if (success) { result.Solutions.Add(solution); } } //Если ни одно решение не подошло, то возвращаем null, иначе готовый решенный регион return(Solutions.Any() ? result : null); }
//Функция генерации решений, подготавливает почву для решения задачи public KenKenBoard Solve() { //Проверка всех клеток на причастие к региону for (int x = 0; x < Constants.MapSize; x++) { for (int y = 0; y < Constants.MapSize; y++) { if (Regions[x, y] != null) { //Если все ок, то побавляем данную клетку к списку клеток региона Regions[x, y].Cells.Add(new Point(x, y)); } } } //Генерируем решения для всех регионов for (int x = 0; x < Constants.MapSize; x++) { for (int y = 0; y < Constants.MapSize; y++) { Regions[x, y].GenerateSolutions(); } } //Когда варианты ответов сгенерированы //Создаем словарь регионов var regions = new Dictionary <Region, int>(); //Временная переменная Region tempSub; //Проходимся по всему игровому полю for (int x = 0; x < Constants.MapSize; x++) { for (int y = 0; y < Constants.MapSize; y++) { //Передаем во временную переменную регион на данных координатах tempSub = Regions[x, y]; //Если такого региона нет в словаре if (!regions.ContainsKey(tempSub)) { //То доабвляем его regions.Add(tempSub, tempSub.Cells.Count); } } } //!!!!!!!!!!!!! //Проходимся по списку регионов foreach (var val in regions.Keys) { //Отбрасываем невозможные решения //Для этого проходимся по всем возможным foreach (var solution in new List <List <int> >(val.Solutions)) { //Временная переменная для хранения игрового поля на данный момент var tempBoard = new KenKenBoard(); //Смотрим все доступные решения for (int i = 0; i < solution.Count; i++) { //Тут что-то идет не так // // // // Console.Write("\n" + solution[i]); //Если при попытке расопложить такое значение в данном положении не вышло if (!tempBoard.TryPlace(val.Cells[i], solution[i])) { //То такое решение удаляем и выходим. Оно точно не будет использоваться val.Solutions.Remove(solution); break; } // // // } } //После фильтрации этого региона, добавляем его к списку регионов AllRegions.Add(val); } Sort(); //Пробуем решить задачу с полученными ресурсами, передаем пустое поле return(Solve(new KenKenBoard())); }