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);
     }
 }