public boolean moveUp() {
		
		// Block invalid moves
		if (!canMoveUp)
			return false;
		
		boolean result = false;
		for (int j = 0; j < dim; j++) {
			for (int i = 1; i < dim; i++) {	// Can skip the top most row
				
				// Skip empty tiles
				if (isTileEmpty(i, j))
					continue;
				
				// Stepping indices
				int k = i;
				
				// Slide this value as far up as it will go
				while (isValidLocation(k - 1, j) && isTileEmpty(k - 1, j) && moveTileUp(k, j)) {
					k--;
					result = true;
				}
				
				// If the tile came to rest below a tile with the 
				// same value, nullify it
				if (canTilesMerge(k, j, k - 1, j)) {
					mergeUp(k, j);
					result = true;
				}
			}
		}
		return result;
	}