private void setRiverTile(River river) { setRiverPath(river); myHeightType = HeightType.River; myHeightValue = 0; myIsLand = false; }
void generateRivers() { int attempts = 0; int rivercount = WorldParameters.theRiverCount; myRivers = new List <River>(); Random rand = new Random(); // Generate some rivers while (rivercount > 0 && attempts < WorldParameters.theMaxRiverAttempts) { // Get a random tile int x = rand.Next(0, WorldParameters.theRegionSize); int y = rand.Next(0, WorldParameters.theRegionSize); Tile tile = myTiles[x, y]; // validate the tile if (!tile.myIsLand) { continue; } if (tile.Rivers.Count > 0) { continue; } if (tile.myHeightValue > WorldParameters.theMinRiverHeight) { // Tile is good to start river from River river = new River(rivercount); // Figure out the direction this river will try to flow river.CurrentDirection = tile.getLowestNeighbor(this); // Recursively find a path to water findPathToWater(tile, river.CurrentDirection, ref river); // Validate the generated river if (river.TurnCount < WorldParameters.theMinRiverTurns || river.myTiles.Count < WorldParameters.theMinRiverLength || river.Intersections > WorldParameters.theMaxRiverIntersections) { //Validation failed - remove this river for (int i = 0; i < river.myTiles.Count; i++) { Tile t = river.myTiles[i]; t.Rivers.Remove(river); } } else if (river.myTiles.Count >= WorldParameters.theMinRiverLength) { //Validation passed - Add river to list myRivers.Add(river); tile.Rivers.Add(river); rivercount--; } } attempts++; } }
public void setRiverPath(River river) { if (!myIsLand) { return; } if (!Rivers.Contains(river)) { Rivers.Add(river); } }
public int getRiverNeighborCount(River river) { int count = 0; if (myLeft != null && myLeft.Rivers.Count > 0 && myLeft.Rivers.Contains(river)) { count++; } if (myRight != null && myRight.Rivers.Count > 0 && myRight.Rivers.Contains(river)) { count++; } if (myTop != null && myTop.Rivers.Count > 0 && myTop.Rivers.Contains(river)) { count++; } if (myBottom != null && myBottom.Rivers.Count > 0 && myBottom.Rivers.Contains(river)) { count++; } return(count); }
void digRiverGroups() { for (int i = 0; i < myRiverGroups.Count; i++) { RiverGroup group = myRiverGroups[i]; River longest = null; //Find longest river in this group for (int j = 0; j < group.Rivers.Count; j++) { River river = group.Rivers[j]; if (longest == null) { longest = river; } else if (longest.myTiles.Count < river.myTiles.Count) { longest = river; } } if (longest != null) { //Dig out longest path first digRiver(longest); for (int j = 0; j < group.Rivers.Count; j++) { River river = group.Rivers[j]; if (river != longest) { digRiver(river, longest); } } } } }
void digRiver(River river) { int counter = 0; Random rand = new Random(); // How wide are we digging this river? int size = rand.Next(1, 5); river.myLength = river.myTiles.Count; // randomize size change int two = river.myLength / 2; int three = two / 2; int four = three / 2; int five = four / 2; int twomin = two / 3; int threemin = three / 3; int fourmin = four / 3; int fivemin = five / 3; // randomize length of each size int count1 = rand.Next(fivemin, five); if (size < 4) { count1 = 0; } int count2 = count1 + rand.Next(fourmin, four); if (size < 3) { count2 = 0; count1 = 0; } int count3 = count2 + rand.Next(threemin, three); if (size < 2) { count3 = 0; count2 = 0; count1 = 0; } int count4 = count3 + rand.Next(twomin, two); // Make sure we are not digging past the river path if (count4 > river.myLength) { int extra = count4 - river.myLength; while (extra > 0) { if (count1 > 0) { count1--; count2--; count3--; count4--; extra--; } else if (count2 > 0) { count2--; count3--; count4--; extra--; } else if (count3 > 0) { count3--; count4--; extra--; } else if (count4 > 0) { count4--; extra--; } } } // Dig it out for (int i = river.myTiles.Count - 1; i >= 0; i--) { Tile t = river.myTiles[i]; if (counter < count1) { t.digRiver(river, 4); } else if (counter < count2) { t.digRiver(river, 3); } else if (counter < count3) { t.digRiver(river, 2); } else if (counter < count4) { t.digRiver(river, 1); } else { t.digRiver(river, 0); } counter++; } }
void digRiver(River river, River parent) { int intersectionID = 0; int intersectionSize = 0; Random rand = new Random(); // determine point of intersection for (int i = 0; i < river.myTiles.Count; i++) { Tile t1 = river.myTiles[i]; for (int j = 0; j < parent.myTiles.Count; j++) { Tile t2 = parent.myTiles[j]; if (t1 == t2) { intersectionID = i; intersectionSize = t2.RiverSize; } } } int counter = 0; int intersectionCount = river.myTiles.Count - intersectionID; int size = rand.Next(intersectionSize, 5); river.myLength = river.myTiles.Count; // randomize size change int two = river.myLength / 2; int three = two / 2; int four = three / 2; int five = four / 2; int twomin = two / 3; int threemin = three / 3; int fourmin = four / 3; int fivemin = five / 3; // randomize length of each size int count1 = rand.Next(fivemin, five); if (size < 4) { count1 = 0; } int count2 = count1 + rand.Next(fourmin, four); if (size < 3) { count2 = 0; count1 = 0; } int count3 = count2 + rand.Next(threemin, three); if (size < 2) { count3 = 0; count2 = 0; count1 = 0; } int count4 = count3 + rand.Next(twomin, two); // Make sure we are not digging past the river path if (count4 > river.myLength) { int extra = count4 - river.myLength; while (extra > 0) { if (count1 > 0) { count1--; count2--; count3--; count4--; extra--; } else if (count2 > 0) { count2--; count3--; count4--; extra--; } else if (count3 > 0) { count3--; count4--; extra--; } else if (count4 > 0) { count4--; extra--; } } } // adjust size of river at intersection point if (intersectionSize == 1) { count4 = intersectionCount; count1 = 0; count2 = 0; count3 = 0; } else if (intersectionSize == 2) { count3 = intersectionCount; count1 = 0; count2 = 0; } else if (intersectionSize == 3) { count2 = intersectionCount; count1 = 0; } else if (intersectionSize == 4) { count1 = intersectionCount; } else { count1 = 0; count2 = 0; count3 = 0; count4 = 0; } // dig out the river for (int i = river.myTiles.Count - 1; i >= 0; i--) { Tile t = river.myTiles[i]; if (counter < count1) { t.digRiver(river, 4); } else if (counter < count2) { t.digRiver(river, 3); } else if (counter < count3) { t.digRiver(river, 2); } else if (counter < count4) { t.digRiver(river, 1); } else { t.digRiver(river, 0); } counter++; } }
void buildRiverGroups() { //loop each tile, checking if it belongs to multiple rivers for (var x = 0; x < WorldParameters.theRegionSize; x++) { for (var y = 0; y < WorldParameters.theRegionSize; y++) { Tile t = myTiles[x, y]; if (t.Rivers.Count > 1) { // multiple rivers == intersection RiverGroup group = null; // Does a rivergroup already exist for this group? for (int n = 0; n < t.Rivers.Count; n++) { River tileriver = t.Rivers[n]; for (int i = 0; i < myRiverGroups.Count; i++) { for (int j = 0; j < myRiverGroups[i].Rivers.Count; j++) { River river = myRiverGroups[i].Rivers[j]; if (river.myId == tileriver.myId) { group = myRiverGroups[i]; } if (group != null) { break; } } if (group != null) { break; } } if (group != null) { break; } } // existing group found -- add to it if (group != null) { for (int n = 0; n < t.Rivers.Count; n++) { if (!group.Rivers.Contains(t.Rivers[n])) { group.Rivers.Add(t.Rivers[n]); } } } else //No existing group found - create a new one { group = new RiverGroup(); for (int n = 0; n < t.Rivers.Count; n++) { group.Rivers.Add(t.Rivers[n]); } myRiverGroups.Add(group); } } } } }
void findPathToWater(Tile tile, Direction direction, ref River river) { if (tile.Rivers.Contains(river)) { return; } // check if there is already a river on this tile if (tile.Rivers.Count > 0) { river.Intersections++; } river.AddTile(tile); // get neighbors Tile left = getLeft(tile); Tile right = getRight(tile); Tile top = getTop(tile); Tile bottom = getBottom(tile); float leftValue = int.MaxValue; float rightValue = int.MaxValue; float topValue = int.MaxValue; float bottomValue = int.MaxValue; // query height values of neighbors if (left != null && left.getRiverNeighborCount(river) < 2 && !river.myTiles.Contains(left)) { leftValue = left.myHeightValue; } if (right != null && right.getRiverNeighborCount(river) < 2 && !river.myTiles.Contains(right)) { rightValue = right.myHeightValue; } if (top != null && top.getRiverNeighborCount(river) < 2 && !river.myTiles.Contains(top)) { topValue = top.myHeightValue; } if (bottom != null && bottom.getRiverNeighborCount(river) < 2 && !river.myTiles.Contains(bottom)) { bottomValue = bottom.myHeightValue; } // if neighbor is existing river that is not this one, flow into it if (bottom != null && bottom.Rivers.Count == 0 && !bottom.myIsLand) { bottomValue = 0; } if (top != null && top.Rivers.Count == 0 && !top.myIsLand) { topValue = 0; } if (left != null && left.Rivers.Count == 0 && !left.myIsLand) { leftValue = 0; } if (right != null && right.Rivers.Count == 0 && !right.myIsLand) { rightValue = 0; } // override flow direction if a tile is significantly lower if (direction == Direction.Left) { if (Math.Abs(rightValue - leftValue) < 0.1) { rightValue = int.MaxValue; } } if (direction == Direction.Right) { if (Math.Abs(rightValue - leftValue) < 0.1) { leftValue = int.MaxValue; } } if (direction == Direction.Top) { if (Math.Abs(topValue - bottomValue) < 0.1) { bottomValue = int.MaxValue; } } if (direction == Direction.Bottom) { if (Math.Abs(topValue - bottomValue) < 0.1) { topValue = int.MaxValue; } } // find minimum float min = Math.Min(Math.Min(Math.Min(leftValue, rightValue), topValue), bottomValue); // if no minimum found - exit if (min == int.MaxValue) { return; } //Move to next neighbor if (min == leftValue) { if (left != null && left.myIsLand) { if (river.CurrentDirection != Direction.Left) { river.TurnCount++; river.CurrentDirection = Direction.Left; } findPathToWater(left, direction, ref river); } } else if (min == rightValue) { if (right != null && right.myIsLand) { if (river.CurrentDirection != Direction.Right) { river.TurnCount++; river.CurrentDirection = Direction.Right; } findPathToWater(right, direction, ref river); } } else if (min == bottomValue) { if (bottom != null && bottom.myIsLand) { if (river.CurrentDirection != Direction.Bottom) { river.TurnCount++; river.CurrentDirection = Direction.Bottom; } findPathToWater(bottom, direction, ref river); } } else if (min == topValue) { if (top != null && top.myIsLand) { if (river.CurrentDirection != Direction.Top) { river.TurnCount++; river.CurrentDirection = Direction.Top; } findPathToWater(top, direction, ref river); } } }
public void digRiver(River river, int size) { setRiverTile(river); RiverSize = size; if (size == 1) { if (myBottom != null) { myBottom.setRiverTile(river); if (myBottom.myRight != null) { myBottom.myRight.setRiverTile(river); } } if (myRight != null) { myRight.setRiverTile(river); } } if (size == 2) { if (myBottom != null) { myBottom.setRiverTile(river); if (myBottom.myRight != null) { myBottom.myRight.setRiverTile(river); } } if (myRight != null) { myRight.setRiverTile(river); } if (myTop != null) { myTop.setRiverTile(river); if (myTop.myLeft != null) { myTop.myLeft.setRiverTile(river); } if (myTop.myRight != null) { myTop.myRight.setRiverTile(river); } } if (myLeft != null) { myLeft.setRiverTile(river); if (myLeft.myBottom != null) { myLeft.myBottom.setRiverTile(river); } } } if (size == 3) { if (myBottom != null) { myBottom.setRiverTile(river); if (myBottom.myRight != null) { myBottom.myRight.setRiverTile(river); } if (myBottom.myBottom != null) { myBottom.myBottom.setRiverTile(river); if (myBottom.myBottom.myRight != null) { myBottom.myBottom.myRight.setRiverTile(river); } } } if (myRight != null) { myRight.setRiverTile(river); if (myRight.myRight != null) { myRight.myRight.setRiverTile(river); if (myRight.myRight.myBottom != null) { myRight.myRight.myBottom.setRiverTile(river); } } } if (myTop != null) { myTop.setRiverTile(river); if (myTop.myLeft != null) { myTop.myLeft.setRiverTile(river); } if (myTop.myRight != null) { myTop.myRight.setRiverTile(river); } } if (myLeft != null) { myLeft.setRiverTile(river); if (myLeft.myBottom != null) { myLeft.myBottom.setRiverTile(river); } } } if (size == 4) { if (myBottom != null) { myBottom.setRiverTile(river); if (myBottom.myRight != null) { myBottom.myRight.setRiverTile(river); } if (myBottom.myBottom != null) { myBottom.myBottom.setRiverTile(river); if (myBottom.myBottom.myRight != null) { myBottom.myBottom.myRight.setRiverTile(river); } } } if (myRight != null) { myRight.setRiverTile(river); if (myRight.myRight != null) { myRight.myRight.setRiverTile(river); if (myRight.myRight.myBottom != null) { myRight.myRight.myBottom.setRiverTile(river); } } } if (myTop != null) { myTop.setRiverTile(river); if (myTop.myRight != null) { myTop.myRight.setRiverTile(river); if (myTop.myRight.myRight != null) { myTop.myRight.myRight.setRiverTile(river); } } if (myTop.myTop != null) { myTop.myTop.setRiverTile(river); if (myTop.myTop.myRight != null) { myTop.myTop.myRight.setRiverTile(river); } } } if (myLeft != null) { myLeft.setRiverTile(river); if (myLeft.myBottom != null) { myLeft.myBottom.setRiverTile(river); if (myLeft.myBottom.myBottom != null) { myLeft.myBottom.myBottom.setRiverTile(river); } } if (myLeft.myLeft != null) { myLeft.myLeft.setRiverTile(river); if (myLeft.myLeft.myBottom != null) { myLeft.myLeft.myBottom.setRiverTile(river); } if (myLeft.myLeft.myTop != null) { myLeft.myLeft.myTop.setRiverTile(river); } } if (myLeft.myTop != null) { myLeft.myTop.setRiverTile(river); if (myLeft.myTop.myTop != null) { myLeft.myTop.myTop.setRiverTile(river); } } } } }