示例#1
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
 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)));
 }