@Override
 public boolean onTouchEvent(MotionEvent event) {
   if (animation == null && puzzleBoard != null) {
     switch (event.getAction()) {
       case MotionEvent.ACTION_DOWN:
         if (puzzleBoard.click(event.getX(), event.getY())) {
           invalidate();
           if (puzzleBoard.resolved()) {
             Toast toast = Toast.makeText(activity, "Congratulations!", Toast.LENGTH_LONG);
             toast.show();
           }
           return true;
         }
     }
   }
   return super.onTouchEvent(event);
 }
  public void solve() {
    PriorityQueue<PuzzleBoard> queue =
        new PriorityQueue<>(
            1000,
            new Comparator<PuzzleBoard>() {
              @Override
              public int compare(PuzzleBoard lhs, PuzzleBoard rhs) {
                return lhs.priority() - rhs.priority();
              }
            });

    PuzzleBoard currBoard = new PuzzleBoard(puzzleBoard);
    currBoard.initializePreviousBoard();

    queue.add(currBoard);

    while (!queue.isEmpty()) {
      currBoard = queue.poll();
      if (currBoard.resolved()) {
        ArrayList<PuzzleBoard> arrayList = new ArrayList();

        while (currBoard.getPreviousBoard() != null) {
          arrayList.add(currBoard);
          currBoard = currBoard.getPreviousBoard();
        }
        Collections.reverse(arrayList);

        animation = new ArrayList<>();
        animation.addAll(arrayList);
        invalidate();
        break;
      } else {
        queue.addAll(currBoard.neighbours());
      }
    }
  }