Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Miketo

Funciona do Ubuntu. No Windows compila mas depois da erro ....

Mensagens Recomendadas

Miketo

Boas pessoal. O problema é o seguinte. Eu fiz este jogo da memória no ubuntu. Corre e faz tudo sem problemas. Só falta ainda ordenar records mas isso faço depois. Agora quero correr o jogo no windows. Já alterei a função que apaga o ecrã, visto que o ubuntu nao suporta o system("cls").

Instalei o Dev C++ (parece-me ser antigo mas nao conheco outro. Se me aconselharem um melhor agradeço). Ele compila o programa e não dá qualquer erro. O programa corre às mil maravilhas, até acertarmos nos simbolos. Quando acertamos, o programa bloqueia e sai. Vou colocar aqui o código que crei. São duas funções, uma .cpp e uma .h. Vou assinalar no código o sitio onde dá erro. Se me puderem ajudar, agradecia imenso.

Ficheiro .ccp com o erro assinalado. Em baixo ponho também o ficheiro .h

#include <stdlib.h>			
#include <stdio.h>
#include <time.h>
#include <iomanip>
#include <iostream>
#include "funcoes.h"
#include <fstream>

using namespace std;

//
//	Programa Principal //////////////////////////////////////////////////////////
//

int main(int  argc, char *argv[]){

// *********** Variaveis *************

char op;	// recebe opcao no menu inicial
int niv;	// recebe o nivel escolhido
int TempEs=10;

// dimensao da matriz por definicao (nivel medio)
int* dim= new int[2]; 
dim[0]=6;	// altura da matriz
dim[1]=4;	// largura da matriz	

// Matrizes
int** tab;	// vai receber matriz aleatoria
int** tab2;	// vai receber matriz por preencher
int** tab_coord;	// matriz de controlo

char a[2]; // recebe as coordenadas do simbolo a mostrar

int b,c,temp=0,x,y,temp2,controlo=0, seg=0;

// variaveis de teste
bool teste=0, final, coordenadas=0; 

// variaveis de controlo para records
int jogadas, acertadas;

// *************** Menu *************
do{
	op=Esopcao();

        //printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
	system("cls");       // Apaga ecra (windows)

	switch (op){
		case '1':{	// Jogar
			seg=1;				
			jogadas=0;
			acertadas=0;
			Cabecalho();	// imprime cabecalho

			cout << " A gerar tabuleiro de jogo.... " << endl << endl;
			espera(2);				

			tab=tabuleiro(dim);	// gera tabuleiro

			mostra(tab, dim);	// mostra tabuleiro

			cout << endl << endl << " Get ready ! " << endl << endl;
			cout << "tip: Caso seja extremamente dificil para ti acabar o jogo," << endl;
			cout << "introduz 'q' para desistir." << endl << endl;
			Contagem(TempEs,tab,dim);
			tab2=tabuleiro2(dim);	// gera tabuleiro escondido

			// tabela de controlo para as coordenadas
			tab_coord = new int*[dim[0]];
			for (int i=0; i< dim[0]; ++i){ 
				tab_coord[i] = new int[dim[1]];
			}
			for (int i=0; i<dim[0] ; ++i){
				for(int j=0; j<dim[1]; ++j){
					tab_coord[i][j]=0;
				}
			}

			do{
				if(controlo==0){	// Só gera novo simbolo se tiver adivinhado o anterior
					do{	
						srand ( time(NULL) ); //inicializaçao da semente
						b=rand()%dim[0]+1;
						c=rand()%dim[1]+1;
					}while(tab_coord[b-1][c-1]==1);	// se ja gerou este simbolo, nao volta a gerar
					tab_coord[b-1][c-1]++;
				};

				tab2[b-1][c-1]=tab[b-1][c-1];	// atribui a tab2 um valor de tab para o jogador adivinhar

				do{	// Seleccionar coordenadas

					//printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
	                system("cls");       // Apaga ecra (windows)

                    	Cabecalho();	// imprime cabecalho
					mostra(tab2, dim);	// mostra tabela com simbolo para adivinhar
					cout << endl;
					cout << "Para desistir introduz 'q'." << endl;
					cout << "Mostra: ";
					cin >> a;
					temp=atoi(&a[0]);
					teste=(a[0]=='q');

					coordenadas=0;	//dentro
					int contador=0;

					for (int i=0; i<dim[0] ; i++){
						x=(i+1)*10;
						y=x+1;
						if(temp<y){
							contador++;	//fora
						}
						y=x+dim[1];
						if(temp>y){
							contador++;	//fora
						}
					}
					if (contador==dim[0]) {coordenadas=1;}
				    
				}while(teste==0 && (coordenadas==1 || temp==(b*10+c)));

				jogadas++;	//so conta como jogada se for uma coordenada da matriz

				if (teste!=1){	// Ainda nao desistiu e colocou coordenadas correctamente
					x=temp/10;	// linha da matriz
					y=temp%10;	// coluna da matriz

					temp2=tab2[x-1][y-1];	// coloca em temp2 o valor de tab2 (-) na posicao das coordenadas
					tab2[x-1][y-1]=tab[x-1][y-1];	// coloca em tab2 o valor de tab na posicao das coordenadas

                        //printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
	                system("cls");       // Apaga ecra (windows)

                        Cabecalho();	// imprime cabecalho
					mostra(tab2, dim);	// mostra matriz tab2

					if (tab2[x-1][y-1]!=tab2[b-1][c-1]) {	// Falhou

						cout << endl << " NOT !! Try again..." << flush;
						espera(1);
						tab2[x-1][y-1]=temp2;	// Se nao acertou, esconde a tentativa do jogador
						controlo=1;

						//printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
	                    system("cls");       // Apaga ecra (windows)
					}
// --->Dá erro quando 	else{	// Acertou
// entra neste else						
// imprime a frase			cout << endl << " Well done! Next one..." << flush;
// e depois puff			espera(1);
						tab_coord[x-1][y-1]++;	// Nao vai pedir um par de um simbolo já descoberto
						controlo=0;
						acertadas++;	// incrementa numero de jogadas acertadas

                            //printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
                     	system("cls");       // Apaga ecra (windows)
					}
				}
				else{	// Desistiu!

                        //printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
                        system("cls");       // Apaga ecra (windows)

                        Cabecalho();	// imprime cabecalho
					cout << endl <<" Better luck next time! " << flush;
					espera(1);

					//printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
                  		system("cls");       // Apaga ecra (windows)
				}

				final=1;
				for (int i=0; i<dim[0] ; ++i){
					for(int j=0; j<dim[1]; ++j){
						if(tab2[i][j]!=tab[i][j]){	// Ainda nao descobriu todos os simbolos
							final=0;
						}	
					}
				}

				if (final==1){

					float percent=0;
					percent=((float)acertadas/(float)jogadas)*100;	// percentagem
					Cabecalho();	// imprime cabecalho
					cout << " Congratulations!! You finish it! " << endl;
					cout << " Game score: " << acertadas << "/" << jogadas << " = " << percent << "%" << endl;
					escreve_record(percent);
					cout << " Now try a harder level ... if you dare... " << endl;
					espera(2);

					//printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
                  		system("cls");       // Apaga ecra (windows)
				}

			}while(teste!=1 && final!=1);	// Sai se desistir ou completar
			break;
		}
		case '2':{	// Nivel
			Cabecalho();	// imprime cabecalho
			niv=nivel();	// escolhe nivel
			dim=dimensao(niv, dim);	// define dimensao do tabuleiro

                //printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
	        system("cls");       // Apaga ecra (windows)

                break;
		}
		case '3':{ // Escolher Tempo
			Definirtempo(TempEs);
			break;
		}
		case '4':{	// Mostra Records
			char enter;
			Cabecalho();	// imprime cabecalho
			mostra_records();
			cout << endl << "introduza uma tecla para voltar: ";
			cin >> enter;

			//printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
	        system("cls");       // Apaga ecra (windows)

                break;
		}

		default:	// Nao faz nada
		break;
	};

}while(op!='5');

// Sao sempre alocadas, para posterior eliminação.
// Previne erro caso nunca se jogue!
tab = new int*[dim[0]];
tab2 = new int*[dim[0]];
tab_coord = new int*[dim[0]];
for (int i=0; i< dim[0]; ++i){ 
	tab[i] = new int[dim[1]];
	tab2[i] = new int[dim[1]];
	tab_coord[i] = new int[dim[1]];
};
// Eliminar as tabelas
for (int i=0; i<dim[0] ; ++i){
		delete tab[i];
		delete tab2[i];
		delete tab_coord[i];		
}
delete tab;
delete tab2;
delete tab_coord;
delete dim;

system("pause");
        return 0;	// main
}

Ficheiro .h

// Ficheiro com funcoes criadas para o jogo da memoria
#include <stdlib.h>			
#include <stdio.h>
#include <time.h>
#include <iomanip>
#include <iostream>
#include <fstream>

using namespace std;

//
// Funcao que escreve records
//
int escreve_record(float percentagem){

char p[4];
int a=(int)percentagem/10;
int b=(int)percentagem%10;
int c=(int)(percentagem*10)%10;
p[0]=(char)a;
p[1]=(char)b;
p[2]='.';
p[3]=(char)c;

FILE* fich;

char nome[15];
fich = fopen ("records.txt" , "a");
if(!fich){
	cout << "Erro a abrir o ficheiro";
	return 0;
    }

cout << "Introduz o teu nome: ";
cin >> nome;
fputs (nome,fich);
fputs (" ---> ",fich);
fputs (p,fich);
fputs ("\n",fich);

fclose(fich);
return 0;
}

//
// Funcao que mostra os records no ecrã
//
int mostra_records(){

char str[150];
FILE* fich;

fich = fopen ("records.txt" , "a");	// caso nao exista o ficheiro, cria mas nao escreve nada nele
if(!fich){
	cout << "Erro a abrir o ficheiro";
	return 0;
    }
fclose(fich);



fich = fopen ("records.txt" , "r");


if(!fich){
	cout << "Erro a abrir o ficheiro";
	return 0;
    }
    
    cout << " Top 10 Jogo da memoria" << endl;
    cout << "Nome   ---   percentagem" << endl;
    
while(!feof(fich)){
	fgets (str, 150,fich );
	cout << str;
};

fclose(fich);
return 0;
}
                                                   
//
// Função que mostra o cabeçalho do jogo
//
void Cabecalho(){
cout << "****************************************************" << endl;
cout << "**                                                **" << endl;
cout << "**              JOGO DA MEMORIA                   **" << endl;
cout << "**                                                **" << endl;
cout << "****************************************************" << endl << endl;
}

//
// Função que escolhe o nivel
//
char nivel(){

char n;

do{
cout << "Escolha o nivel de jogo:" << endl;
cout << "1 - Facil" << endl << "2 - Medio" << endl << "3 - Dificil (MESMO!!)" << endl;
cin >> n;
}while(n!='1' && n!='2' && n!='3');

return n;
}

//
//	Funcao que da a dimensao da matriz
//
int* dimensao(char niv, int* dim) {
int dim1=0,dim2=0;

switch (niv){
	case '1':{
		dim1=4;
		dim2=3;
		break;
	}
	case '2':{
		dim1=6;
		dim2=4;
		break;
	}
	case '3':{
		dim1=8;
		dim2=6;
		break;
	}
	default:
	break;
};

dim[0]=dim1;
dim[1]=dim2;
return dim;
}

//
// Funcao que gera matriz de jogo
//
int** tabuleiro(int* dim){

int simb;	// vai receber o número de simbolos diferentes

simb=((dim[0])*dim[1])/2; // pares

int pares[simb];	// vector de controlo
int temp;

for(int i=0; i<simb; i++) {pares[i]=0;} // inicializaçao a zero do vector controlo

int **tab = new int*[dim[0]];
for (int i=0; i< dim[0]; ++i){ 
	tab[i] = new int[dim[1]];
};

srand ( time(NULL) ); //inicializaçao da semente

// cout << simb << endl; // controlo 

for (int i=0; i<dim[0] ; ++i){
	for(int j=0; j<dim[1]; ++j){

		do{
			temp = rand()%simb+65;	//gera inteiro aleatorio entre 1 e simb
			}while(pares[temp-65]==2);	// so queremos um par de cada simbolo

		tab[i][j] = temp;
		pares[temp-65]++;
	}
}

return tab;
}

//
// Funcao que espera
//
void espera ( int seconds ){
  clock_t endwait;
  endwait = clock () + seconds * CLOCKS_PER_SEC ;
  while (clock() < endwait) {}
}

//
// Funcao que mostra o tabuleiro
//
void mostra(int** tab, int* dim){
int i,j;

cout << " ";
for (i=0; i<dim[1]; ++i){
	cout << "   " << i+1 ;
}
cout << endl << endl;

for (i=0; i<dim[0] ; ++i){
	cout << i+1;

	for(j=0; j<dim[1]; ++j){
		cout << "   " << (char)tab[i][j];
	}
	cout << endl;
}
}

//
// Funcao que gera tabuleiro escondido
//
int** tabuleiro2(int* dim){

int simb;	// vai receber o número de simbolos diferentes

simb=((dim[0])*dim[1])/2; // pares

int **tab = new int*[dim[0]];
for (int i=0; i< dim[0]; ++i){ 
	tab[i] = new int[dim[1]];
};

for (int i=0; i<dim[0] ; ++i){
	for(int j=0; j<dim[1]; ++j){
		tab[i][j]=45;
	}
}
return tab;
}

//
// Função da contagem decrescente
//
int Contagem(int TemP,int** tab, int* dim){
int b=0,t,i;
long tem,ago,es;
time(&tem);
tem=tem+TemP+1;
time(&ago);
while(ago<tem){
	es=ago+1;
	time(&ago);
	i=0;
	while(ago<es){
		time(&ago);
		if(i==0){
			//printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
	        system("cls");       // Apaga ecra (windows)

                Cabecalho();
			mostra(tab, dim);
			t=TemP-b;
			cout<<endl<<"Tempo retante: "<<t<<"segundos"<<endl;
			i++;
			b++;
		}
	}
	//printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
	system("cls");       // Apaga ecra (windows)
}
return 0;
}

//
//Funcao para mostrar o menu
//
int Menu(){
cout<<"  *********** Menu  Principal *********** "<< endl << endl;
cout<<"I- iniciar jogo"<<endl;
cout<<"N- definir nivel"<<endl;
cout<<"T- defenir tempo"<<endl;
cout<<"R- ver os recordes"<<endl;
cout<<"S- sair"<<endl;
return 0;
}

//
//Funcao para proteger a opção de escolha
//
char Opcao(){

char Opc;

do{
	cout<<"Introduza a opção desejada: ";
	cin>>Opc;
	if(Opc!='s' && Opc!='S' && Opc!='i' && Opc!='I' && Opc!='t' && Opc!='T' && Opc!='r' && Opc!='R' && Opc!='n'&& Opc!='N' ){
		cout<<"Opção invalida"<<endl;
	}
}while(Opc!='s' && Opc!='S' && Opc!='i' && Opc!='I' && Opc!='t' && Opc!='T' && Opc!='r' && Opc!='R' && Opc!='n'&& Opc!='N' );

return Opc;
}

//
//	Converçao
//
char Esopcao(){

char op;
Cabecalho();
Menu();
op=Opcao();
		switch(op){
		case 'i':
			op='1';
			break;
		case 'I':
			op='1';
			break;
		case 'r':
			op='4';
			break;
		case 'R':
			op='4';
			break;
		case 't':
			op='3';
			break;
		case 'T':
			op='3';
			break;
		case 'n':
			op='2';
			break;
		case 'N':
			op='2';
			break;
		case 's':
			op='5';
			break;
		case 'S':
			op='5';
			break;
		default: 
			cout<<"ERRO";
		}
	return op;
}

//
//Função que define o tempo
//
int Definirtempo(int &TempM){

char resp;
Cabecalho();
while(1){
	//printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
	system("cls");       // Apaga ecra (windows)

	Cabecalho();
	cout<<endl<<"Tempo actual para memorização é "<<TempM<<" segundos "<<endl;
	cout<<"Pretende alterar o tempo? [s/n] ";

	do{
		cin>>resp;
		if(resp!='s' && resp!='S' && resp!='n' && resp!='N'){
			cout<<"opção invalida"<<endl<<"Introduza novamente a opção: ";
		}
	}while(resp!='s' && resp!='S' && resp!='n' && resp!='N');

	if(resp=='n' || resp=='N'){
		//printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
    	system("cls");       // Apaga ecra (windows)
		return 0;
	}

	do{
		//printf("\e[H\e[2J");	// Apaga ecra (ubuntu)
    	system("cls");       // Apaga ecra (windows)

        	Cabecalho();
		cout<<endl<<"Introduza o tempo desejado, entre 1 e 30 segundos ";
		cin>>TempM;

		if(TempM<1 || TempM>30){
			cout<<"Tempo invalido"<<flush;
			espera(1);
		}

	}while(TempM<1 || TempM>30);
}
return 0;		
}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Miketo

Quando o programa é interrompido, ao fazer um debug com o visual studio aparece a seguinte mensagem:

"Access violation writing location 0x00000000."

Na net dizem que isto aparece quando temos uma "Null-pointer dereference".

Não sei o que o código faça para isto acontecer.

Espero que isto ajude a ajudarem-me  :-[

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Miketo

O problema era uma coisa muito simples.

Não estava a criar uma tabela dinamicamente.  :-[

Era uma coisa que tinha feito nas restantes... mas aquela escapou-me e estava a fazer uma alocação "normal" da memória para a tabela.

Mas o que me fez não reparar foi o facto de, para o mesmo problema, no linux ter dado erro para outras tabelas, e naquela não ter dado.  :hmm: Daí não ter associado.

Esta é uma questão que não consegui perceber... mas o programa já funciona... é o que interessa  :thumbsup:

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.