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.