/**
  * Gets the tiles that need to be deleted due to the detonating of the flame gem.
  *
  * @param tile the flame gem
  * @return tiles, the list of tiles to be deleted.
  */
 public List<Tile> getTilesToDeleteFlame(Tile tile) {
   final Point[] translations = {
     new Point(-1, 0),
     new Point(1, 1),
     new Point(0, 1),
     new Point(-1, 1),
     new Point(1, 0),
     new Point(-1, -1),
     new Point(0, -1),
     new Point(1, -1)
   };
   tile.detonate = true;
   List<Tile> tiles =
       Arrays.stream(translations)
           .map(p -> new Point(tile.getX() + p.x, tile.getY() + p.y))
           .filter(p -> board.validBorders(p.x, p.y))
           .map(p -> board.getTileAt(p.x, p.y))
           .filter(t -> !t.detonate)
           .collect(Collectors.toList());
   checkForSpecialTile(tiles);
   if (!tiles.contains(tile)) {
     tiles.add(tile);
   }
   return tiles;
 }
 /**
  * Add tile to swapTiles based on location from the mouseEvent.
  *
  * @param loc location of tile
  */
 public void addTile(Point loc) {
   int col = loc.x;
   int row = loc.y;
   if (!swapTiles.contains(board.getTileAt(col, row))) {
     swapTiles.add(board.getTileAt(col, row));
     main.setFocus(loc);
     if (swapTiles.size() == 2 && canSwap()) {
       swapTiles(swapTiles);
       swapTiles.clear();
     }
   }
 }
  /**
   * Switch tile t0 and t1 on the board.
   *
   * @param t0 first tile to swap
   * @param t1 second tile to swap
   */
  public void swappedTiles(Tile t0, Tile t1) {
    Tile temp = board.getTileAt(t0.getX(), t0.getY());
    board.setTileAt(board.getTileAt(t1.getX(), t1.getY()), t0.getX(), t0.getY());
    board.setTileAt(temp, t1.getX(), t1.getY());

    int xc = t0.getX();
    int yc = t0.getY();
    t0.setLoc(t1.getX(), t1.getY());
    t1.setLoc(xc, yc);

    swappedTiles[0] = t0;
    swappedTiles[1] = t1;
  }
  /**
   * Gets the tiles that need to be deleted due to the detonating of the hypercube gem.
   *
   * @param t1 the hypercube gem
   * @return tiles, the list of tiles to be deleted.
   */
  public List<Tile> getTilesToDeleteHypercube(Tile t1, Tile hyper) {
    List<Tile> tiles = new ArrayList<Tile>();
    tiles.add(hyper);
    hyper.detonate = true;
    int index = t1.getIndex();

    Tile tempTile = null;
    for (int row = 0; row < board.getWidth(); row++) { // loop through board
      for (int col = 0; col < board.getHeight(); col++) {
        tempTile = board.getTileAt(row, col);
        if (index == tempTile.getIndex() && !tempTile.detonate) {
          // add tile tile if colors are the same
          tiles.add(tempTile);
        }
      }
    }
    return tiles;
  }
  /** Swap two tiles if it result in a sequence of 3 of more tiles with the same color. */
  public boolean canSwap() {
    Tile t0 = board.getTileAt(swapTiles.get(0).getX(), swapTiles.get(0).getY());
    Tile t1 = board.getTileAt(swapTiles.get(1).getX(), swapTiles.get(1).getY());

    if (t0 instanceof HypercubeTile || t1 instanceof HypercubeTile) {
      return true;
    }

    if (!createsCombination(t0, t1)) {
      return false;
    }

    if (!isNeighbour(t0, t1)) {
      Logger.error("t0 and t1 are not neighbours.");
      return false;
    }
    return true;
  }
  /**
   * Gets the tiles that need to be deleted due to the detonating of the hypercube gem.
   *
   * @param tile the hypercube gem
   * @return tiles, the list of tiles to be deleted.
   */
  public List<Tile> getTilesToDeleteStar(Tile tile) {
    List<Tile> tiles = new ArrayList<Tile>();
    tile.detonate = true;
    tiles.add(tile);

    int tx = tile.getX();
    int ty = tile.getY();
    for (int col = 0; col < board.getHeight(); col++) {
      if (col != tx && !board.getTileAt(col, ty).detonate) {
        tiles.add(board.getTileAt(col, ty));
      }
    }
    for (int row = 0; row < board.getWidth(); row++) {
      if (row != ty && !board.getTileAt(tx, row).detonate) {
        tiles.add(board.getTileAt(tx, row));
      }
    }
    checkForSpecialTile(tiles);
    return tiles;
  }