-
Notifications
You must be signed in to change notification settings - Fork 27
Border tile assignment improvements #839
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: Development
Are you sure you want to change the base?
Changes from 4 commits
a7826b1
60b1fa4
9cd4157
1a4c0d2
fd13815
b6c6b79
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -186,9 +186,13 @@ public bool NeighborsOcean() { | |
| /// This is used by some graphics algorithms. | ||
| /// </summary> | ||
| /// <returns></returns> | ||
| public Tile[] getEdgeNeighbors() { | ||
| Tile[] edgeNeighbors = { neighbors[TileDirection.NORTHEAST], neighbors[TileDirection.NORTHWEST], neighbors[TileDirection.SOUTHEAST], neighbors[TileDirection.SOUTHWEST]}; | ||
| return edgeNeighbors; | ||
| public Tile[] GetEdgeNeighbors() { | ||
| List<Tile> edgeNeighbors = new(); | ||
| if (neighbors.TryGetValue(TileDirection.NORTHEAST, out Tile ne)) edgeNeighbors.Add(ne); | ||
| if (neighbors.TryGetValue(TileDirection.NORTHWEST, out Tile nw)) edgeNeighbors.Add(nw); | ||
| if (neighbors.TryGetValue(TileDirection.SOUTHEAST, out Tile se)) edgeNeighbors.Add(se); | ||
| if (neighbors.TryGetValue(TileDirection.SOUTHWEST, out Tile sw)) edgeNeighbors.Add(sw); | ||
| return edgeNeighbors.ToArray(); | ||
| } | ||
|
|
||
| public override string ToString() { | ||
|
|
@@ -612,6 +616,69 @@ public Tile GetTileAtNeighborIndex(int neighborIndex) { | |
| return map.tileAt(XCoordinate + xDelta, YCoordinate + yDelta); | ||
| } | ||
|
|
||
|
|
||
| /// <summary> | ||
| /// <para> | ||
| /// Walks clockwise/counter-clockwise the nth ring around | ||
| /// the specified tile starting on the northmost tile | ||
| /// and tries to find the first tile that matches our boolean criterion. | ||
| /// </para> | ||
| /// <para> | ||
| /// This differs from <see cref="GetTilesWithinRankDistance"/>, | ||
| /// because it includes all the tiles regardless of the distance. | ||
| /// An example would be that GetTilesWithinRankDistance() with a rank of 2 | ||
| /// will not return a NN, SS, WW, or EE tile, whereas this method will. | ||
| /// </para> | ||
| /// <para> | ||
| /// It is mostly used to calculate to whom we should assign tiles | ||
| /// that are being claimed by more than 1 city or civilization. | ||
| /// </para> | ||
| /// </summary> | ||
| /// <param name="rank"></param> | ||
| /// <param name="predicate"></param> | ||
| /// <param name="clockwise"></param> | ||
| /// <returns></returns> | ||
| public Tile FindInRing(int rank, Func<Tile, bool> predicate, bool clockwise = true) { | ||
| Tile startingTile = map.tileAt(this.XCoordinate, this.YCoordinate - (2 * rank)); | ||
| int dx = startingTile.XCoordinate; | ||
| int dy = startingTile.YCoordinate; | ||
|
|
||
| if (startingTile != Tile.NONE && predicate(startingTile)) return startingTile; | ||
|
|
||
| // Going SW(counter-clockwise) or SE(clockwise) | ||
| for (int _ = 1; _ < (2 * rank) + 1; _++) { | ||
| if (clockwise) { dx++; dy++; } else { dx--; dy++; } | ||
| if (!IsInValidCoordinates(dx, dy, out Tile currentTile) || !predicate(currentTile)) continue; | ||
| return currentTile; | ||
| } | ||
| // Going SE(counter-clockwise) or SW(clockwise) | ||
| for (int _ = 1; _ < (2 * rank) + 1; _++) { | ||
| if (clockwise) { dx--; dy++; } else { dx++; dy++; } | ||
| if (!IsInValidCoordinates(dx, dy, out Tile currentTile) || !predicate(currentTile)) continue; | ||
| return currentTile; | ||
| } | ||
| // Going NE(counter-clockwise) or NW(clockwise) | ||
| for (int _ = 1; _ < (2 * rank) + 1; _++) { | ||
| if (clockwise) { dx--; dy--; } else { dx++; dy--; } | ||
| if (!IsInValidCoordinates(dx, dy, out Tile currentTile) || !predicate(currentTile)) continue; | ||
| return currentTile; | ||
| } | ||
| // Going NW(counter-clockwise) or NE(clockwise) | ||
| for (int _ = 1; _ < (2 * rank); _++) { | ||
| if (clockwise) { dx++; dy--; } else { dx--; dy--; } | ||
| if (!IsInValidCoordinates(dx, dy, out Tile currentTile) || !predicate(currentTile)) continue; | ||
| return currentTile; | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| private bool IsInValidCoordinates(int dx, int dy, out Tile currentTile) { | ||
|
||
| if (map.wrapHorizontally) dx %= map.numTilesWide; | ||
| if (map.wrapVertically) dy %= map.numTilesTall; | ||
| currentTile = map.tileAt(dx, dy); | ||
| return currentTile != null && currentTile != Tile.NONE; | ||
| } | ||
|
|
||
| // Returns the tiles in the spiral ordering defined by | ||
| // GetTileAtNeighborIndex(i). | ||
| public List<Tile> GetTilesWithinRankDistance(int rank) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this in addition to GetTilesWithinRankDistance, which returns things in spiral order?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetTilesWithinRankDistance returns tiles in a big fat cross style. I tried to use it, but for borders, although it's fine for the first rank, the 2nd rank doesn't include a NN, WW, EE or SS tile. This method goes around the "actual" ring around a tile. I called it ring to distinguish it from rank, which behaves differently.
I hope that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, thanks! Could you put that in a comment on the method to explain how it's different and why we need it?