public static List <(int sumCutLength, List <Polymino> pieces)> GetAllCuts(Polymino polymino) { var result = new List <(int sumCutLength, List <Polymino> pieces)>(); Dictionary <int, List <(Polymino part1, Polymino part2)> > singleCutPolymino = CutPolymino(polymino); foreach (var cutLength in singleCutPolymino.Keys) { foreach (var parts in singleCutPolymino[cutLength]) { PerformRecurreceCuttingAndMergingPolyminosParts(result, cutLength, parts); } } result = GetDistinctCutsCombinations(result); return(result); }
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); }
public static Dictionary <int, List <(Polymino part1, Polymino part2)> > CutPolymino(Polymino polymino) { var result = new Dictionary <int, List <(Polymino part1, Polymino part2)> >(); result[1] = new List <(Polymino part1, Polymino part2)>(); result[2] = new List <(Polymino part1, Polymino part2)>(); (int x, int y)polyminoRect = (polymino.Points.Max(point => point.X) + 1, polymino.Points.Max(point => point.Y) + 1); for (int i = 1; i < polyminoRect.x; i++) { if (polymino.Type == Types.U && polymino.Points.Count == 5) // przypadek który zwróciłby błędnie { result[1].Add((new Polymino(Types.U, polymino.Id, new List <Point>() { new Point(0, 0) }), new Polymino(Types.U, polymino.Id, new List <Point>() { new Point(0, 0), new Point(1, 0), new Point(2, 0), new Point(2, 1) }))); result[1].Add((new Polymino(Types.U, polymino.Id, new List <Point>() { new Point(0, 0) }), new Polymino(Types.U, polymino.Id, new List <Point>() { new Point(0, 0), new Point(1, 0), new Point(2, 0), new Point(0, 1) }))); continue; } //CutPolymino(polymino, result, i); var points1 = polymino.Points.Where(p => p.X < i).ToList(); var points2 = polymino.Points.Where(p => p.X >= i).ToList(); int cutLength = points1.Count(p => p.X == i - 1 && points2.Any(p2 => p2.X == i && p2.Y == p.Y)); result[cutLength].Add(points1.Count > points2.Count ? (GetPolyminoFromPoints(points1, polymino.Type, polymino.Id), GetPolyminoFromPoints(points2, polymino.Type, polymino.Id)) : (GetPolyminoFromPoints(points2, polymino.Type, polymino.Id), GetPolyminoFromPoints(points1, polymino.Type, polymino.Id))); } for (int i = 1; i < polyminoRect.y; i++) { //CutPolymino(polymino, result, i); var points1 = polymino.Points.Where(p => p.Y < i).ToList(); var points2 = polymino.Points.Where(p => p.Y >= i).ToList(); int cutLength = points1.Count(p => p.Y == i - 1 && points2.Any(p2 => p2.Y == i && p2.X == p.X)); result[cutLength].Add(points1.Count > points2.Count ? (GetPolyminoFromPoints(points1, polymino.Type, polymino.Id), GetPolyminoFromPoints(points2, polymino.Type, polymino.Id)) : (GetPolyminoFromPoints(points2, polymino.Type, polymino.Id), GetPolyminoFromPoints(points1, polymino.Type, polymino.Id))); } return(result); }
private void NewTetrimino() { // create new Random Tetrimino and move it in the top center of the playground Tetrimino = (Polymino)Activator.CreateInstance(Tetriminos[PRandom.Next(0, Tetriminos.Length)]); Tetrimino.MoveTo(new Point(0, (grid.GetLength(1) / 2) - (Tetrimino.Structure.GetLength(1) / 2))); }