예제 #1
0
        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);
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        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
            });
        }
예제 #3
0
        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);
        }