@Override
    public List<Point> startPathfinder(boolean diagonalAllowed) {
        ArrayList<MazeCell> closedSet = new ArrayList<>();
        ArrayList<MazeCell> openSet = new ArrayList<>();
        openSet.add(start);
        ArrayList<MazeCell> pathMap = new ArrayList<>();

        while (!openSet.isEmpty()) {
            MazeCell min = getMinF(openSet);
            if (min.equals(goal)) {
                return reconstructPath(start, goal);
            }

            openSet.remove(min);
            closedSet.add(min);
            List<MazeCell> ngbr = getNeighbourNodes(min, diagonalAllowed);
            Iterator<MazeCell> iter = ngbr.iterator();
            boolean tentativeIsBetter = false;
            while (iter.hasNext()) {
                MazeCell cr = iter.next();
                if (!closedSet.contains(cr)) {
                    double tentativeGscore = min.getG() + distance(min, cr);
                    if (!openSet.contains(cr)) {
                        openSet.add(cr);
                        tentativeIsBetter = true;
                    } else {
                        if (tentativeGscore < cr.getG()) {
                            tentativeIsBetter = true;
                        } else {
                            tentativeIsBetter = false;
                        }
                    }

                    if (tentativeIsBetter) {
                        cr.setCameFrom(min);
                        cr.setG(tentativeGscore);
                        cr.setH(distance(cr, goal));
                        cr.setF(cr.getG() + cr.getH());
                    }
                }
            }
        }
        return null;
    }