From 340a9cb11515f49551b86bfb95e2b32ce9aeba4a Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 19:31:27 +0000 Subject: [PATCH] Refactor AverageInt to use tuples Replaced individual integer coordinate parameters with integer tuples in Diamond.AverageInt to improve readability. Co-authored-by: johnstrand <11484777+johnstrand@users.noreply.github.com> --- patch.diff | 45 +++++++++++++++ src/GameUtils/Procedural/Diamond.cs | 20 +++---- src/GameUtils/Procedural/Diamond.cs.orig | 73 ++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 patch.diff create mode 100644 src/GameUtils/Procedural/Diamond.cs.orig diff --git a/patch.diff b/patch.diff new file mode 100644 index 0000000..2795f88 --- /dev/null +++ b/patch.diff @@ -0,0 +1,45 @@ +--- src/GameUtils/Procedural/Diamond.cs ++++ src/GameUtils/Procedural/Diamond.cs +@@ -1,4 +1,5 @@ +-using GameUtils.Types.Collections; ++using System.Numerics; ++using GameUtils.Types.Collections; + + namespace GameUtils.Procedural; + +@@ -45,11 +46,11 @@ + var mx = x + halfStep; + var my = y + halfStep; + +- map[mx, my] = valueFactory(AverageInt(map, x, y, x + step, y, x, y + step, x + step, y + step), range); +- map[mx, y] = valueFactory(AverageInt(map, x, y, x + step, y, mx, my, mx, y - step), range); +- map[x, my] = valueFactory(AverageInt(map, x, y, x, y + step, mx, my, x - step, my), range); +- map[x + step, my] = valueFactory(AverageInt(map, x + step, y, x + step, y + step, mx, my, x + step + step, my), range); +- map[mx, y + step] = valueFactory(AverageInt(map, x, y + step, x + step, y + step, mx, my, mx, y + step + step), range); ++ map[mx, my] = valueFactory(AverageInt(map, new(x, y), new(x + step, y), new(x, y + step), new(x + step, y + step)), range); ++ map[mx, y] = valueFactory(AverageInt(map, new(x, y), new(x + step, y), new(mx, my), new(mx, y - step)), range); ++ map[x, my] = valueFactory(AverageInt(map, new(x, y), new(x, y + step), new(mx, my), new(x - step, my)), range); ++ map[x + step, my] = valueFactory(AverageInt(map, new(x + step, y), new(x + step, y + step), new(mx, my), new(x + step + step, my)), range); ++ map[mx, y + step] = valueFactory(AverageInt(map, new(x, y + step), new(x + step, y + step), new(mx, my), new(mx, y + step + step)), range); + } + } + +@@ -60,13 +61,13 @@ + return map; + } + +- private static float AverageInt(Grid map, int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy) ++ private static float AverageInt(Grid map, Vector2 a, Vector2 b, Vector2 c, Vector2 d) + { + var sum = 0f; + var count = 0; +- if (ax >= 0 && ax < map.Width && ay >= 0 && ay < map.Height) { sum += map[ax, ay]; count++; } +- if (bx >= 0 && bx < map.Width && by >= 0 && by < map.Height) { sum += map[bx, by]; count++; } +- if (cx >= 0 && cx < map.Width && cy >= 0 && cy < map.Height) { sum += map[cx, cy]; count++; } +- if (dx >= 0 && dx < map.Width && dy >= 0 && dy < map.Height) { sum += map[dx, dy]; count++; } ++ if (map.IsInBounds(a)) { sum += map[a]; count++; } ++ if (map.IsInBounds(b)) { sum += map[b]; count++; } ++ if (map.IsInBounds(c)) { sum += map[c]; count++; } ++ if (map.IsInBounds(d)) { sum += map[d]; count++; } + return count == 0 ? 0f : sum / count; + } diff --git a/src/GameUtils/Procedural/Diamond.cs b/src/GameUtils/Procedural/Diamond.cs index 05bfd97..3d1e5f8 100644 --- a/src/GameUtils/Procedural/Diamond.cs +++ b/src/GameUtils/Procedural/Diamond.cs @@ -45,11 +45,11 @@ public static Grid Create(int size, int min, int max, float range, Func Create(int size, int min, int max, float range, Func map, int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy) + private static float AverageInt(Grid map, (int x, int y) a, (int x, int y) b, (int x, int y) c, (int x, int y) d) { var sum = 0f; var count = 0; - if (ax >= 0 && ax < map.Width && ay >= 0 && ay < map.Height) { sum += map[ax, ay]; count++; } - if (bx >= 0 && bx < map.Width && by >= 0 && by < map.Height) { sum += map[bx, by]; count++; } - if (cx >= 0 && cx < map.Width && cy >= 0 && cy < map.Height) { sum += map[cx, cy]; count++; } - if (dx >= 0 && dx < map.Width && dy >= 0 && dy < map.Height) { sum += map[dx, dy]; count++; } + if (map.IsInBounds(a.x, a.y)) { sum += map[a.x, a.y]; count++; } + if (map.IsInBounds(b.x, b.y)) { sum += map[b.x, b.y]; count++; } + if (map.IsInBounds(c.x, c.y)) { sum += map[c.x, c.y]; count++; } + if (map.IsInBounds(d.x, d.y)) { sum += map[d.x, d.y]; count++; } return count == 0 ? 0f : sum / count; } } diff --git a/src/GameUtils/Procedural/Diamond.cs.orig b/src/GameUtils/Procedural/Diamond.cs.orig new file mode 100644 index 0000000..05bfd97 --- /dev/null +++ b/src/GameUtils/Procedural/Diamond.cs.orig @@ -0,0 +1,73 @@ +using GameUtils.Types.Collections; + +namespace GameUtils.Procedural; + +/// +/// Generates a diamond-square map +/// +public static class Diamond +{ + /// + /// Creates a new diamond-square map from the specified parameters. + /// + /// Height and width. Must be a power-of-two plus one (e.g. 129, 257, 513). + /// Min value of the initial seed + /// Max value of the initial seed + /// The initial range for the next step + /// A method that will be passed the current range and is expected to return the range for the next iteration + /// A method that will be passed an average value and a range, and is expected to return an integer map value + /// Optional random seed for reproducible generation. Uses a thread-safe shared instance when null. + /// Thrown when is not a power-of-two plus one. + public static Grid Create(int size, int min, int max, float range, Func nextRange, Func valueFactory, int? seed = null) + { + var n = size - 1; + if (n < 1 || (n & (n - 1)) != 0) + { + throw new ArgumentException("Size must be a power-of-two plus one (e.g. 3, 5, 9, 17, 33, ...).", nameof(size)); + } + + var r = seed.HasValue ? new Random(seed.Value) : Random.Shared; + var map = new Grid(size, size); + map[0, 0] = r.Next(min, max); + map[0, size - 1] = r.Next(min, max); + map[size - 1, 0] = r.Next(min, max); + map[size - 1, size - 1] = r.Next(min, max); + + var step = size - 1; + + while (step > 1) + { + var halfStep = step / 2; + for (var y = 0; y < size - 1; y += step) + { + for (var x = 0; x < size - 1; x += step) + { + var mx = x + halfStep; + var my = y + halfStep; + + map[mx, my] = valueFactory(AverageInt(map, x, y, x + step, y, x, y + step, x + step, y + step), range); + map[mx, y] = valueFactory(AverageInt(map, x, y, x + step, y, mx, my, mx, y - step), range); + map[x, my] = valueFactory(AverageInt(map, x, y, x, y + step, mx, my, x - step, my), range); + map[x + step, my] = valueFactory(AverageInt(map, x + step, y, x + step, y + step, mx, my, x + step + step, my), range); + map[mx, y + step] = valueFactory(AverageInt(map, x, y + step, x + step, y + step, mx, my, mx, y + step + step), range); + } + } + + range = nextRange(range); + step = halfStep; + } + + return map; + } + + private static float AverageInt(Grid map, int ax, int ay, int bx, int by, int cx, int cy, int dx, int dy) + { + var sum = 0f; + var count = 0; + if (ax >= 0 && ax < map.Width && ay >= 0 && ay < map.Height) { sum += map[ax, ay]; count++; } + if (bx >= 0 && bx < map.Width && by >= 0 && by < map.Height) { sum += map[bx, by]; count++; } + if (cx >= 0 && cx < map.Width && cy >= 0 && cy < map.Height) { sum += map[cx, cy]; count++; } + if (dx >= 0 && dx < map.Width && dy >= 0 && dy < map.Height) { sum += map[dx, dy]; count++; } + return count == 0 ? 0f : sum / count; + } +}