这将是一个扫雷但尚未完成。目前,该程序应该询问您阵列的大小和地雷数量。然后,它显示隐藏的板(带有数字和X'作为地雷的板)。这就是全部。
问题是程序停止使用此错误
进程返回-1073741819< 0xC0000005>
我认为这是一个记忆问题,但我不知道问题出在哪里。
很抱歉,因为评论是西班牙语。我会尝试添加一些大写字母以使其可以理解。代码:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "Tablero/tablero.h"
#include <stdbool.h>
int main()
{
int fils, cols, nMinas; //ROWS, COLUMNS, NUMBER OF MINES
printf("Introduzca el número de filas: ");
scanf("%d", &fils);
printf("Introduzca el número de columna: ");
scanf("%d", &cols);
printf("Introduzca el número de minas: ");
scanf("%d", &nMinas);
Tablero tab = crearTablero(fils, cols, nMinas);//CREATE BOARD
mostrarTablero(tab.tabOculto, tab.x, tab.y);//SHOW HIDDEN BOARD
liberarTablero(tab);//FREE THE MEMORY
return 0;
}
tablero.h
#ifndef TABLERO_H_INCLUDED
#define TABLERO_H_INCLUDED
typedef struct{
int x;//ROWS
int y;//COLUMNS
int numMinas;//NUMBER OF MINES
char **tabOculto;//HIDDEN BOARD
char **tabVisible;//VISIBLE BOARD
} Tablero;
Tablero crearTablero(int x, int y, int numMinas);//CREATE BOARD
void mostrarTablero(char **tab, int x, int y);//SHOW BOARD
void liberarTablero(Tablero tab);//FREE BOARD
#endif // TABLERO_H_INCLUDED
tablero.c
#include "tablero.h"
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
//CREATE BOARD
Tablero crearTablero(int x, int y, int numMinas){
Tablero tab;
tab.x = x;//ROWS
tab.y = y;//COLUMNS
tab.numMinas = numMinas;//NUMBER OF MINES
int i, j, k, l;
//Iniciamos y establecemos el contenido del tablero que se va a ver por consola
//INITIATE AND ESTABLISH THE CONTENT OF THE VISIBLE BOARD
tab.tabVisible = (char**) malloc (x * sizeof(char*));
for(i = 0; i < x; i++)
tab.tabVisible[i] = (char*) malloc (y * sizeof(char));
//Rellenamos con asteriscos para marcar la casilla normal
for(i = 0; i < x; i++)
for(j = 0; j < y; j++)
tab.tabVisible[i][j] = '*';
//Iniciamos y establecemos el contenido del tablero oculto, que se irá identificando
//INITIATE AND ESTABLISH THE CONTENT OF THE HIDDEN BOARD
tab.tabOculto = (char**) malloc (x * sizeof(char*));
for(i = 0; i < x; i++)
tab.tabOculto[i] = (char*) malloc (y * sizeof(char));
//Rellenamos con ceros antes de distribuir minas
//FIRST, FILL EVERYTHING WITH '0'
for(i = 0; i < x; i++)
for(j = 0; j < y; j++)
tab.tabOculto[i][j] = '0';
//Introducimos las minas aleatoriamente
//ESTABLISH RANDOM MINE POSITION
srand(time(NULL));
for(i = 0; i < tab.numMinas; i++)
tab.tabOculto[(int)rand() % x][(int)rand() % y] = 'X';
//Ponemos los números según las minas que tengan alrededor
//PUT THE NUMBERS DEPENDING ON THE QUANTITY OF MINES AROUND AND THE POSITION
for(i = 0; i < x; i++)
for(j = 0; j < y; j++)
if(tab.tabOculto[i][j] == 'X'){
//Esquina superior izquierda: de posx, posy a posx+1, posy+1
if(i == 0 && j == 0){
for(k = i; k <= i+1; k++)
for(l = j; l <= j+1; l++)
if(tab.tabOculto[k][l] != 'X')
tab.tabOculto[k][l]++;
}
//Esquina superior derecha: de posx, posy-1 a posx+1, posy
else if(i == 0 && j == y){
for(k = i; k <= i+1; k++)
for(l = j-1; l <= j; l++)
if(tab.tabOculto[k][l] != 'X')
tab.tabOculto[k][l]++;
}
//Esquina inferior izquierda: de posx-1, posy a posx, posy+1
else if(i == x && j == 0){
for(k = i-1; k <= i; k++)
for(l = j; l <= j+1; l++)
if(tab.tabOculto[k][l] != 'X')
tab.tabOculto[k][l]++;
}
//Esquina inferior derecha: de posx-1, posy-1 a posx, posy
else if(i == x && j == y){
for(k = i-1; k <= i; k++)
for(l = j-1; l <= j; l++)
if(tab.tabOculto[k][l] != 'X')
tab.tabOculto[k][l]++;
}
//Borde superior: de posx, posy-1 a posx+1, posy+1
else if(i == 0){
for(k = i; k <= i+1; k++)
for(l = j-1; l <= j+1; l++)
if(tab.tabOculto[k][l] != 'X')
tab.tabOculto[k][l]++;
}
//Borde inferior: de posx-1, posy-1 a posx, posy+1
else if(i == x){
for(k = i-1; k <= i; k++)
for(l = j-1; l <= j+1; l++)
if(tab.tabOculto[k][l] != 'X')
tab.tabOculto[k][l]++;
}
//Borde izquierdo: de posx-1, posy a posx+1, posy+1
else if(j == 0){
for(k = i-1; k <= i+1; k++)
for(l = j; l <= j+1; l++)
if(tab.tabOculto[k][l] != 'X')
tab.tabOculto[k][l]++;
}
//Borde derecho: de posx-1, posy-1 a posx+1, posy
else if(j == y){
for(k = i-1; k <= i+1; k++)
for(l = j-1; l <= j; l++)
if(tab.tabOculto[k][l] != 'X')
tab.tabOculto[k][l]++;
}
//Sin borde: de posx-1, posy-1 a posx+1, posy+1
else{
for(k = i-1; k <= i+1; k++)
for(l = j-1; l <= j+1; l++)
if(tab.tabOculto[k][l] != 'X')
tab.tabOculto[k][l]++;
}
}
return tab;
}
//SHOW BOARD
void mostrarTablero(char **tab, int x, int y){
int i, j;
for(i = 0; i < x; i++){
for(j = 0; j < y; j++)
printf(" %c ", tab[i][j]);
printf("\n");
}
}
//FREE BOARD
void liberarTablero(Tablero tab){
//liberamos la memoria reservada a los arrays
int i;
for(i = 0; i < tab.x; i++){
free(tab.tabOculto[i]);
free(tab.tabVisible[i]);
}
free(tab.tabOculto);
free(tab.tabVisible);
}
答案 0 :(得分:0)
当您确定何时处于右边界或下边界时,您只有一次:
if (j == y)
这不可能,因为它发生在条件为j < y
的循环中。永远不会输入右边和右边边框情况,您最终会访问j + 1
和i + 1
处的字段,这是数组之外的一个条目。
您根本不需要区分这些案例。大小写确定要扫描的邻近区域的边界,但是您可以通过简单的计算来完成,然后在边界上调整范围:
int jmin = j - 1;
int jmax = j + 1;
if (j == 0) jmin = 0;
if (jmax == y) jmax = y - 1;
同样适用于i
。这将消除大量重复的代码。