private bool CouldWaterFlowDown(GridEntryViewModel entry) { if (entry.Y == this.YLength - 1) { //Water can flow out below the map return(true); } var cellRightBelow = this.Cells[entry.Y + 1][entry.X]; if (cellRightBelow.Type == GridEntryType.RunningWater) { //Water is already running down from here return(true); } if (cellRightBelow.Type == GridEntryType.Sand) { MakeWaterFlow(cellRightBelow); return(true); } //There is either clay or still water below us, so we can't run further down return(false); }
private void LetWaterFlowHorizontally(List <GridEntryViewModel> waterThatDidNotFlowDown) { //This might/will find duplicate bodies of water, but that doesn't matter var nextWaterBodyEdges = waterThatDidNotFlowDown .Select(entry => { //This will be left as null if we come to the edge or any along the path can flow down GridEntryViewModel nextOnLeftSide = null; for (var x = entry.X; x >= 0; x--) { //If it's not running water, it should be sand or clay, so this is what we're looking for. if (Cells[entry.Y][x].Type != GridEntryType.RunningWater) { nextOnLeftSide = Cells[entry.Y][x]; break; } GridEntryViewModel cellRightBelow = Cells[entry.Y + 1][x]; if (cellRightBelow.Type == GridEntryType.RunningWater || cellRightBelow.Type == GridEntryType.Sand) { break; } } //This will be left as null if we come to the edge or any along the path can flow down GridEntryViewModel nextOnRightSide = null; for (var x = entry.X; x < XLength; x++) { //If it's not running water, it should be sand or clay, so this is what we're looking for. if (Cells[entry.Y][x].Type != GridEntryType.RunningWater) { nextOnRightSide = Cells[entry.Y][x]; break; } GridEntryViewModel cellRightBelow = Cells[entry.Y + 1][x]; if (cellRightBelow.Type == GridEntryType.RunningWater || cellRightBelow.Type == GridEntryType.Sand) { break; } } return(Tuple.Create(nextOnLeftSide, nextOnRightSide)); }) .ToArray(); foreach (var waterBodyEdges in nextWaterBodyEdges) { switch (waterBodyEdges.Item1?.Type) { case null: //This means we have an edge here break; case GridEntryType.Sand: MakeWaterFlow(waterBodyEdges.Item1); break; case GridEntryType.Clay: //This case is handled by the right edge instead break; default: //This most likely happens because we have a duplicate of the body of water, so this is just to be ignored break; } switch (waterBodyEdges.Item2?.Type) { case null: //This means we have an edge here break; case GridEntryType.Sand: MakeWaterFlow(waterBodyEdges.Item2); break; case GridEntryType.Clay: //If both of the edges are clay, let's freeze the water. if (waterBodyEdges.Item1?.Type == GridEntryType.Clay) { for (var x = waterBodyEdges.Item1.X + 1; x < waterBodyEdges.Item2.X; x++) { MakeWaterStill(Cells[waterBodyEdges.Item1.Y][x]); } } break; default: //This most likely happens because we have a duplicate of the body of water, so this is just to be ignored break; } } }
private void MakeWaterStill(GridEntryViewModel cell) { cell.Type = GridEntryType.StillWater; _cellsWithRunningWater.Remove(cell); }
private void MakeWaterFlow(GridEntryViewModel cell) { cell.Type = GridEntryType.RunningWater; _waterCells.Add(cell); _cellsWithRunningWater.Add(cell); }