Solución a la Tarea 6: Buscaminas

Había al menos dos formas de resolver esta tarea. En la primera, que es más difícil, se deben estudiar casos especiales para las casillas del tablero que están en las orillas y en las esquinas. En la segunda, que es más ingeniosa, simplemente se agregan dos renglones y dos columnas vacíos alrededor del tablero para evitar todos los casos especiales. Esto es lo que hacemos en el programa que muestro abajo. Observe que usamos dos funciones vistas en clase (lee y escribe, aunque lee tiene una modificación para agregar los renglones y columnas). La función calcula es más interesante, puesto que separa sólamente dos casos: hay o no hay mina. En el primer caso simplemente pone un 9 en el segundo tablero (piense: ¿porqué es mejor tener una segunda matriz en lugar de hacer todas las operaciones en sólo una matriz?) mientras que en el segundo cuenta cuántas minas hay alrededor de la posición vacía. ¿Cómo evitamos contabilizar ésta posición? ¿Era realmente necesario hacer esto?

#include <stdio.h>
 
#define M 22
 
void lee(int m, int n, int a[M][M])
{
  int i, j;
 
  for (i = 1; i <= m; i++)
    for (j = 1; j <= n; j++)
      scanf("%d", &a[i][j]);
  for (i = 0; i <= m+1; i++)
    a[i][0] = a[i][n+1] = 0;
  for (j = 0; j <= n+1; j++)
    a[0][j] = a[m+1][j] = 0;
}
 
void calcula(int m, int n, int a[M][M], int b[M][M])
{
  int h, i, j, k, t;
 
  for (i = 1; i <= m; i++)
    for (j = 1; j <= n; j++)
      if (a[i][j])
        b[i][j] = 9;
      else {
        t = 0;
        for (h = i-1; h <= i+1; h++)
          for (k = j-1; k <= j+1; k++)
            if ((h != i || k != j) && a[h][k])
              t++;
        b[i][j] = t;
      }
}
 
void escribe(int m, int n, int b[M][M])
{
  int i, j;
 
  for (i = 1; i <= m; i++) {
    for (j = 1; j <= n; j++)
      printf("%d ", b[i][j]);
    printf("\n");
  }
}
 
int main(void)
{
  int m, n;
  int a[M][M], b[M][M];
 
  scanf("%d%d", &m, &n);
  lee(m, n, a);
  calcula(m, n, a, b);
  escribe(m, n, b);
  return 0;
}

Los valores de entrada y salida empleados para la evaluación fueron los siguientes (cada entrada arriba de su salida correspondiente):

1 1
1
1 1
0
2 2
0 0
1 0
2 4
0 1 0 0
0 1 0 0
4 2
0 0
1 0
0 1
0 0
9
0
1 1
9 1
2 9 2 0
2 9 2 0
1 1
9 2
2 9
1 1
4 4
0 0 1 0
1 0 0 1
0 0 0 0
0 0 1 0
4 8
0 0 0 0 1 0 1 0
0 0 0 0 0 0 0 0
0 1 1 0 0 1 0 0
0 0 0 0 0 0 0 0
8 4
0 0 1 0
0 0 0 0
0 0 0 0
0 0 0 0
1 0 0 1
1 0 0 0
0 0 0 0
0 0 0 0
8 8
0 1 0 0 0 1 0 0
0 0 1 0 0 1 0 0
0 0 0 0 0 0 0 1
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0
1 0 1 0 0 0 0 1
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
8 8
0 0 1 1 0 1 0 1
1 1 0 0 0 1 1 0
0 1 1 1 1 1 0 0
1 1 0 1 1 1 0 0
0 0 1 1 0 0 1 0
0 1 0 1 1 0 1 1
0 1 1 0 1 0 0 0
1 1 0 1 1 1 0 0
1 2 9 2
9 2 2 9
1 2 2 2
0 1 9 1
0 0 0 1 9 2 9 1
1 2 2 2 2 3 2 1
1 9 9 1 1 9 1 0
1 2 2 1 1 1 1 0
0 1 9 1
0 1 1 1
0 0 0 0
1 1 1 1
9 2 1 9
9 2 1 1
1 1 0 0
0 0 0 0
1 9 2 1 2 9 2 0
1 2 9 1 2 9 3 1
0 1 1 2 2 2 2 9
0 0 0 1 9 1 1 1
1 2 1 2 1 1 1 1
9 3 9 1 0 0 1 9
9 3 1 1 0 0 1 1
1 1 0 0 0 0 0 0
2 3 9 9 3 9 4 9
9 9 6 5 6 9 9 2
5 9 9 9 9 9 4 1
9 9 7 9 9 9 3 1
3 4 9 9 6 5 9 3
2 9 6 9 9 4 9 9
4 9 9 6 9 5 3 2
9 9 4 9 9 9 1 0

Para probar su tarea en UNIX, escriban la instrucción gcc bminasNN.c -o bminas para compilar su programa, y la instrucción ./bminas para correrlo. Algunos errores comúnes fueron: (a) No considerar las orillas del tablero como casos especiales. (b) Hacer las modificaciones directamente sobre la misma matriz en donde leyeron el tablero.