diff --git a/examples/debug.png b/examples/debug.png index bbb918962ed113c30f201511e1c0da6f8bebec8c..03822747f1d56b2a3a9c8f28ed799ac84338a301 100644 Binary files a/examples/debug.png and b/examples/debug.png differ diff --git a/examples/maze1.png b/examples/maze1.png new file mode 100644 index 0000000000000000000000000000000000000000..1d0e89eac8cdd7837acf4492417be38bcd7897e0 Binary files /dev/null and b/examples/maze1.png differ diff --git a/examples/maze2.png b/examples/maze2.png new file mode 100644 index 0000000000000000000000000000000000000000..1aaec2636c11260c9a9edfce809568154ef6b57d Binary files /dev/null and b/examples/maze2.png differ diff --git a/src/Program.java b/src/Program.java index a182e27ba7474e246c7b66769c7109d39548e725..b1c8ef9cf566766a7b9fdd55f37668c0285734bd 100644 --- a/src/Program.java +++ b/src/Program.java @@ -1,13 +1,14 @@ // - 1 - import approach2.window.MainWindowApproach2; +import approach3.window.MainWindowApproach3; public class Program { public static void main(String[] args) throws Exception { - MainWindowApproach2 window = new MainWindowApproach2("Pathfinder v1", 1080, 1080); + MainWindowApproach3 window = new MainWindowApproach3("Pathfinder v1", 1080, 1080); window.run(); } diff --git a/src/approach3/parallel/SharedRessources.java b/src/approach3/parallel/SharedRessources.java index 198eef2111f38a85278a69eb637e14b04e90ae4a..94e1a487f278b019d261f2e2b1cf0432f8d89b24 100644 --- a/src/approach3/parallel/SharedRessources.java +++ b/src/approach3/parallel/SharedRessources.java @@ -96,6 +96,10 @@ public class SharedRessources { } } + public Int3 getData(int x, int y) { + return data[x + y * width]; + } + public boolean isWall(int x, int y) { return walls[x + y * width]; } @@ -104,4 +108,12 @@ public class SharedRessources { walls[x + y * width] = true; } + public int getWidth() { + return this.width; + } + + public int getHeight() { + return this.height; + } + } diff --git a/src/approach3/parallel/WallBasedPathfinder.java b/src/approach3/parallel/WallBasedPathfinder.java index a0270c4597736085268e3c881d7eafcae11a9890..887ab246cd2d65f542f9429d509fb8782a720a2a 100644 --- a/src/approach3/parallel/WallBasedPathfinder.java +++ b/src/approach3/parallel/WallBasedPathfinder.java @@ -1,7 +1,121 @@ package approach3.parallel; +import approach3.parallel.operations.Trace; +import structs.Int3; +import structs.Vec3; + +import java.awt.*; +import java.util.ArrayList; + public class WallBasedPathfinder { + public void find() { + + int beginX = SharedRessources.getInstance().getStart().x; + int beginY = SharedRessources.getInstance().getStart().y; + + int endX = SharedRessources.getInstance().getEnd().x; + int endY = SharedRessources.getInstance().getEnd().y; + + + SharedRessources + .getInstance() + .getExecutor() + .execute(new Trace(endX, endY, beginX, beginY, 0)); + + + } + + + ArrayList<Point> debug = new ArrayList<>(); + + + public ArrayList<Point> calculatePath(int startX, int startY, int destX, int destY) { + + int x = startX; + int y = startY; + + while (x != destX || y != destY) { + + debug.add(new Point(x, y)); + + Int3 currentDir + = + SharedRessources.getInstance().getData(x, y); + + int dx = (int) currentDir.getX(); + int dy = (int) currentDir.getY(); + + if (dx == 0 && dy == 0) + break; + + x += dx; + y += dy; + + + } + + System.out.println("Done."); + + return debug; + } + + + public void draw(Graphics g) { + + + for (int j = 0; j < SharedRessources.getInstance().getHeight(); j++) { + for (int i = 0; i < SharedRessources.getInstance().getWidth(); i++) { + if (SharedRessources.getInstance().isWall(i, j)) { + g.setColor(Color.blue); + g.fillRect(i * 5, j * 5, 5, 5); + } else { + int dx = (int) SharedRessources.getInstance().getData(i, j).getX() * 5; + int dy = (int) SharedRessources.getInstance().getData(i, j).getY() * 5; + + if (dx != 0 || dy != 0) { + int green = SharedRessources.getInstance().getStep(i, j); + if (green >= 255) + green = 255; + Color color + = new Color(0, 255, 0); + + g.setColor(color); + + g.fillRect(i * 5, j * 5, 5, 5); + + g.setColor(Color.red); + g.drawLine(i * 5, j * 5, i * 5 + dx, j * 5 + dy); + + + } else { + g.setColor(Color.black); + g.fillRect(i * 5, j * 5, 5, 5); + } + } + } + } + + if (SharedRessources.getInstance().getEnd() == null || SharedRessources.getInstance().getStart() == null) + return; + + + g.setColor(Color.yellow); + g.fillRect(SharedRessources.getInstance().getEnd().x * 5, + SharedRessources.getInstance().getEnd().y * 5, 5 + , 5); + + g.setColor(Color.red); + g.fillRect(SharedRessources.getInstance().getStart().x * 5, + SharedRessources.getInstance().getStart().y * 5 + , 5, 5); + + + g.setColor(Color.red); + + for (int i = 0; i < debug.size(); i++) + g.fillRect(debug.get(i).x * 5, debug.get(i).y * 5, 5, 5); + } } diff --git a/src/approach3/parallel/operations/Flood.java b/src/approach3/parallel/operations/Flood.java index 952adfe9c6e8c3bae9e0f5a7b917560dbe7122be..55563b52eaacb4764c918ffb29c27e5e1d9ad11b 100644 --- a/src/approach3/parallel/operations/Flood.java +++ b/src/approach3/parallel/operations/Flood.java @@ -37,20 +37,16 @@ public class Flood implements Runnable { while (!openPoints.isEmpty()) { if (SharedRessources.getInstance().isFound()) - return; + break; Point cur = openPoints.poll(); - int x = cur.x; int y = cur.y; - if(steps >= SharedRessources.getInstance().getStep(x, y)) - break; - boolean left = SharedRessources.getInstance().isWall(x - 1, y); boolean @@ -64,7 +60,6 @@ public class Flood implements Runnable { SharedRessources.getInstance().isWall(x - 1, y - 1); boolean rightUp = SharedRessources.getInstance().isWall(x + 1, y - 1); - boolean leftDown = SharedRessources.getInstance().isWall(x - 1, y + 1); boolean rightDown = @@ -128,23 +123,21 @@ public class Flood implements Runnable { } - SharedRessources - .getInstance() - .getExecutor() - .execute(new Trace( - x, - y, - SharedRessources.getInstance().getStart().x, - SharedRessources.getInstance().getStart().y, - steps)); + if (steps % 18 == 0) + SharedRessources + .getInstance() + .getExecutor() + .execute(new Trace( + x, + y, + SharedRessources.getInstance().getStart().x, + SharedRessources.getInstance().getStart().y, + steps)); steps++; } - System.out.println("Done flooding."); - - } } diff --git a/src/approach3/parallel/operations/Trace.java b/src/approach3/parallel/operations/Trace.java index c1b93fc47eab9f6a9e6635af748f99337d76b10d..3246e379217deff11444052f0d18673e337d2c8f 100644 --- a/src/approach3/parallel/operations/Trace.java +++ b/src/approach3/parallel/operations/Trace.java @@ -40,6 +40,7 @@ public class Trace implements Runnable { if (SharedRessources.getInstance().isFound()) return; + oldX = x0; oldY = y0; @@ -60,46 +61,69 @@ public class Trace implements Runnable { y0 += sy; } - step++; - int currentStep = SharedRessources.getInstance().getStep(x0, y0); + if (step < currentStep) { + int dirX = x0 - oldX; + int dirY = y0 - oldY; + + SharedRessources.getInstance() + .setData(x0, y0, -dirX, -dirY, step); + + } + if (SharedRessources.getInstance().isWall(x0, y0)) { - if (step < SharedRessources.getInstance().getStep(oldX - 1, oldY)) + if (step < SharedRessources.getInstance().getStep(oldX - 1, oldY)) { SharedRessources .getInstance() .getExecutor() .execute(new Flood(oldX - 1, oldY, step)); - if (step < SharedRessources.getInstance().getStep(oldX + 1, oldY)) + SharedRessources.getInstance() + .setData(oldX - 1, oldY, 1, 0, step); + } + + + if (step < SharedRessources.getInstance().getStep(oldX + 1, oldY)) { SharedRessources .getInstance() .getExecutor() .execute(new Flood(oldX + 1, oldY, step)); - if (step < SharedRessources.getInstance().getStep(oldX, oldY - 1)) + SharedRessources.getInstance() + .setData(oldX + 1, oldY, -1, 0, step); + } + + if (step < SharedRessources.getInstance().getStep(oldX, oldY - 1)) { SharedRessources .getInstance() .getExecutor() .execute(new Flood(oldX, oldY - 1, step)); - if (step < SharedRessources.getInstance().getStep(oldX, oldY + 1)) + SharedRessources.getInstance() + .setData(oldX, oldY - 1, 0, 1, step); + + } + + if (step < SharedRessources.getInstance().getStep(oldX, oldY + 1)) { SharedRessources .getInstance() .getExecutor() .execute(new Flood(oldX, oldY + 1, step)); - break; - } else if (step < currentStep) { - int dirX = x0 - oldX; - int dirY = y0 - oldY; + SharedRessources.getInstance() + .setData(oldX, oldY + 1, 0, -1, step); - SharedRessources.getInstance() - .setData(x0, y0, dirX, dirY, step); + } + break; } + + + step++; + } } diff --git a/src/approach3/window/MainWindowApproach3.java b/src/approach3/window/MainWindowApproach3.java index e70b60888ba286cbff1f23fdbcb91bbfc4f63339..ab3226b55b343192abcdb25812057ac125ec87f2 100644 --- a/src/approach3/window/MainWindowApproach3.java +++ b/src/approach3/window/MainWindowApproach3.java @@ -1,26 +1,91 @@ package approach3.window; +import approach3.misc.MapLoader; +import approach3.parallel.SharedRessources; +import approach3.parallel.WallBasedPathfinder; import framework.Game; +import javax.imageio.ImageIO; import java.awt.*; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; public class MainWindowApproach3 extends Game { public MainWindowApproach3(String title, int w, int h) { super(title, w, h); } + + private WallBasedPathfinder pathfinder; + @Override public void loadGame() { + SharedRessources.setMaxCores(4); + try { + MapLoader.getDefault().load(ImageIO.read(new File("examples/maze1.png"))); + } catch (IOException e) { + e.printStackTrace(); + } + + pathfinder = new WallBasedPathfinder(); + } + + private boolean pressed; + @Override public void updateGame() { + if (isMouseKeyDown(MouseEvent.BUTTON1)) + SharedRessources.getInstance().setStart(this.getMouseX() / 5, this.getMouseY() / 5); + + if (isMouseKeyDown(MouseEvent.BUTTON3)) + SharedRessources.getInstance().setEnd(this.getMouseX() / 5, this.getMouseY() / 5); + + if (isKeyDown(KeyEvent.VK_ENTER) && !pressed) { + pressed = true; + pathfinder.find(); + + + while (!SharedRessources.getInstance().isFound()); + + int beginX = SharedRessources.getInstance().getStart().x; + int beginY = SharedRessources.getInstance().getStart().y; + + int endX = SharedRessources.getInstance().getEnd().x; + int endY = SharedRessources.getInstance().getEnd().y; + + + SharedRessources.getInstance() + .getExecutor() + .execute(new Runnable() { + @Override + public void run() { + pts = pathfinder.calculatePath(beginX, beginY, endX, endY); + } + }); + + } + + if (isKeyUp(KeyEvent.VK_ENTER)) + pressed = false; + + } + ArrayList<Point> pts; + @Override public void renderGame(Graphics g) { + if (pathfinder == null) + return; + pathfinder.draw(g); } }