public boolean moveDown() {
		
		// Block invalid moves
		if (!canMoveDown)
			return false;
		
		boolean result = false;
		for (int j = 0; j < dim; j++) {
			for (int i = dim-2; i >= 0; i--) {	// Can skip the bottom most row
				
				// Skip empty tiles
				if (isTileEmpty(i, j))
					continue;
				
				// Stepping indices
				int k = i;
				
				// Slide this value as far down as it will go
				while (isValidLocation(k + 1, j) && isTileEmpty(k + 1, j) && moveTileDown(k, j)) {
					k++;
					result = true;
				}
				
				// If the tile came to rest above a tile with the 
				// same value, nullify it
				if (canTilesMerge(k, j, k + 1, j)) {
					mergeDown(k, j);
					result = true;
				}
			}
		}
		return result;
	}