buscaminas en c++ [Solucionado]
Hola, estoy haciendo el programita del buscaminas para C++, compila y funciona bién, pero al terminar, al salir del método main me da error de segmentación, por lo que sé debe ser un error al liberar la memoria, no se me ocurre otra. Pero sigo sin entenderlo, a ver si alguien me puede explicar qué ocurre (El programa está pensado para ejecutar bajo consola win32, desarrollado con el editor CodeBlocks):
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <cstdlib>
#include <unistd.h>
#include <ctype.h>
using namespace std;
struct Tshell{
int x;
int y;
int n; //nomber of bombs for the neighbors
bool bomb;
bool display;
bool mark;
};
struct Ttable{
int n_bombs;
int hight;
int width;
struct Tshell** v;
int bombsDisc;
};
void DrawnTable(struct Ttable table)
{
int k;
system("cls");
cout<<" ";
for(k=0;k<table.width;k++)
cout<<k+1<<" ";
cout<<endl<<" ";
for (k=0;k<table.width*2-1;k++)
cout<<"-";
cout<<endl;
for(int i=0;i<table.hight; i++)
{
if(i<9)
cout<<" ";
cout<<i+1<<" |";
for(int j=0; j<table.width; j++){
if(table.v[j][i].display==true)
cout<<table.v[j][i].n;
else{
if(table.v[j][i].mark==true)
cout<<"M";
else
cout<<" ";
}
cout<<"|";
}
cout<<endl;
}
cout<<" ";
for (int k=0;k<table.width*2-1;k++)
cout<<"-";
cout<<endl;
int n=table.n_bombs-table.bombsDisc;
cout<<"Bombs remaining: "<<n<<endl;
}
void Mark(struct Ttable &table, char* in)
{
int x,y;
table.bombsDisc++;
char * inn=&in[1];
char *aux;
aux=strtok(inn,"-");
x = atoi(aux);
aux=strtok(NULL,"-");
y = atoi(aux);
//cout<<x<<" "<<y<<in<<endl;
if(table.v[x-1][y-1].mark==false)
table.v[x-1][y-1].mark=true;
else{
table.v[x-1][y-1].mark=false;
table.bombsDisc--;
}
}
void Explote(struct Ttable table,int x, int y)
{
//set the self shell to display
table.v[x][y].display=true;
//Exploting left side
if(x>0)
{
if(table.v[x-1][y].n==0 && table.v[x-1][y].display==false)
Explote(table, x-1, y);
else
table.v[x-1][y].display=true;
}
//Exploting right side
if(x<table.width-1)
{
if(table.v[x+1][y].n==0 && table.v[x+1][y].display==false)
Explote(table, x+1, y);
else
table.v[x+1][y].display=true;
}
//Exploting up side
if(y>0)
{
if(table.v[x][y-1].n==0 && table.v[x][y-1].display==false)
Explote(table, x, y-1);
else
table.v[x][y-1].display=true;
}
//Exploting down side
if(y<table.hight-1)
{
if(table.v[x][y+1].n==0 && table.v[x][y+1].display==false)
Explote(table, x, y+1);
else
table.v[x][y+1].display=true;
}
//Exploting left-up side
if(x>0 && y>0)
{
if(table.v[x-1][y-1].n==0 && table.v[x-1][y-1].display==false)
Explote(table, x-1, y-1);
else
table.v[x-1][y-1].display=true;
}
//Exploting right-up side
if(x<table.width-1 && y>0)
{
if(table.v[x+1][y-1].n==0 && table.v[x+1][y-1].display==false)
Explote(table, x+1, y-1);
else
table.v[x+1][y-1].display=true;
}
//Exploting right-down side
if(x<table.width-1 && y<table.hight-1)
{
if(table.v[x+1][y+1].n==0 && table.v[x+1][y+1].display==false)
Explote(table, x+1, y+1);
else
table.v[x+1][y+1].display=true;
}
//Exploting left-down side
if(x>0 && y<table.hight-1)
{
if(table.v[x-1][y+1].n==0 && table.v[x-1][y+1].display==false)
Explote(table, x-1, y+1);
else
table.v[x-1][y+1].display=true;
}
}
bool Discover(struct Ttable table, char* in)
{
bool ret=false;
int x,y;
char * inn=&in[1];
x = atoi(strtok(inn,"-"));
y = atoi(strtok(NULL,"-"));
x--;y--;
//first check if the shell contains a bomb
if(table.v[x][y].bomb==true)
{
cout<<"Booom! Game Over, try again"<<endl;
ret=true;
}else{
table.v[x][y].display=true;
if(table.v[x][y].n==0)
{
Explote(table,x,y);
}
}
return ret;
}
void Destructor(struct Ttable table)
{
for(int i=0;i<table.width;i++){
delete table.v[i];
table.v[i]=NULL;
}
delete table.v;
table.v=NULL;
}
void setNumberOfBombs(struct Ttable table)
{
int i,j,bombs=0;
for(i=0;i<table.width;i++)
{
for(j=0;j<table.hight;j++)
{
//bombs=0;
if(!table.v[i][j].bomb)
{
//check for the upper shell
if(i>0)
{
if(table.v[i-1][j].bomb==true)
bombs++;
}
//check for the downer shell
if(i<table.hight-1)
{
if(table.v[i+1][j].bomb==true)
bombs++;
}
//check for the left shell
if(j>0)
{
if(table.v[i][j-1].bomb==true)
bombs++;
}
//check for the right shell
if(j<table.width-1)
{
if(table.v[i][j+1].bomb==true)
bombs++;
}
//check for the up-left shell
if(j>0 && i>0)
{
if(table.v[i-1][j-1].bomb==true)
bombs++;
}
//check for up-right shell
if(i>0 && j<table.width-1)
{
if(table.v[i-1][j+1].bomb)
bombs++;
}
//check for the down-left shell
if(i<table.hight-1 && j>0)
{
if(table.v[i+1][j-1].bomb)
bombs++;
}
//check for the down-right shell
if(i<table.hight-1 && j<table.width-1)
{
if(table.v[i+1][j+1].bomb)
bombs++;
}
table.v[i][j].n=bombs;
bombs=0;
}
}
}
}
void Configure(struct Ttable &table)
{
// argv[1]=="-c"){
cout<<"Hight:";
cin>>table.hight;
cout<<endl<<"Width:";
cin>>table.width;
cout<<endl<<"Number of bombs:";
cin>>table.n_bombs;
cout<<endl;
}
void Init(struct Ttable &table)
{
int w,h;
table.bombsDisc=0;
w=table.width;
h=table.hight;
table.v = new struct Tshell* [w];
for(int i=0;i<w;i++)
table.v[i]=new struct Tshell[h];
for(int i=0; i<table.width; i++)
{
for(int j=0; j<table.hight; j++)
{
table.v[i][j].x=i;
table.v[i][j].y=j;
table.v[i][j].n=0;
table.v[i][j].mark=false;
table.v[i][j].bomb=false;
table.v[i][j].display=false;
}
}
//set the random bombs
int x,y;
for(int i=0; i<table.n_bombs; i++){
x= rand()%table.width;
y= rand()%table.hight;
table.v[x][y].bomb=true;
}
}
bool IsNumber(const char* s)
{
for (int i = 0; i < strlen(s); i++) {
if (!isdigit(s[i]))
return false;
}
return true;
}
bool Check(struct Ttable table,char* in)
{
char * inn=&in[1];
bool ret=false;
char* aux;
int x,y;
aux = strtok(inn,"-");
if(!strcmp(in,"conf") || !strcmp(in,"Conf"))//"in=="conf" || in=="Conf")
return true;
if(aux!="" && IsNumber(aux))
{
x = atoi(aux);
aux=strtok(NULL,"- ");
if(aux!="" && IsNumber(aux))
{
y = atoi(aux);
if(x<=table.width && y<=table.hight)
ret = true;
}
}
return ret;
}
bool Win(struct Ttable table)
{
bool ret = true;
for(int i=0;i<table.width;i++)
{
for(int j=0;j<table.hight;j++)
{
if (!(table.v[i][j].display==true || (table.v[i][j].display=false && table.v[i][j].mark==true)))
ret=false;
}
}
if(ret && table.bombsDisc==table.n_bombs)
{
ret =true;
}else
ret = false;
return ret;
}
int main(int argc, char** argv){
//introduction to the game
cout<<"-----------------MiNeSwEePeR-----------------"<<endl;
cout<<"Instructions: X and Y are the coordenates for the table game shells"<<endl<<
" For pick(discover) a shell use dX-Y"<<endl<<
" For mark a shell use mX-Y"<<endl<<"Press Enter to continue"<<endl;
cin.get();
//srand(time(0)); //for set the random function
struct Ttable table = {10,9,9};
if(argc>2){
cout<<"Invalid number of input parameters."<<endl;
return 0;
}
if(argv[1]=="--conf"){
Configure(table);
}
//Initialiting the seed
srand (time(NULL));
//srand((unsigned)getpid());
//Initialiting the shells of the table
Init(table);
//set the nomber of neightbores shells with bombs for each shell
setNumberOfBombs(table);
DrawnTable(table);
//The game starts
char* in;char aux[10];
bool checked=false;
// bool gameOver=true;
while(true)
{
checked=false;
cout<<"Input: "<<endl;
cin>>in;
strcpy(aux,in);
if(Check(table,aux))
checked=true;
if(checked && (in[0]=='d' || in[0]=='D')) //discover shell
{
if(Discover(table,in)){ //if the user picks in a boomb halt game
Destructor(table);
system("pause");
return 0;
}
}
else{
if(checked &&(in[0]=='m' || in[0]=='M')) //mark shell
Mark(table,in);
else
{
if(!strcmp(in,"conf") || !strcmp(in,"Conf"))
{
Destructor(table);
Configure(table);
Init(table);
//set the nomber of neightbores shells with bombs for each shell
setNumberOfBombs(table);
}
else
cout<<endl<<endl<<"Invalid option. Retry"<<endl<<endl;
}
}
DrawnTable(table);
if(Win(table))
{
cout<<"Finished! You win."<<endl;
system("pause");
return 0;
}
}
}
- Inicie sesión o regístrese para enviar comentarios
- 1356 lecturas


¿Ocurre siempre? ¿Cuando ganas, cuando has marcado una casilla, o no has marcado ninguna? Pon el error que te muestra.
¿entiendo que quieres que te ayudemos con un programa para windows y que está en inglés encima?
--> Esdebian. La mayor comunidad de Debian en español
¿entiendo que quieres que te ayudemos con un programa para windows y que está en inglés encima?
--> Esdebian. La mayor comunidad de Debian en español
Será para usarlo con wine, que mal pensado eres
jajajaja, gracias por el capote pero sinceramente es para ejecutarlo desde güindows, aunque no por gusto, obviamente es mucho más cómodo desarrollar en c/c++/java desde linux. De todas formas este apartado trata sobre programación en c++ no?
No, no ocurre siempre, al marcar, descubrir casilla...en el desarrollo del juego en general funciona perfectamente.
Ocurre siempre que finalices,ya ganes, pierdas o cierres la aplicación. Depurando línea a línea llego hasta el final, al salir del main, al salir del último corchete, de ahí que piense a que se debe a algún tipo de destructor que debe invocar automáticamente.
Ahí va el ***** error:
Process returned -1073741819 (0xC0000005) execution time: 19,950sEn modo depuración se ve el sementation fault:
Setting breakpointsDebugger name and version: GNU gdb 6.8
Child process PID: 5200
Program received signal SIGSEGV, Segmentation fault.
In ?? () ()
Lo del inglés no creo que sea para tanto, son cuatro palabrejas. Table: tablero, sheel: casilla, bomb: bomba... de todas formas mis disculpas a quién le suponga un inconveniente :)
Ya lo tengo!! Alguna tontería tenía que ser, no le veía el sentido por ningún lado.
Resulta que inicializaba la variable "in" como
char *in;//para luego utilizarla sin un tamaño especifico
cin>>in;
En el momento en que la he inicializado con una longitud determinada me ha dejado de dar problemas
char in[10];Y todo el tiempecito que me he tirado........ es ley de vida :P
Ya lo tengo!! Alguna tontería tenía que ser, no le veía el sentido por ningún lado.
Resulta que inicializaba la variable "in" como
char *in;//para luego utilizarla sin un tamaño especifico
cin>>in;
En el momento en que la he inicializado con una longitud determinada me ha dejado de dar problemas
char in[10];Y todo el tiempecito que me he tirado........ es ley de vida :P
Pues marcalo como solucionado.