public void PortRule_Is_Not_Satisfied_When_Distance_To_Water_Is_Greater_Than_10_Pixels()
        {
            var road1         = _settlement.Roads.First();
            var roadGenerator = new RoadPointsGenerator();
            var road2         = new Road(roadGenerator.GenerateStraight(new RoadGenerationTwoPoints()
            {
                Start  = new Point(50, 51),
                End    = new Point(50, 10),
                Fields = _settlement.Fields
            }));

            _settlement.AddRoad(road2);

            var port = new Port()
            {
                Position = new Point(51, 25)
            };

            Assert.AreEqual(0, port.CalculateFitness(new BuildingRule()
            {
                BuildingRoad     = road1,
                Fields           = _settlement.Fields,
                Roads            = _settlement.Roads,
                SettlementCenter = _settlement.SettlementCenter
            }));
        }
        public void PortRule_Is_Not_Satisfied_When_There_Is_Other_Port()
        {
            IRoad road1         = _settlement.Roads.First();
            var   roadGenerator = new RoadPointsGenerator();
            var   road2         = new Road(roadGenerator.GenerateStraight(new RoadGenerationTwoPoints()
            {
                Start  = new Point(50, 51),
                End    = new Point(50, 10),
                Fields = _settlement.Fields
            }));

            _settlement.AddRoad(road2);

            var port = new Port()
            {
                Position = new Point(51, 10)
            };

            var exitingPort = new Port()
            {
                Position = new Point(49, 10)
            };

            exitingPort.Road = road2;
            _settlement.AddBuildingToRoad(road2, exitingPort);

            Assert.AreEqual(0, port.CalculateFitness(new BuildingRule()
            {
                BuildingRoad     = road1,
                Fields           = _settlement.Fields,
                Roads            = _settlement.Roads,
                SettlementCenter = _settlement.SettlementCenter
            }));
        }
        public void MarketRule_IsSatisfied_When_Exists_Other_Market_But_It_Further_Than_50_Pixels_Away()
        {
            IRoad road1   = _settlement.Roads.First();
            var   market1 = new Market()
            {
                Position = new Point(50, 51)
            };

            market1.Road = road1;
            _settlement.AddBuildingToRoad(road1, market1);

            //add vertical road to the end of the road to increase distance between markets
            var roadGenerator = new RoadPointsGenerator();
            var road2         = new Road(roadGenerator.GenerateStraight(new RoadGenerationTwoPoints()
            {
                Start  = new Point(98, 51),
                End    = new Point(98, 21),
                Fields = _settlement.Fields
            }));

            _settlement.AddRoad(road2);
            var market2 = new Market()
            {
                Position = new Point(99, 21)
            };

            market2.Road = road1;
            _settlement.AddBuildingToRoad(road1, market2);


            while (_settlement.Roads.SelectMany(g => g.Buildings).Count() < 120)
            {
                var buildingPositions = road1.GetPossibleBuildingPositions(new PossibleBuildingPositions(_settlement.Roads, _settlement.Fields));
                if (!buildingPositions.Any())
                {
                    continue;
                }

                var building = new Residence {
                    Position = buildingPositions[RandomProvider.Next(buildingPositions.Count)]
                };
                building.Road = road1;
                _settlement.AddBuildingToRoad(road1, building);
            }

            Assert.AreEqual(5, market1.CalculateFitness(new BuildingRule()
            {
                BuildingRoad     = road1,
                Fields           = _settlement.Fields,
                Roads            = _settlement.Roads,
                SettlementCenter = _settlement.SettlementCenter
            }));
        }
        public void SetUp()
        {
            var fields     = new Field[100, 100];
            int waterLevel = 10;

            for (int i = 0; i < fields.GetLength(0); i++)
            {
                for (int j = 0; j < fields.GetLength(1); j++)
                {
                    var position = new Point(i, j);
                    if (j < waterLevel)
                    {
                        fields[i, j] = new Field()
                        {
                            InSettlement = false,
                            Position     = position,
                            Terrain      = new Water()
                        };
                    }
                    else
                    {
                        fields[i, j] = new Field()
                        {
                            InSettlement       = true,
                            Position           = position,
                            Terrain            = new Lowland(),
                            DistanceToWater    = position.Y - waterLevel,
                            DistanceToMainRoad = position.Y - waterLevel - 1
                        };
                    }
                }
            }

            var roadGenerator = new RoadPointsGenerator();
            var mainRoad      = roadGenerator.GenerateStraight(new RoadGenerationTwoPoints()
            {
                Start  = new Point(0, waterLevel),
                End    = new Point(fields.GetLength(0) - 1, waterLevel),
                Fields = fields
            });//in this case main road should be straight horizontal line

            _settlement = new Settlement(fields, mainRoad, false);

            var road1 = new Road(roadGenerator.GenerateStraight(new RoadGenerationTwoPoints()
            {
                Start  = new Point(0, 50),
                End    = new Point(99, 50),
                Fields = _settlement.Fields
            }));

            _settlement.AddRoad(road1);
        }
        private IRoad CreateNewRoad(IRoad road)
        {
            var roadGenerator = new RoadPointsGenerator();
            var roadPoints    = roadGenerator.GenerateAttached(new RoadGenerationAttached()
            {
                Road                    = road,
                Roads                   = this.Roads,
                Fields                  = this.Fields,
                SettlementCenter        = this.SettlementCenter,
                MinDistanceBetweenRoads = MinDistanceBetweenRoads,
                MinRoadLength           = MinRoadLength,
                MaxRoadLength           = MaxRoadLength
            }).ToList();

            return(new Road(roadPoints));
        }
        public void SetUp()
        {
            _fields = new Field[50, 50];
            int waterLevel = 10;

            for (int i = 0; i < _fields.GetLength(0); i++)
            {
                for (int j = 0; j < _fields.GetLength(1); j++)
                {
                    var position = new Point(i, j);
                    if (j < waterLevel)
                    {
                        _fields[i, j] = new Field()
                        {
                            InSettlement = false,
                            Position     = position,
                            Terrain      = new Water()
                        };
                    }
                    else
                    {
                        _fields[i, j] = new Field()
                        {
                            InSettlement       = true,
                            Position           = position,
                            Terrain            = new Lowland(),
                            DistanceToWater    = position.Y - waterLevel,
                            DistanceToMainRoad = position.Y - waterLevel - 1
                        };
                    }
                }
            }

            var roadGenerator = new RoadPointsGenerator();

            _mainRoad = roadGenerator.GenerateStraight(new Models.RoadGenerationTwoPoints()
            {
                Start  = new Point(0, waterLevel),
                End    = new Point(_fields.GetLength(0) - 1, waterLevel),
                Fields = _fields
            });
        }
        private void InitializeGenes()
        {
            var minRadius        = Fields.GetLength(0) / 100 < 10 ? 10 : Fields.GetLength(0) / 100;
            var maxRadius        = Fields.GetLength(0) / 10 < 10 ? 10 : Fields.GetLength(0) / 10;
            var settlementFields = Fields.ToList()
                                   .Where(f => f.InSettlement &&
                                          f.Position.X > maxRadius &&
                                          f.Position.X <Fields.GetLength(0) - maxRadius &&
                                                        f.Position.Y> maxRadius &&
                                          f.Position.Y < Fields.GetLength(1) - maxRadius)
                                   .ToList();

            Point center = new Point(-1, -1);
            int   radius = -1;

            for (int r = maxRadius; r >= minRadius; r--)
            {
                Field centerField = settlementFields
                                    .FirstOrDefault(f =>
                                                    f.Position.GetCircularPoints(r, Math.PI / 17.0f)
                                                    .All(p => Fields[p.X, p.Y].InSettlement) &&
                                                    f.Position.GetCircularPoints(r / 2.0, Math.PI / 17.0f)
                                                    .All(p => Fields[p.X, p.Y].InSettlement) &&
                                                    f.Position.GetCircularPoints(r / 4.0, Math.PI / 17.0f)
                                                    .All(p => Fields[p.X, p.Y].InSettlement) &&
                                                    f.Position.GetCircularPoints(r / 6.0, Math.PI / 17.0f)
                                                    .All(p => Fields[p.X, p.Y].InSettlement) &&
                                                    f.Position.GetCircularPoints(r / 8.0, Math.PI / 17.0f)
                                                    .All(p => Fields[p.X, p.Y].InSettlement) &&
                                                    f.Position.GetCircularPoints(r / 10.0, Math.PI / 17.0f)
                                                    .All(p => Fields[p.X, p.Y].InSettlement));

                if (centerField != null)
                {
                    radius = r;
                    center = centerField.Position;
                    break;
                }

                if (r == minRadius)
                {
                    throw new Exception("Cannot find center for initial point");
                }
            }

            SettlementCenter = center;

            var roadGenerator = new RoadPointsGenerator();

            var initialRoads    = new List <IRoad>(InitialRoadsCount);
            var firstRoadPoints = roadGenerator.GenerateStraight(new RoadGenerationTwoPoints()
            {
                Start  = new Point(center.X - radius / 2, center.Y),
                End    = new Point(center.X + radius / 2, center.Y),
                Fields = Fields
            });
            var firstRoad = new Road(firstRoadPoints);

            while (firstRoad.Buildings.Count < 0.25 * firstRoad.Length)
            {
                var possiblePlaces =
                    firstRoad.GetPossibleBuildingPositions(new PossibleBuildingPositions(this.Roads, this.Fields));
                var building = new Residence
                {
                    Position = possiblePlaces[RandomProvider.Next(possiblePlaces.Count)],
                    Road     = firstRoad,
                    Fitness  = 0.1,
                    Material = Material.Wood
                };
                firstRoad.AddBuilding(building);
            }
            initialRoads.Add(firstRoad);
            AddRoad(initialRoads.First());

            while (initialRoads.Count != InitialRoadsCount)
            {
                var roadToAttach = initialRoads[RandomProvider.Next(initialRoads.Count)];
                var roadPoints   = roadGenerator.GenerateAttached(new RoadGenerationAttached()
                {
                    Road                    = roadToAttach,
                    Roads                   = initialRoads,
                    Fields                  = Fields,
                    MaxRoadLength           = MaxRoadLength,
                    MinRoadLength           = MinRoadLength,
                    MinDistanceBetweenRoads = MinDistanceBetweenRoads
                }).ToList();

                if (!roadPoints.Any())
                {
                    continue;
                }

                var newRoad = new Road(roadPoints);
                initialRoads.Add(newRoad);

                while (newRoad.Buildings.Count < 0.25 * newRoad.Length)
                {
                    var possiblePlaces =
                        newRoad.GetPossibleBuildingPositions(new PossibleBuildingPositions(this.Roads, Fields));

                    var building = new Residence
                    {
                        Position = possiblePlaces[RandomProvider.Next(possiblePlaces.Count)],
                        Road     = newRoad,
                        Fitness  = 0.1,
                        Material = Material.Wood
                    };
                    newRoad.AddBuilding(building);
                }

                if (CanAddRoad(newRoad))
                {
                    AddRoad(newRoad);
                }
            }
        }