public List<Cell> exploreWay(Cell [][]cells, int xStart, int yStart, int xGoal, int yGoal) { // A* alogoritm
    List<Cell> openset = new ArrayList<Cell>(); // will explore
    List<Cell> closeset = new ArrayList<Cell>(); // was explored
    int tentativeScore;
    boolean tentetiveIsBetter;
    List<Cell> pathMap = new ArrayList<Cell>();
    openset.add(cells[xStart][yStart]);
    cells[xStart][yStart].setCostWay(0);
    cells[xStart][yStart].setHeuristicCostEstimate(heruisticCostEstimate(xStart, yStart, xGoal, yGoal));
    cells[xStart][yStart].setValueWay((int) (cells[xStart][yStart].getHeuristicCostEstimate() + cells[xStart][yStart]
        .getCostWay()));

    while (openset.size() != 0) {
      Cell cell = Collections.min(openset, new Comparator<Cell>() {

        public int compare(Cell o1, Cell o2) {
          return ((Integer) o1.getValueWay()).compareTo(o2.getValueWay());
        }
      });

      if (cell.getxCoordinate() == xGoal && cell.getyCoordinate() == yGoal) {
        return pathMap;
      }

      openset.remove(cell);
      closeset.add(cell);
      for (Cell neightbourCell : neighbors(cells, cell)) {
        if (closeset.contains(neightbourCell)) {
          continue;
        }
        tentativeScore = cell.getCostWay() + distance;

        if (!openset.contains(neightbourCell)) {
          openset.add(neightbourCell);
          tentetiveIsBetter = true;
        } else {
          if (tentativeScore < neightbourCell.getCostWay()) {
            tentetiveIsBetter = true;
          } else
            tentetiveIsBetter = false;
        }

        if (tentetiveIsBetter) {
          pathMap.add(cell);
          neightbourCell.setCostWay(tentativeScore);
          neightbourCell.setHeuristicCostEstimate(heruisticCostEstimate(neightbourCell.getxCoordinate(),
              neightbourCell.getyCoordinate(), xGoal, yGoal));
          neightbourCell.setValueWay((int) (neightbourCell.getCostWay() + neightbourCell.getHeuristicCostEstimate()));
        }
      }
    }

    return null;
  }