void InitializeTectonicPlates() { // TODO ensure plate can't be chosen twice for (int i = 0; i < NumberOfPlates; i++) { int randomX = random.Next(Width); int randomY = random.Next(Height); mapData.Tiles[randomX, randomY].PlateId = i; mapData.Tiles[randomX, randomY].IsPlateCenter = true; } List <Tile> plateEdgeTiles = mapData.Tiles.AsList().Where(t => t.PlateId.HasValue).ToList(); List <Tile> nextPlateEdgeTiles = new List <Tile>(); while (plateEdgeTiles.Count > 0) { foreach (Tile plateEdgeTile in plateEdgeTiles) { if (plateEdgeTile.PlateId.HasValue) { //int floodAmount = random.Next(1, random.Next(2, 5)); //int floodAmount = 1; int floodAmount = random.Next(2) + 1; List <Tile> nextLocalEdgeTiles = new List <Tile>(); List <Tile> localEdgeTiles = new List <Tile> { plateEdgeTile }; for (int i = 0; i < floodAmount; i++) { foreach (Tile localEdgeTile in localEdgeTiles) { List <Tile> neighbors = TileHelpers.GetNeighbors(mapData.Tiles, Width, Height, localEdgeTile); //List<Tile> neighbors = TileHelpers.GetSurrounding(mapData.Tiles, Width, Height, localEdgeTile); foreach (Tile neighbor in neighbors.Where(x => !x.PlateId.HasValue)) { if (!neighbor.PlateId.HasValue) { neighbor.PlateId = localEdgeTile.PlateId.Value; nextLocalEdgeTiles.Add(neighbor); } } } localEdgeTiles.Clear(); localEdgeTiles.AddRange(nextLocalEdgeTiles); nextLocalEdgeTiles.Clear(); } nextPlateEdgeTiles.AddRange(localEdgeTiles); } } plateEdgeTiles.Clear(); plateEdgeTiles.AddRange(nextPlateEdgeTiles); nextPlateEdgeTiles.Clear(); } // DEBUG TEST, should be 0 Console.WriteLine(mapData.Tiles.AsList().Count(x => !x.PlateId.HasValue)); // Assign border tiles // TODO smartly combine this with above so we don't have to iterate full list again? foreach (Tile tile in mapData.Tiles.AsList()) { List <Tile> neighbors = TileHelpers.GetNeighbors(mapData.Tiles, Width, Height, tile); if (neighbors.Any(n => n.PlateId != tile.PlateId)) { tile.IsPlateBorder = true; } } }
void EvaluateTectonics() { // TEST EXAMPLES // PUSHING //mapData.Tiles = new Tile[1, 2] //{ // { // new Tile { X = 0, Y = 0, PlateId = 0, GlobalDriftDirection = Vector2.Left, GlobalDriftStrength = 0.25f, PlateRotationDirection = Vector2.Down, PlateRotationStrength = 1.0f, IsPlateBorder = true}, // new Tile { X = 0, Y = 1, PlateId = 1, GlobalDriftDirection = Vector2.Left, GlobalDriftStrength = 0.25f, PlateRotationDirection = Vector2.Up, PlateRotationStrength = 1.0f, IsPlateBorder = true} // }, //}; // SEPARATING //mapData.Tiles = new Tile[1, 2] //{ // { // new Tile { X = 0, Y = 0, PlateId = 0, GlobalDriftDirection = Vector2.Left, GlobalDriftStrength = 0.25f, PlateRotationDirection = Vector2.Up, PlateRotationStrength = 1.0f, IsPlateBorder = true}, // new Tile { X = 0, Y = 1, PlateId = 1, GlobalDriftDirection = Vector2.Left, GlobalDriftStrength = 0.25f, PlateRotationDirection = Vector2.Down, PlateRotationStrength = 1.0f, IsPlateBorder = true} // }, //}; // SHEARING //mapData.Tiles = new Tile[1, 2] //{ // { // new Tile { X = 0, Y = 0, PlateId = 0, GlobalDriftDirection = Vector2.Left, GlobalDriftStrength = 0.25f, PlateRotationDirection = Vector2.Left, PlateRotationStrength = 1.0f, IsPlateBorder = true}, // new Tile { X = 0, Y = 1, PlateId = 1, GlobalDriftDirection = Vector2.Left, GlobalDriftStrength = 0.25f, PlateRotationDirection = Vector2.Right, PlateRotationStrength = 1.0f, IsPlateBorder = true} // }, //}; // Calculate Pressure List <Tile> boundaryTiles = mapData.Tiles.AsList().Where(x => x.IsPlateBorder).ToList(); foreach (Tile boundaryTile in boundaryTiles) { var neighbors = TileHelpers.GetNeighbors(mapData.Tiles, Width, Height, boundaryTile).Where(t => t.PlateId != boundaryTile.PlateId); foreach (Tile neighbor in neighbors) { // if boundary relative movement plus neighbor relative movement is less than boundary's original, then they're acting on eachother.. // otherwise they're moving the same direction.. can't compare magnitude since that doesn't take direction into account Vector2 added = boundaryTile.RelativeMovement.UnitVector + neighbor.RelativeMovement.UnitVector; if (added.X < boundaryTile.RelativeMovement.UnitVector.X || added.Y < boundaryTile.RelativeMovement.UnitVector.Y) { Vector2 unitToNeighbor = (new Point(boundaryTile.X, boundaryTile.Y) - new Point(neighbor.X, neighbor.Y)).UnitVector; // if vector to neighbor aligns with pressure vector, they're pushing against eachother, otherwise separating float directionalMagnitude = (unitToNeighbor + boundaryTile.RelativeMovement).Magnitude; if (directionalMagnitude > 1) { boundaryTile.Pressure += (boundaryTile.RelativeMovement + neighbor.RelativeMovement).Magnitude; } else { boundaryTile.Pressure -= (boundaryTile.RelativeMovement + neighbor.RelativeMovement).Magnitude; } } } // Capping effect if (boundaryTile.Pressure > 10) { boundaryTile.Pressure = 10; } if (boundaryTile.Pressure < -10) { boundaryTile.Pressure = -10; } // TEMPORARY FOR OUTPUT.. normalize pressure to height values boundaryTile.HeightValue = ((boundaryTile.Pressure + 10) / 20); boundaryTile.HeightValue = (((boundaryTile.Pressure + 10) / 10) - 0.5f); } //List<float> pressures = boundaryTiles.Select(x => x.Pressure).ToList(); //List<float> sortedPressures = pressures.OrderBy(x => x).ToList(); //List<float> bottomHalf = sortedPressures.GetRange(0, sortedPressures.Count / 2); //List<float> topHalf = sortedPressures.GetRange(sortedPressures.Count / 2, sortedPressures.Count - 1 - (sortedPressures.Count / 2)); //List<float> First = bottomHalf.GetRange(0, bottomHalf.Count / 2); //List<float> Second = bottomHalf.GetRange(bottomHalf.Count / 2, bottomHalf.Count - 1 - (bottomHalf.Count / 2)); //List<float> Third = topHalf.GetRange(0, topHalf.Count / 2); //List<float> Fourth = topHalf.GetRange(topHalf.Count / 2, topHalf.Count - 1 - (topHalf.Count / 2)); //float maxPressure = pressures.Max(); //float minPressure = pressures.Min(); //float averagePressure = pressures.Average(); }