From 9ecba43d731d21892a8985f0fe23e21c23c9bf87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Mon, 1 Jun 2020 22:26:29 +0200 Subject: Board : implement lineOfSight for VERTICAL HexBoard --- core/src/ch/asynk/gdx/boardgame/Tile.java | 7 + core/src/ch/asynk/gdx/boardgame/boards/Board.java | 3 + .../ch/asynk/gdx/boardgame/boards/HexBoard.java | 173 +++++++++++++++++++++ .../ch/asynk/gdx/boardgame/boards/SquareBoard.java | 7 + .../asynk/gdx/boardgame/boards/TriangleBoard.java | 7 + 5 files changed, 197 insertions(+) diff --git a/core/src/ch/asynk/gdx/boardgame/Tile.java b/core/src/ch/asynk/gdx/boardgame/Tile.java index 504a82d..36dcf32 100644 --- a/core/src/ch/asynk/gdx/boardgame/Tile.java +++ b/core/src/ch/asynk/gdx/boardgame/Tile.java @@ -14,6 +14,7 @@ public class Tile implements Drawable public int y; public float cx; public float cy; + public boolean blocked; private Overlays overlays; public Tile(int x, int y, float cx, float cy) @@ -22,11 +23,17 @@ public class Tile implements Drawable this.y = y; this.cx = cx; this.cy = cy; + this.blocked = false; if (defaultOverlay != null) { setOverlay(defaultOverlay); } } + public boolean blockLos(final Tile from, final Tile to) + { + return false; + } + public boolean overlaysEnabled() { if (overlays != null) { diff --git a/core/src/ch/asynk/gdx/boardgame/boards/Board.java b/core/src/ch/asynk/gdx/boardgame/boards/Board.java index 0a7acf1..020d12a 100644 --- a/core/src/ch/asynk/gdx/boardgame/boards/Board.java +++ b/core/src/ch/asynk/gdx/boardgame/boards/Board.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.math.Vector2; import ch.asynk.gdx.boardgame.Piece; import ch.asynk.gdx.boardgame.Tile; import ch.asynk.gdx.boardgame.tilestorages.TileStorage.TileKeyGenerator; +import ch.asynk.gdx.boardgame.utils.Collection; public interface Board extends TileKeyGenerator { @@ -19,6 +20,8 @@ public interface Board extends TileKeyGenerator public Tile[] getAdjacents(); public void buildAdjacents(int x, int y); + public boolean lineOfSight(int x0, int y0, int x1, int y1, Collection tiles); + enum Geometry { EUCLIDEAN, diff --git a/core/src/ch/asynk/gdx/boardgame/boards/HexBoard.java b/core/src/ch/asynk/gdx/boardgame/boards/HexBoard.java index 86347d1..691382b 100644 --- a/core/src/ch/asynk/gdx/boardgame/boards/HexBoard.java +++ b/core/src/ch/asynk/gdx/boardgame/boards/HexBoard.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.math.Vector2; import ch.asynk.gdx.boardgame.Tile; import ch.asynk.gdx.boardgame.tilestorages.TileStorage.TileProvider; +import ch.asynk.gdx.boardgame.utils.Collection; public class HexBoard implements Board { @@ -259,4 +260,176 @@ public class HexBoard implements Board } } } + + @Override public boolean lineOfSight(int x0, int y0, int x1, int y1, Collection tiles) + { + tiles.clear(); + + // orthogonal projection + int ox0 = x0 - ((y0 + 1) / 2); + int ox1 = x1 - ((y1 + 1) / 2); + int dy = y1 - y0; + int dx = ox1 - ox0; + + // same sign + boolean sig = !(((dx < 0) && (dy >= 0)) || ((dx >= 0) && (dy < 0))); + + // is positive + int xs = 1; + int ys = 1; + if (dx < 0) xs = -1; + if (dy < 0) ys = -1; + + // dx counts half width + dy = Math.abs(dy); + dx = Math.abs(2 * dx); + if ((dy % 2) == 1) { + if ((y0 % 2) == 0) { + dx += xs; + } else { + dx -= xs; + Math.abs(dx); + } + } + + int dx3 = 3 * dx; + int dy3 = 3 * dy; + + if (dx == 0) + return verticalLineOfSight(x0, y0, x1, y1, tiles); + if (dx == dy3) + return diagonalLineOfSight(x0, y0, x1, y1, tiles); + + // angle is smaller than diagonal + boolean flat = (dx > dy3); + + int x = x0; + int y = y0; + int e = -2 * dx; + + Tile from = getTile(x0, y0); + Tile to = getTile(x1, y1); + tiles.add(from); + boolean losBlocked = false; + while ((x != x1) || (y != y1)) { + if (e > 0) { + e -= (dy3 + dx3); + y += ys; + if (!sig) + x -= xs; + } else { + e += dy3; + if ((e > -dx) || (!flat && (e == -dx))) { + e -= dx3; + y += ys; + if (sig) + x += xs; + } else if (e < -dx3) { + e += dx3; + y -= ys; + if (!sig) + x += xs; + } else { + e += dy3; + x += xs; + } + } + final Tile t = getTile(x, y); + tiles.add(t); + t.blocked = losBlocked; + losBlocked = (losBlocked || t.blockLos(from, to)); + } + + return tiles.get(tiles.size() - 1).blocked; + } + + private boolean verticalLineOfSight(int x0, int y0, int x1, int y1, Collection tiles) + { + int d = ( (y1 > y0) ? 1 : -1); + int x = x0; + int y = y0; + + + Tile t = null; + Tile from = getTile(x0, y0); + Tile to = getTile(x1, y1); + tiles.add(from); + boolean losBlocked = false; + while ((x != x1) || (y != y1)) { + boolean blocked = losBlocked; + + y += d; + t = getTile(x, y); + if (t != null) { + tiles.add(t); + t.blocked = losBlocked; + blocked = (blocked || t.blockLos(from, to)); + } + + x += d; + t = getTile(x, y); + if (t != null) { + tiles.add(t); + t.blocked = losBlocked; + blocked = (blocked && t.blockLos(from, to)); + } + + y += d; + t = getTile(x, y); + if (t != null) { + tiles.add(t); + t.blocked = (losBlocked || blocked); + losBlocked = (t.blocked || t.blockLos(from, to)); + } + } + + return tiles.get(tiles.size() - 1).blocked; + } + + private boolean diagonalLineOfSight(int x0, int y0, int x1, int y1, Collection tiles) + { + int dy = ( (y1 > y0) ? 1 : -1); + int dx = ( (x1 > x0) ? 1 : -1); + boolean sig = !(((dx < 0) && (dy >= 0)) || ((dx >= 0) && (dy < 0))); + + int x = x0; + int y = y0; + + Tile t = null; + Tile from = getTile(x0, y0); + Tile to = getTile(x1, y1); + tiles.add(from); + boolean losBlocked = false; + while ((x != x1) || (y != y1)) { + boolean blocked = losBlocked; + + x += dx; + t = getTile(x, y); + if (t != null) { + tiles.add(t); + t.blocked = losBlocked; + blocked = (blocked || t.blockLos(from, to)); + } + + y += dy; + if (!sig) + x -= dx; + t = getTile(x, y); + if (t != null) { + tiles.add(t); + t.blocked = losBlocked; + blocked = (blocked && t.blockLos(from, to)); + } + + x += dx; + t = getTile(x, y); + if (t != null) { + tiles.add(t); + t.blocked = (losBlocked || blocked); + losBlocked = (t.blocked || t.blockLos(from, to)); + } + } + + return tiles.get(tiles.size() - 1).blocked; + } } diff --git a/core/src/ch/asynk/gdx/boardgame/boards/SquareBoard.java b/core/src/ch/asynk/gdx/boardgame/boards/SquareBoard.java index 3997c1c..84eee34 100644 --- a/core/src/ch/asynk/gdx/boardgame/boards/SquareBoard.java +++ b/core/src/ch/asynk/gdx/boardgame/boards/SquareBoard.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.math.Vector2; import ch.asynk.gdx.boardgame.Tile; import ch.asynk.gdx.boardgame.tilestorages.TileStorage.TileProvider; +import ch.asynk.gdx.boardgame.utils.Collection; public class SquareBoard implements Board { @@ -102,4 +103,10 @@ public class SquareBoard implements Board } return -1; } + + @Override public boolean lineOfSight(int x0, int y0, int x1, int y1, Collection tiles) + { + System.err.println("NOT implemented yet."); + return false; + } } diff --git a/core/src/ch/asynk/gdx/boardgame/boards/TriangleBoard.java b/core/src/ch/asynk/gdx/boardgame/boards/TriangleBoard.java index db3cb5d..cf3ef07 100644 --- a/core/src/ch/asynk/gdx/boardgame/boards/TriangleBoard.java +++ b/core/src/ch/asynk/gdx/boardgame/boards/TriangleBoard.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.math.Vector2; import ch.asynk.gdx.boardgame.Tile; import ch.asynk.gdx.boardgame.tilestorages.TileStorage.TileProvider; +import ch.asynk.gdx.boardgame.utils.Collection; public class TriangleBoard implements Board { @@ -171,4 +172,10 @@ public class TriangleBoard implements Board } return -1; } + + @Override public boolean lineOfSight(int x0, int y0, int x1, int y1, Collection tiles) + { + System.err.println("NOT implemented yet."); + return false; + } } -- cgit v1.1-2-g2b99