diff --git a/examples/debug.png b/examples/debug.png
new file mode 100644
index 0000000000000000000000000000000000000000..bbb918962ed113c30f201511e1c0da6f8bebec8c
Binary files /dev/null and b/examples/debug.png differ
diff --git a/src/Program.java b/src/Program.java
index a25e53b327ff8c07973088c2a44b793c8998b0f9..ee73c02dafb710666ef4f6b0f005cd45591e9646 100644
--- a/src/Program.java
+++ b/src/Program.java
@@ -1,13 +1,13 @@
 // - 1 -
 
-import parallel.EagerWorkingThread;
-import window.MainWindow;
+import window.MainWindowApproach1;
+import window.MainWindowApproach2;
 
 public class Program {
 
 
     public static void main(String[] args) throws Exception {
-        MainWindow window = new MainWindow("Pathfinder v1", 1080, 1080);
+        MainWindowApproach2 window = new MainWindowApproach2("Pathfinder v1", 1080, 1080);
         window.run();
 
     }
diff --git a/src/algorithm/Explorer.java b/src/approach1/algorithm/Explorer.java
similarity index 95%
rename from src/algorithm/Explorer.java
rename to src/approach1/algorithm/Explorer.java
index 7e9fe2c0e15491928d4961b3f9fc6ac550ec6509..092cfc75f8dd0721205f81072c9a781675ab208d 100644
--- a/src/algorithm/Explorer.java
+++ b/src/approach1/algorithm/Explorer.java
@@ -1,7 +1,6 @@
-package algorithm;
+package approach1.algorithm;
 
-import parallel.EagerWorkingThread;
-import parallel.SharedRessources;
+import approach1.parallel.SharedRessources;
 import structs.Vec3;
 
 public class Explorer {
@@ -20,11 +19,6 @@ public class Explorer {
 
     private Direction direction;
 
-
-    public int getSteps() {
-        return steps;
-    }
-
     public Explorer(int x, int y, int steps, Direction direction) {
         this.x = x;
         this.y = y;
diff --git a/src/algorithm/ParallelPathfinder.java b/src/approach1/algorithm/ParallelPathfinder.java
similarity index 97%
rename from src/algorithm/ParallelPathfinder.java
rename to src/approach1/algorithm/ParallelPathfinder.java
index 217e09ac9544a2a9bdcc63f8cf41d09e6c8c48a9..fbb5bc45733cb81fb5ca74b11029db88e6f56db9 100644
--- a/src/algorithm/ParallelPathfinder.java
+++ b/src/approach1/algorithm/ParallelPathfinder.java
@@ -1,7 +1,6 @@
-package algorithm;
+package approach1.algorithm;
 
-import parallel.EagerWorkingThread;
-import parallel.SharedRessources;
+import approach1.parallel.SharedRessources;
 import structs.Vec3;
 
 import java.awt.*;
diff --git a/src/algorithm/WorkingExplorers.java b/src/approach1/algorithm/WorkingExplorers.java
similarity index 89%
rename from src/algorithm/WorkingExplorers.java
rename to src/approach1/algorithm/WorkingExplorers.java
index 8b6ad68219f9bc8ba51253f2672fe3e61baaadb0..787350c3282f60abc4f8ae2c3c49a65e2715537d 100644
--- a/src/algorithm/WorkingExplorers.java
+++ b/src/approach1/algorithm/WorkingExplorers.java
@@ -1,12 +1,10 @@
-package algorithm;
+package approach1.algorithm;
 
-import parallel.EagerWorkingThread;
-import parallel.SharedRessources;
+import approach1.parallel.EagerWorkingThread;
+import approach1.parallel.SharedRessources;
 
 import java.util.*;
-import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.LinkedBlockingQueue;
 
 public class WorkingExplorers extends EagerWorkingThread {
 
diff --git a/src/parallel/EagerWorkingThread.java b/src/approach1/parallel/EagerWorkingThread.java
similarity index 97%
rename from src/parallel/EagerWorkingThread.java
rename to src/approach1/parallel/EagerWorkingThread.java
index cb1bba64b97f0f82c0a04b414edcea1cf72b9982..6145beb3fa68753c56809fd08ba8f35b6835af5d 100644
--- a/src/parallel/EagerWorkingThread.java
+++ b/src/approach1/parallel/EagerWorkingThread.java
@@ -1,4 +1,4 @@
-package parallel;
+package approach1.parallel;
 
 public abstract class EagerWorkingThread extends Thread {
 
diff --git a/src/parallel/MapLoader.java b/src/approach1/parallel/MapLoader.java
similarity index 98%
rename from src/parallel/MapLoader.java
rename to src/approach1/parallel/MapLoader.java
index d0721bae7f44421934b8faba899ba279372888bf..50906d95276328d9afed903a0848e497bfb0cead 100644
--- a/src/parallel/MapLoader.java
+++ b/src/approach1/parallel/MapLoader.java
@@ -1,4 +1,4 @@
-package parallel;
+package approach1.parallel;
 
 import structs.Vec3;
 
diff --git a/src/parallel/SharedRessources.java b/src/approach1/parallel/SharedRessources.java
similarity index 90%
rename from src/parallel/SharedRessources.java
rename to src/approach1/parallel/SharedRessources.java
index 7f115e9d32ace52b9d15605f103350caf96a6db8..511965405b22ff9a96dd6cba97a1f63b2c3d6643 100644
--- a/src/parallel/SharedRessources.java
+++ b/src/approach1/parallel/SharedRessources.java
@@ -1,11 +1,9 @@
-package parallel;
+package approach1.parallel;
 
-import algorithm.Explorer;
-import algorithm.WorkingExplorers;
+import approach1.algorithm.Explorer;
+import approach1.algorithm.WorkingExplorers;
 import structs.Vec3;
 
-import java.util.Stack;
-
 public class SharedRessources {
     private static int USING_CORES;
 
@@ -81,6 +79,14 @@ public class SharedRessources {
     }
 
     public void add(Explorer explorer) {
+
+        for(int i = 0; i < maxCores; i++){
+            if(workingThreads[i].isReady()){
+                workingThreads[i].add(explorer);
+                return;
+            }
+        }
+
         this.workingThreads[(currentCore++) % maxCores].add(explorer);
     }
 
diff --git a/src/approach2/ExplorerThread.java b/src/approach2/ExplorerThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e2693c51fd4a92356ed287f5c1800221cb4b228
--- /dev/null
+++ b/src/approach2/ExplorerThread.java
@@ -0,0 +1,17 @@
+package approach2;
+
+import approach2.algorithm.Explorer;
+
+public class ExplorerThread extends Thread {
+
+    private Explorer explorer;
+
+    @Override
+    public void run() {
+        explorer.explore();
+    }
+
+    public void setExplorer(Explorer explorer) {
+        this.explorer = explorer;
+    }
+}
diff --git a/src/approach2/MapLoader.java b/src/approach2/MapLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9dd5967138a57e8cf5f39247d0470cb374926d0
--- /dev/null
+++ b/src/approach2/MapLoader.java
@@ -0,0 +1,45 @@
+package approach2;
+
+import structs.Vec3;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+
+public class MapLoader {
+
+    private int width;
+    private int height;
+
+    private MapLoader() {
+    }
+
+    private static MapLoader mapLoader;
+
+    public static MapLoader getDefault() {
+        if (mapLoader == null)
+            mapLoader = new MapLoader();
+        return mapLoader;
+    }
+
+    public void load(BufferedImage src) {
+        this.width = src.getWidth();
+        this.height = src.getHeight();
+
+        SharedRessources.getInstance().setWidth(width);
+        SharedRessources.getInstance().setHeight(height);
+
+        SharedRessources.getInstance().initializeArrays();
+
+        // https://stackoverflow.com/a/9470843/14727115
+        byte[] pixels = ((DataBufferByte) src.getRaster().getDataBuffer()).getData();
+
+        for (int j = 0; j < height; j++) {
+            for (int i = 0; i < width; i++) {
+                if (((BufferedImage) src).getRGB(i, j) == Color.black.getRGB())
+                    SharedRessources.getInstance().setWall(i, j);
+            }
+        }
+    }
+
+}
diff --git a/src/approach2/SharedRessources.java b/src/approach2/SharedRessources.java
new file mode 100644
index 0000000000000000000000000000000000000000..21669447093752884e735fbc112c139177f1e9dc
--- /dev/null
+++ b/src/approach2/SharedRessources.java
@@ -0,0 +1,121 @@
+package approach2;
+
+import approach1.algorithm.WorkingExplorers;
+import approach2.algorithm.Explorer;
+import structs.Vec3;
+
+public class SharedRessources {
+
+    private static SharedRessources sharedRessources;
+
+    public static SharedRessources getInstance() {
+        if (sharedRessources == null)
+            sharedRessources = new SharedRessources(USING_CORES);
+        return sharedRessources;
+    }
+
+    private static int USING_CORES;
+
+    /***
+     * Use Integer.MAX_VALUE for all cores
+     * @param cores
+     */
+    public static void setMaximumCores(int cores) {
+        if (cores >= Runtime.getRuntime().availableProcessors())
+            cores = Runtime.getRuntime().availableProcessors();
+        USING_CORES = cores;
+    }
+
+    private int width;
+    private int height;
+
+    private boolean[] wallMatrix;
+    private boolean[] visitMatrix;
+
+    private Vec3[] directionMatrix;
+
+    private int maxCores;
+    private int currentCore;
+
+    private ExplorerThread[] workingThreads;
+
+
+    private SharedRessources(int cores) {
+        maxCores = cores;
+        currentCore = 0;
+
+        System.out.println("[*] Using " + maxCores + " cores.");
+
+        workingThreads = new ExplorerThread[maxCores];
+        for (int i = 0; i < maxCores; i++)
+            workingThreads[i] = new ExplorerThread();
+    }
+
+    public void initializeArrays() {
+        wallMatrix = new boolean[width * height];
+        visitMatrix = new boolean[width * height];
+        directionMatrix = new Vec3[width * height];
+
+        for (int i = 0; i < directionMatrix.length; i++)
+            directionMatrix[i] = new Vec3(0, 0, Integer.MAX_VALUE);
+    }
+
+    public void setExplorer(Explorer explorer) {
+        int index
+                = (currentCore++) % maxCores;
+
+        workingThreads[index]
+                .setExplorer(explorer);
+    }
+
+    public void start() {
+        for (int i = 0; i < maxCores; i++)
+            workingThreads[i].start();
+    }
+
+
+    public int getWidth() {
+        return width;
+    }
+
+    public int getHeight() {
+        return height;
+    }
+
+    protected void setWidth(int width) {
+        this.width = width;
+    }
+
+    protected void setHeight(int height) {
+        this.height = height;
+    }
+
+    protected void setWall(int x, int y) {
+        wallMatrix[x + y * width] = true;
+    }
+
+    public boolean isWall(int x, int y) {
+        return wallMatrix[x + y * width];
+    }
+
+    public int getStep(int x, int y) {
+        return (int) directionMatrix[x + y * width].getZ();
+    }
+
+    public void visit(int x, int y) {
+        visitMatrix[x + y * width] = true;
+    }
+
+    public boolean isVisited(int x, int y) {
+        return visitMatrix[x + y * width];
+    }
+
+    public Vec3 getData(int x, int y) {
+        return directionMatrix[x + y * width];
+    }
+
+    public void set(int x, int y, Vec3 data) {
+        directionMatrix[x + y * width]
+                = new Vec3(data.getX(), data.getY(), data.getZ());
+    }
+}
diff --git a/src/approach2/algorithm/Explorer.java b/src/approach2/algorithm/Explorer.java
new file mode 100644
index 0000000000000000000000000000000000000000..727edd3ac4e8205fad7be58b41d88a805c5af09a
--- /dev/null
+++ b/src/approach2/algorithm/Explorer.java
@@ -0,0 +1,119 @@
+package approach2.algorithm;
+
+import approach2.SharedRessources;
+import structs.Vec3;
+
+import java.awt.*;
+import java.awt.geom.Point2D;
+import java.util.HashMap;
+import java.util.Stack;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class Explorer {
+
+    private int px;
+    private int py;
+
+    private int steps;
+
+    public Explorer(int x, int y, int steps) {
+        this.px = x;
+        this.py = y;
+        this.steps = steps;
+    }
+
+    private ConcurrentLinkedQueue<Point> openPoints
+            = new ConcurrentLinkedQueue<>();
+
+    public void explore() {
+        openPoints.offer(new Point(px, py));
+
+
+        while (!openPoints.isEmpty()) {
+
+
+            Point cur
+                    = openPoints.poll();
+
+            int x = cur.x;
+            int y = cur.y;
+
+            SharedRessources.getInstance().visit(x, y);
+
+
+            boolean
+                    left = SharedRessources.getInstance().isWall(x - 1, y);
+            boolean
+                    right = SharedRessources.getInstance().isWall(x + 1, y);
+            boolean up
+                    = SharedRessources.getInstance().isWall(x, y - 1);
+            boolean down
+                    = SharedRessources.getInstance().isWall(x, y + 1);
+
+            int stepLeft
+                    = SharedRessources.getInstance().getStep(x - 1, y);
+            int stepRight
+                    = SharedRessources.getInstance().getStep(x + 1, y);
+            int stepUp
+                    = SharedRessources.getInstance().getStep(x, y - 1);
+            int stepDown
+                    = SharedRessources.getInstance().getStep(x, y + 1);
+
+            if (!left) {
+                if (steps < stepLeft) {
+                    SharedRessources.getInstance()
+                            .set(x - 1, y, new Vec3(1, 0, steps + 1));
+
+                    openPoints
+                            .offer(new Point(x - 1, y));
+
+                }
+            }
+
+            if (!right) {
+                if (steps < stepRight) {
+                    SharedRessources.getInstance()
+                            .set(x + 1, y, new Vec3(-1, 0, steps + 1));
+
+
+                    openPoints
+                            .offer(new Point(x + 1, y));
+                }
+            }
+
+            if (!up) {
+                if (steps < stepUp) {
+                    SharedRessources.getInstance()
+                            .set(x, y - 1, new Vec3(0, 1, steps + 1));
+
+
+                    openPoints
+                            .offer(new Point(x, y - 1));
+                }
+            }
+
+            if (!down) {
+                if (steps < stepDown) {
+                    SharedRessources.getInstance()
+                            .set(x, y + 1, new Vec3(0, -1, steps + 1));
+
+
+                    openPoints
+                            .offer(new Point(x, y + 1));
+                }
+            }
+
+
+
+            steps++;
+
+
+
+
+        }
+
+
+    }
+
+
+}
diff --git a/src/approach2/algorithm/ParallelPathfinder.java b/src/approach2/algorithm/ParallelPathfinder.java
new file mode 100644
index 0000000000000000000000000000000000000000..724f4ca6b3c06384d0d66ec059aae38877caaf5a
--- /dev/null
+++ b/src/approach2/algorithm/ParallelPathfinder.java
@@ -0,0 +1,130 @@
+package approach2.algorithm;
+
+import approach2.SharedRessources;
+import structs.Vec3;
+
+import java.awt.*;
+import java.util.ArrayList;
+
+public class ParallelPathfinder {
+
+    int lastDestX;
+    int lastDestY;
+
+    public void flood(int destX, int destY) {
+        System.out.println("[*] Flooding...");
+
+        lastDestX = destX;
+        lastDestY = destY;
+
+        SharedRessources
+                .getInstance()
+                .setExplorer(new Explorer(destX - 1, destY, 1));
+
+        SharedRessources
+                .getInstance()
+                .setExplorer(new Explorer(destX + 1, destY, 1));
+
+        SharedRessources
+                .getInstance()
+                .setExplorer(new Explorer(destX, destY - 1, 1));
+        SharedRessources
+                .getInstance()
+                .setExplorer(new Explorer(destX, destY + 1, 1));
+
+
+
+
+        SharedRessources.getInstance()
+                .set(destX - 1, destY, new Vec3(1, 0, 1));
+
+        SharedRessources.getInstance()
+                .set(destX + 1, destY, new Vec3(-1, 0, 1));
+
+        SharedRessources.getInstance()
+                .set(destX, destY - 1, new Vec3(0, +1, 1));
+
+        SharedRessources.getInstance()
+                .set(destX, destY + 1, new Vec3(0, -1, 1));
+
+
+        SharedRessources
+                .getInstance().start();
+
+    }
+
+    public ArrayList<Point> calculatePath(int startX, int startY, int destX, int destY) {
+        ArrayList<Point> path
+                = new ArrayList<>();
+
+        int x = startX;
+        int y = startY;
+
+        while (x != destX || y != destY) {
+
+            path.add(new Point(x, y));
+
+            Vec3 currentDir
+                    =
+                    SharedRessources.getInstance().getData(x, y);
+
+            int dx = (int) currentDir.getX();
+            int dy = (int) currentDir.getY();
+
+            if (dx == 0 && dy == 0)
+                return null;
+
+            x += dx;
+            y += dy;
+        }
+
+        System.out.println("Done.");
+
+        return path;
+    }
+
+    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 * 10, j * 10, 10, 10);
+                }
+                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, green, 0);
+
+                        g.setColor(color);
+
+                        g.fillRect(i * 10, j * 10, 10, 10);
+
+                        g.setColor(Color.red);
+                        g.drawLine(i * 10, j * 10, i * 10 + dx, j * 10 + dy);
+
+
+
+                    } else {
+                        g.setColor(Color.black);
+                        g.fillRect(i * 10, j * 10, 10, 10);
+                    }
+                }
+
+
+
+
+            }
+        }
+    }
+}
diff --git a/src/window/MainWindow.java b/src/window/MainWindowApproach1.java
similarity index 86%
rename from src/window/MainWindow.java
rename to src/window/MainWindowApproach1.java
index 3600393dad86563b6557548768d24de4e4927e22..8fb9460b2d65297f4be2e4b0dca7dda80eb9ff9c 100644
--- a/src/window/MainWindow.java
+++ b/src/window/MainWindowApproach1.java
@@ -1,19 +1,18 @@
 package window;
 
-import algorithm.ParallelPathfinder;
-import parallel.MapLoader;
-import parallel.SharedRessources;
+import approach1.algorithm.ParallelPathfinder;
+import approach1.parallel.MapLoader;
+import approach1.parallel.SharedRessources;
 
 import javax.imageio.ImageIO;
 import java.awt.*;
-import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 
-public class MainWindow extends Game {
-    public MainWindow(String title, int w, int h) {
+public class MainWindowApproach1 extends Game {
+    public MainWindowApproach1(String title, int w, int h) {
         super(title, w, h);
     }
 
diff --git a/src/window/MainWindowApproach2.java b/src/window/MainWindowApproach2.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1769c6c489c5dc32b006bddc1969d3e70ce4995
--- /dev/null
+++ b/src/window/MainWindowApproach2.java
@@ -0,0 +1,71 @@
+package window;
+
+import approach2.MapLoader;
+import approach2.SharedRessources;
+import approach2.algorithm.ParallelPathfinder;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class MainWindowApproach2 extends Game {
+    public MainWindowApproach2(String title, int w, int h) {
+        super(title, w, h);
+    }
+
+
+    ParallelPathfinder parallelPathfinder
+            = new ParallelPathfinder();
+
+    @Override
+    public void loadGame() {
+        SharedRessources.setMaximumCores(4);
+
+        try {
+            MapLoader.getDefault().load(ImageIO.read(new File("examples/maze.png")));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        parallelPathfinder.flood(80 ,80);
+
+
+    }
+
+
+    private boolean pressed;
+    ArrayList<Point> pts = new ArrayList<>();
+    @Override
+    public void updateGame() {
+
+        if (isMouseKeyDown(MouseEvent.BUTTON1) && !pressed) {
+            pts =
+                    parallelPathfinder.calculatePath(this.getMouseX() / 10, this.getMouseY() / 10, 80, 80);
+            pressed = true;
+        }
+
+        if (isMouseKeyUp(MouseEvent.BUTTON1))
+            pressed = false;
+
+    }
+
+    @Override
+    public void renderGame(Graphics g) {
+        parallelPathfinder.draw(g);
+
+
+
+        if (pts == null)
+            return;
+
+        g.setColor(Color.red);
+        for (var pt : pts) {
+            g.fillRect(pt.x * 10, pt.y * 10, 10, 10);
+        }
+    }
+
+
+}