yo una vez hize algo similar a lo que buscas:
las funciones que puedes hacer es generar numeros de al cuadrado de numero que tenga de largo la cuadricula (N). en este caso seria 3*3, Y guardarlo en una matriz que represente el rompezcabezas dejando el espacio mas grande de la matriz como 0.
algo como esto:
void generar_puzzle(int puzzle[N][N]){
int i,j,num;
num=1;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
puzzle[i][j]=num;
num++;
if(i==3 && j==3){
puzzle[i][j]=0;
}
}
}
}
luego seria otra funcion para intercambiar el espacio de la matriz que guarda el valor de 0 ya sea con el de la izquierda cambiando el valor de las matricez por el de una posicion antes, derecha con el de una posicion despues, de arriba con el de una posicion menos en el otro eje de la matriz y viceversa para abajo de acuerdo a una entrada hecha por el teclado de acuerdo al codigo ascii.(tambien hay que tomar en cuenta las excepciones, ya que no puede subir uno el espacio vacio una casilla mas si esta se encuentra en la fila de hasta arriba por ejemplo)
el siguiente paso, serìa una funciòn para desordenar el puzzle para que no empiece resuelto, llamando la funcion anterior de intercambiar los valores de las matrices una cantidad determinada por un ciclo, y que seleccione cualquiera de las 4 opciones (arriba, abajo, izquierda, derecha) de manera aleatoria.
lo que restaria es imprimir la matriz en pantalla en el orden que se ha estado trabajando mediante dos for
void imprimir(int puzzle[N][N]){
int i,j;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
if(puzzle[i][j]==0)
printf(" |");
else
printf("%3d |",puzzle[i][j]);
}
printf("\n");
if(i<N-1)
printf("\t\t\t ------+-----+-----+------\n");
}
}
asi quedaria la impresion mas o menos con una cuadricula
por ultimo serìa una funciòn que detectara cuando el puzzle esta ordenado, para indicar que se ha trerminado el juego.
espero que te sirva.