private void updateTileButtons(Turn turn) {
    if (turn == null || turn instanceof Pass)
      throw new IllegalArgumentException("Turn can't be null or a pass");

    if (turn instanceof Flip) {
      Flip flip = (Flip) turn;
      TileButton flipped = tileButtons[flip.getX()][flip.getY()];
      flipped.setIcon(flipped.getIcon());
    }
    else {
      // A tile was moved
      Move move = (Move) turn;
      TileButton from = tileButtons[move.getFromX()][move.getFromY()];
      TileButton to = null;  // assume off-board
      if (!(move instanceof Rescue)) {
        to = tileButtons[move.getToX()][move.getToY()];
      }
      
      if (gameFrame.playTileNoises()) {
        // Make the noise for the moving tile
        from.playSound(to != null && to.getTile() != null);
      }
      
      // Update the "to" square (if any) to contain the moving tile
      if (to != null) {
        // Make the captured tile's sound, if any
        if (gameFrame.playTileNoises() && to.getTile() != null)
          to.playCapturedSound();
        to.setTile(from.getTile());
      }
      
      // Empty the "from" square where the capturing tile was
      from.setTile(null);
    }

    // Clear any currently selected tile button
    selectButton(null);
    
    validate();
    paintAll(getGraphics());
  }