コード例 #1
0
        private PlacedObject _tryPlaceObject(List <Vector>[,] vec, int w, int h, PlaceableObject obj)
        {
            if (vec[w, h] == null)
            {
                return(null);
            }

            var numRectanglesCut = vec[w, h].Count;

            foreach (var maxDimensionInDirection in vec[w, h])
            {
                PlacedObject placedObject = null;

                if (_placeIfFullfilsConstrainsRememberIfBetterScore(
                        obj, false,
                        new Vector(w - obj.Dimensions.X + 1, h - obj.Dimensions.Y + 1),
                        maxDimensionInDirection,
                        numRectanglesCut, out placedObject))
                {
                    return(placedObject);
                }

                if (_placeIfFullfilsConstrainsRememberIfBetterScore(
                        obj, true,
                        new Vector(w - obj.Dimensions.Y + 1, h - obj.Dimensions.X + 1),
                        maxDimensionInDirection,
                        numRectanglesCut, out placedObject))
                {
                    return(placedObject);
                }
            }

            return(null);
        }
コード例 #2
0
        public PlacedObject(PlaceableObject placeableObject, Vector position, bool flipped, bool shouldCalculateDistScore = false)
        {
            PlaceableObject          = placeableObject;
            Position                 = position;
            Flipped                  = flipped;
            ShouldCalculateDistScore = shouldCalculateDistScore;

            Dimensions = !Flipped ? PlaceableObject.Dimensions : PlaceableObject.Dimensions.Reversed();
        }
コード例 #3
0
        public PlacedObject Place(PlaceableObject obj, PlacementScoreRequirement scoreReq)
        {
            if (scoreReq != PlacementScoreRequirement.DontCare)
            {
                throw new NotImplementedException();
            }

            var tilesNotAvailable = Helper.Copy(_templateRoom.RoomLayout);

            foreach (var tileIndex in _templateRoom.AvailableTileIndices())
            {
                if (!_room.TileAvailable(tileIndex.X, tileIndex.Y))
                {
                    tilesNotAvailable[tileIndex.X, tileIndex.Y] = true;
                }
            }

            PlacedObject placedObj = null;

            for (var w = 0; placedObj == null && w < _room.Width; w++)
            {
                for (var h = 0; placedObj == null && h < _room.Height; h++)
                {
                    if (Fits(tilesNotAvailable, w, h, obj.Dimensions.X, obj.Dimensions.Y))
                    {
                        placedObj = new PlacedObject(obj, new Vector(w, h), false);
                    }

                    if (placedObj == null &&
                        obj.Dimensions.X != obj.Dimensions.Y &&
                        Fits(tilesNotAvailable, w, h, obj.Dimensions.Y, obj.Dimensions.X))
                    {
                        placedObj = new PlacedObject(obj, new Vector(w, h), true);
                    }
                }
            }

            return(placedObj);
        }
コード例 #4
0
        public PlacedObject Place(PlaceableObject obj,
                                  PlacementScoreRequirement scoreReq, bool includeDistance,
                                  float acceptProbability = 1f)
        {
            _includeDistance    = includeDistance;
            _scoreReq           = scoreReq;
            _bestPlacementSoFar = null;
            _acceptProbability  = acceptProbability;

            var maxObjectSize = new List <Vector> [_room.Width, _room.Height];

            // dynamic algorithm for determining fit
            // first row
            for (int w = 0, maxWidth = 0; w < _room.Width; w++)
            {
                if (_room.TileAvailable(w, 0))
                {
                    maxWidth++;
                    _addSingle(maxObjectSize, w, 0, maxWidth, 1);
                }
                else
                {
                    maxWidth = 0;
                }

                var placed = _tryPlaceObject(maxObjectSize, w, 0, obj);
                if (placed != null)
                {
                    placed.AddToRooms();
                    return(placed);
                }
            }

            // first column
            for (int h = 0, maxHeight = 0; h < _room.Height; h++)
            {
                if (_room.TileAvailable(0, h))
                {
                    maxHeight++;
                    _addSingle(maxObjectSize, 0, h, 1, maxHeight);
                }
                else
                {
                    maxHeight = 0;
                }

                var placed = _tryPlaceObject(maxObjectSize, 0, h, obj);
                if (placed != null)
                {
                    placed.AddToRooms();
                    return(placed);
                }
            }

            // rest of the 2d array
            for (int h = 1; h < _room.Height; h++)
            {
                for (int w = 1, lastSmallestWidth = _room.TileAvailable(0, h) ? 1 : 0; w < _room.Width; w++)
                {
                    if (_room.TileAvailable(w, h))
                    {
                        lastSmallestWidth++;

                        _addBasedOnNeighborsForAllDirections(maxObjectSize, w, h, lastSmallestWidth);

                        var placed = _tryPlaceObject(maxObjectSize, w, h, obj);
                        if (placed != null)
                        {
                            placed.AddToRooms();
                            return(placed);
                        }
                    }
                    else
                    {
                        lastSmallestWidth = 0;
                    }
                }
            }

            if (_bestPlacementSoFar != null)
            {
                _bestPlacementSoFar.AddToRooms();
                return(_bestPlacementSoFar);
            }

            return(null);
        }
コード例 #5
0
        private bool _placeIfFullfilsConstrainsRememberIfBetterScore(
            PlaceableObject obj, bool flipped,
            Vector position, Vector maxDimensionsInDirection,
            int numRectanglesCut,
            out PlacedObject o)
        {
            var placedObject = new PlacedObject(obj, position, flipped, _includeDistance);

            placedObject.Rooms = _room;

            if (!placedObject.Fits(maxDimensionsInDirection))
            {
                o = null;
                return(false);
            }

            if (_scoreReq == PlacementScoreRequirement.DontCare)
            {
                o = placedObject;
                return(true);
            }

            placedObject.CalculateWallScore();
            placedObject.CalculateDistanceScore();

            switch (_scoreReq)
            {
            case PlacementScoreRequirement.LeastDamageThenBestWall:
                if (_bestPlacementSoFar == null ||
                    placedObject.WallScore + 100 * numRectanglesCut < _bestPlacementSoFar.WallScore + 100 * _numCutsOfBestSoFar)
                {
                    _bestPlacementSoFar = placedObject;
                    _numCutsOfBestSoFar = numRectanglesCut;
                }
                break;

            case PlacementScoreRequirement.OnlyBestWall:
                if (placedObject.WallScore == 0)
                {
                    if (_rand.NextDouble() <= _acceptProbability)
                    {
                        o = placedObject;
                        return(true);
                    }
                    else
                    {
                        _bestPlacementSoFar = placedObject;
                    }
                }
                break;

            case PlacementScoreRequirement.PreferBest:
                if (placedObject.PlacementScore == 0)
                {
                    if (_rand.NextDouble() <= _acceptProbability)
                    {
                        o = placedObject;
                        return(true);
                    }
                    else
                    {
                        _bestPlacementSoFar = placedObject;
                    }
                }
                else if (_bestPlacementSoFar == null || placedObject.PlacementScore < _bestPlacementSoFar.PlacementScore)
                {
                    _bestPlacementSoFar = placedObject;
                }
                break;
            }

            o = null;
            return(false);
        }