private static void Solve(List <Polymino> polyminos, Board board, int depth, int solutionsLimit) { if (stop) { return; } if (depth == polyminos.Count) // wszystkie klocki włożone { if (results.Count > solutionsLimit) { stop = true; } results.Add(new Board(board)); return; } for (int d = depth; d < polyminos.Count; d++) { var curPolymino = polyminos[d]; foreach (var poly in rotations[curPolymino.Type]) { poly.Id = d + 1; for (int j = 0; j < board.Width - poly.MaxY + 1; j++) { for (int i = 0; i < board.Height - poly.MaxX + 1; i++) { if (board.CanPolyminoBePlacedInFields(j, i, poly)) { board.PlacePolymino(j, i, poly); Solve(polyminos, board, depth + 1, solutionsLimit); board.RemovePolymino(j, i, poly); } } } } } }
private static List <Board> Solve(List <Polymino> polyminos, Board board) { var positions = Solver.PotentiallyValidPositions(polyminos, board.Width, board.Height); foreach (var t in polyminos) { var rating = new Dictionary <(Polymino, Point), int>(); foreach (var p in positions[t.Type]) { foreach (var rotated_polymino in t.Rotations()) { if (board.CanPolyminoBePlacedInEmpty(p.Y, p.X, rotated_polymino) && board.CanPolyminoBePlacedInFields(p.Y, p.X, rotated_polymino)) { rating.Add((rotated_polymino, p), board.RatePosition(p.Y, p.X, rotated_polymino)); } } } (Polymino polymino, Point position)? best_position = Solver.FindBestRating(rating); if (best_position == null || best_position.Value.polymino == null) { return(null); //no solution found, no place to put all pentominos in current board } else { board.PlacePolymino(best_position.Value.position.Y, best_position.Value.position.X, best_position.Value.polymino); } } return(new List <Board>() { board }); }
private static Board Solve(List <Polymino> polyminos, Board board) { var positions = Solver.PotentiallyValidPositionsPolymino(polyminos, board.Width, board.Height); int index = 0; foreach (var t in polyminos) { index++; // wstaw klocek w najlepsze miejsce jesli sie da - skopiować od Poliny var rating = new Dictionary <(Polymino, Point), int>(); for (int width = 0; width < board.Width; width++) { for (int height = 0; height < board.Height; height++) { var p = new Point(height, width); foreach (var rotated_polymino in t.Rotations()) { if (board.CanPolyminoBePlacedInEmpty(p.Y, p.X, rotated_polymino) && board.CanPolyminoBePlacedInFields(p.Y, p.X, rotated_polymino)) { rating.Add((rotated_polymino, p), board.RatePosition(p.Y, p.X, rotated_polymino)); } } } } //foreach (var p in positions[t]) //{ // foreach (var rotated_polymino in t.Rotations()) // { // if (board.CanPolyminoBePlacedInEmpty(p.Y, p.X, rotated_polymino) && board.CanPolyminoBePlacedInFields(p.Y, p.X, rotated_polymino)) // rating.Add((rotated_polymino, p), board.RatePosition(p.Y, p.X, rotated_polymino)); // } //} (Polymino polymino, Point position)? best_position = Solver.FindBestRating(rating); if (best_position != null) { board.PlacePolymino(best_position.Value.position.Y, best_position.Value.position.X, best_position.Value.polymino); } else // jesli sie nie da { // wygenerować listę pociętych var cuts = Solver.CutPolymino(t); // znaleść największy który wejdzie z najmniejszą liczbą cięć int max = 0; int maxRate = 0; int cutsMade = 0; Point position = new Point(0, 0); Polymino maxToPlace = null; Polymino maxToSkip = null; var freePoints = board.GetFreePoints(); foreach (var cut in cuts.Keys) { if (max > 0) { break; } foreach (var poly in cuts[cut]) { foreach (var point in freePoints) { foreach (var rotatedPoly in poly.part1.Rotations()) { if (board.CanPolyminoBePlacedInEmpty(point.Y, point.X, rotatedPoly) && board.CanPolyminoBePlacedInFields(point.Y, point.X, rotatedPoly)) { int rate = board.RatePosition(point.Y, point.X, rotatedPoly); if (rotatedPoly.Points.Count > max || (rotatedPoly.Points.Count == max && rate > maxRate)) { max = rotatedPoly.Points.Count; maxRate = rate; maxToPlace = rotatedPoly; maxToSkip = poly.part2; position = point; cutsMade = cut; } } } if (maxToPlace == null) { foreach (var rotatedPoly in poly.part2.Rotations()) { if (board.CanPolyminoBePlacedInEmpty(point.Y, point.X, rotatedPoly) && board.CanPolyminoBePlacedInFields(point.Y, point.X, rotatedPoly)) { int rate = board.RatePosition(point.Y, point.X, rotatedPoly); if (rotatedPoly.Points.Count > max || (rotatedPoly.Points.Count == max && rate > maxRate)) { max = rotatedPoly.Points.Count; maxRate = rate; maxToPlace = rotatedPoly; maxToSkip = poly.part1; position = point; cutsMade = cut; } } } } } } } totalCuts += cutsMade; // wstawić kloca, a resztę dodać na koniec listy board.PlacePolymino(position.Y, position.X, maxToPlace);// //polyminos.RemoveAt(index); polyminos.RemoveRange(0, index); polyminos.Add(maxToSkip); board = Solve(polyminos, board); break; } } return(board); }