Ir ao conteúdo
  • Cadastre-se

Torre de Hanói resolução iterativa


caaholiveira91

Posts recomendados

Boa noite.

Eu e uma colega estamos desenvolvendo um código em c para simular o jogo da torre de hanói sem usar a recursividade. Estamos com problemas porque ao rodar o programa aparece lixo de memória. Imaginamos que o erros estão no envio dos parâmetros ou na função de mover discos mas não conseguimos localizá-los :confused:

Se alguém puder nos ajudar ficaríamos muito gratas. Abaixo segue o código do programa:

#include <stdlib.h>

#include <stdio.h>

void jogar(int arg,int *pa,int *pb,int *pc);

void movedisco(int arg,int origem,int destino,int *veta,int *vetb,int *vetc);

void intrucoes();

void movedisco(int arg,int origem,int destino,int *pa,int *pb,int *pc){

int i,discoi;

//move o disco do pinoA para o pinoC

if(origem==1 && destino==3){

//busca o disco mais de cima do pino A,e armazena o conteudo dele na variavel pinoi

for(i=0;i<arg;i++) {

if(*pa!=0){

discoi=*pa;

*pa=0;

break;

}

else{

pa++;

}

}

//busca no pinoC a primeira posição vazia de baixo pra cima, e armazena o disco do A caso o disco que ja estiver no pinoC for maior que o proximo a armazenar

pc=pc+4;

for(i=arg-1;i>=0;i--){

if (*pc==0){

if(*(pc+1)>discoi){

*pc=discoi;

break;

}

else{

printf("\nMovimento invalido!");

}

}

pc--;

}

}

//move o disco do pinoA para o pinoB

if(origem==1 && destino==2){

for(i=0;i<arg;i++) {

if(*pa!=0){

discoi=*pa;

*pa=0;

break;

}

else{

pa++;

}

}

pb=pb+4;

for(i=arg-1;i>=0;i--){

if (*pb==0){

if(*(pb+1)>discoi){

*pb=discoi;

break;

}

else{

printf("\nMovimento invalido!");

}

}

pb--;

}

}

//move o disco do pinoB para o pinoC

if(origem==2 && destino==3){

for(i=0;i<arg;i++) {

if(*pb!=0){

discoi=*pb;

*pb=0;

break;

}

else{

pb++;

}

}

pc=pc+4;

for(i=arg-1;i>=0;i--){

if (*pc==0){

if(*(pc+1)>discoi){

*pc=discoi;

break;

}

else{

printf("\nMovimento invalido!");

}

}

pc--;

}

}

//move o disco do pinoB para o pinoA

if(origem==2 && destino==1){

for(i=0;i<arg;i++) {

if(*pb!=0){

discoi=*pb;

*pb=0;

break;

}

else{

pb++;

}

}

pa=pa+4;

for(i=arg-1;i>=0;i--){

if (*pa==0){

if(*(pa+1)>discoi){

*pa=discoi;

break;

}

else{

printf("\nMovimento invalido!");

}

}

pa--;

}

}

//move o disco do pinoC para o pinoA

if(origem==3 && destino==1){

for(i=0;i<arg;i++) {

if(*pc!=0){

discoi=*pc;

*pc=0;

break;

}

else{

pc++;

}

}

pa=pa+4;

for(i=arg-1;i>=0;i--){

if (*pa==0){

if(*(pa+1)>discoi){

*pa=discoi;

break;

}

else{

printf("\nMovimento invalido!");

}

}

pa--;

}

}

//move o disco do pinoC para o pinoB

if(origem==3 && destino==2){

for(i=0;i<arg;i++) {

if(*pc!=0){

discoi=*pc;

*pc=0;

break;

}

else{

pc++;

}

}

pb=pb+4;

for(i=arg-1;i>=0;i--){

if (*pb==0){

if(*(pb+1)>discoi){

*pb=discoi;

break;

}

else{

printf("\nMovimento invalido!");

}

}

pb--;

}

}

//chama função jogar para mostrar o jogo despois do movimento do disco

jogar(arg,pa,pb,pc);

system("pause");

system("cls");

return;

}

void jogar(int arg,int *pa,int *pb,int *pc){

int i,origem,destino,contb=0,contc=0,movimentos=0;

system("cls");

for(i=0;i<arg;i++){

printf("\n ");

if (*pa==0)

printf(" | ");

else

printf("(%i)", *pa);

if (*pb==0)

printf(" | ");

else

printf(" (%i)",*pb);

if (*pc==0)

printf(" | ");

else printf(" (%i) ",*pc);

pa++;

pb++;

pc++;

}

printf("\n ==============\n");

printf(" A B C ");

printf("\n ==============\n\n");

for(i=0;i<arg;i++){

if(*pb==(i+1)){

contb++;

}

if(*pc==(i+1)){

contc++;

}

pb++;

pc++;

}

if(contb==arg || contc==arg){

printf("\nParabens!! voce venceu o jogo com %i movimentos!\n",movimentos);

main();

}

printf("Digite 1 para A 2 para B 3 para C\n\n");

printf("Origem: ");

scanf("%i",&origem);

printf("\nDestino: ");

scanf("%i",&destino);

movimentos++;

//fazendo os ponteiros voltarem para primeira posição para mandar por parametro

pa=pa-4;

pb=pb-4;

pc=pc-4;

if((origem==1)&&(destino==3))

movedisco(arg,origem,destino,pa,pb,pc);

if((origem==1)&&(destino==2))

movedisco(arg,origem,destino,pa,pb,pc);

if((origem==2)&&(destino==3))

movedisco(arg,origem,destino,pa,pb,pc);

if((origem==2)&&(destino==1))

movedisco(arg,origem,destino,pa,pb,pc);

if((origem==3)&&(destino==1))

movedisco(arg,origem,destino,pa,pb,pc);

if((origem==3)&&(destino==2))

movedisco(arg,origem,destino,pa,pb,pc);

return;

}

void instrucoes(){

printf("\n- voce so pode movimentar um disco de cada vez.");

printf("\n\n- Um disco maior NAO pode ficar em cima de um menor.");

printf("\n\n- O jogo termina quando voce conseguir colocar todos os discos (do maior ao menor) no pino C.");

printf("\n\n- Bom jogo!!\n\n\n");

system("pause");

system("cls");

main();

return;

}

int main(){

int opcao,veta[5],vetb[5],vetc[5],arg=5,i;

printf("\n*Jogo desenvolvido por Camila e Rose*\n");

printf("\n\n\n ----------TORRE DE HANOI----------\n\n");

//Enquanto opcao for diferente de 3

while (opcao != 3){

printf(" 1 - Jogar\n");

printf(" 2 - Insrucoes\n");

printf(" 3 - Sair\n\n");

printf(" Digite opcao: ");

scanf("%i",&opcao);

system("cls");

if(opcao==1){

for(i=0;i<arg;i++){

veta=i+1;

vetb=0;

vetc=0;

}

jogar(arg,&veta,&vetb,&vetc);//chama funcao jogar

}

if(opcao==2){

instrucoes();

}

return 0;

}

}

Link para o comentário
Compartilhar em outros sites

É meio irônico ler o seu código, pois vocês não sabem debugar ele, mas querem usar aritmética de ponteiro, uma das técnicas mais difíceis e propensas a erro que existe. Usem subscript [].

Segundo, usa a tag code pra posta, porque do jeito que você postou sem condições de ler. Se postarem num formato legal até leio.

Boa sorte.

Aproveitar que eu já to na área, não é a primeira vez que vejo as pessoas dando return no final de uma função void e/ou chamando main();

Um é desnecessário, o outro é errado de tantas maneiras que nem sabia que dava pra fazer isso...

Link para o comentário
Compartilhar em outros sites

Peço desculpas por ter esquecido a tag code >.<

Infelizmente o código é reflexo do que nos é passado em sala de aula,

uma vez que temos que nos basear nos conteúdos e exercícios passados pelo professor.

Usamos os ponteiros porque os parâmetros devem ser passados por referência.

Obrigado.


#include <stdlib.h>
#include <stdio.h>

void jogar(int arg,int *pa,int *pb,int *pc);
void movedisco(int arg,int origem,int destino,int *veta,int *vetb,int *vetc);
void intrucoes();


void movedisco(int arg,int origem,int destino,int *pa,int *pb,int *pc){
int i,discoi;

//move o disco do pinoA para o pinoC
if(origem==1 && destino==3){
//busca o disco mais de cima do pino A,e armazena o conteudo dele na variavel pinoi
for(i=0;i<arg;i++) {
if(*pa!=0){
discoi=*pa;
*pa=0;
break;
}
else{
pa++;
}
}
//busca no pinoC a primeira posição vazia de baixo pra cima, e armazena o disco do A caso o disco que ja estiver no pinoC for maior que o proximo a armazenar
pc=pc+4;
for(i=arg-1;i>=0;i--){
if (*pc==0){
if(*(pc+1)>discoi){
*pc=discoi;
break;
}
else{
printf("\nMovimento invalido!");
}
}
pc--;
}
}
//move o disco do pinoA para o pinoB
if(origem==1 && destino==2){
for(i=0;i<arg;i++) {
if(*pa!=0){
discoi=*pa;
*pa=0;
break;
}
else{
pa++;
}
}
pb=pb+4;
for(i=arg-1;i>=0;i--){
if (*pb==0){
if(*(pb+1)>discoi){
*pb=discoi;
break;
}
else{
printf("\nMovimento invalido!");
}
}
pb--;
}
}

//move o disco do pinoB para o pinoC
if(origem==2 && destino==3){
for(i=0;i<arg;i++) {
if(*pb!=0){
discoi=*pb;
*pb=0;
break;
}
else{
pb++;
}
}
pc=pc+4;
for(i=arg-1;i>=0;i--){
if (*pc==0){
if(*(pc+1)>discoi){
*pc=discoi;
break;
}
else{
printf("\nMovimento invalido!");
}
}
pc--;
}
}
//move o disco do pinoB para o pinoA
if(origem==2 && destino==1){
for(i=0;i<arg;i++) {
if(*pb!=0){
discoi=*pb;
*pb=0;
break;
}
else{
pb++;
}
}
pa=pa+4;
for(i=arg-1;i>=0;i--){
if (*pa==0){
if(*(pa+1)>discoi){
*pa=discoi;
break;
}
else{
printf("\nMovimento invalido!");
}
}
pa--;
}
}
//move o disco do pinoC para o pinoA
if(origem==3 && destino==1){
for(i=0;i<arg;i++) {
if(*pc!=0){
discoi=*pc;
*pc=0;
break;
}
else{
pc++;
}
}
pa=pa+4;
for(i=arg-1;i>=0;i--){
if (*pa==0){
if(*(pa+1)>discoi){
*pa=discoi;
break;
}
else{
printf("\nMovimento invalido!");
}
}
pa--;
}
}
//move o disco do pinoC para o pinoB
if(origem==3 && destino==2){
for(i=0;i<arg;i++) {
if(*pc!=0){
discoi=*pc;
*pc=0;
break;
}
else{
pc++;
}
}
pb=pb+4;
for(i=arg-1;i>=0;i--){
if (*pb==0){
if(*(pb+1)>discoi){
*pb=discoi;
break;
}
else{
printf("\nMovimento invalido!");
}
}
pb--;
}
}

//chama função jogar para mostrar o jogo despois do movimento do disco
jogar(arg,pa,pb,pc);
system("pause");
system("cls");
return;
}

void jogar(int arg,int *pa,int *pb,int *pc){
int i,origem,destino,contb=0,contc=0,movimentos=0;

system("cls");
for(i=0;i<arg;i++){
printf("\n ");
if (*pa==0)
printf(" | ");
else
printf("(%i)", *pa);
if (*pb==0)
printf(" | ");
else
printf(" (%i)",*pb);
if (*pc==0)
printf(" | ");
else printf(" (%i) ",*pc);
pa++;
pb++;
pc++;
}

printf("\n ==============\n");
printf(" A B C ");
printf("\n ==============\n\n");


for(i=0;i<arg;i++){
if(*pb==(i+1)){
contb++;
}
if(*pc==(i+1)){
contc++;
}
pb++;
pc++;
}
if(contb==arg || contc==arg){
printf("\nParabens!! voce venceu o jogo com %i movimentos!\n",movimentos);
main();
}

printf("Digite 1 para A 2 para B 3 para C\n\n");
printf("Origem: ");
scanf("%i",&origem);
printf("\nDestino: ");
scanf("%i",&destino);
movimentos++;
//fazendo os ponteiros voltarem para primeira posição para mandar por parametro
pa=pa-4;
pb=pb-4;
pc=pc-4;
if((origem==1)&&(destino==3))
movedisco(arg,origem,destino,pa,pb,pc);

if((origem==1)&&(destino==2))
movedisco(arg,origem,destino,pa,pb,pc);

if((origem==2)&&(destino==3))
movedisco(arg,origem,destino,pa,pb,pc);

if((origem==2)&&(destino==1))
movedisco(arg,origem,destino,pa,pb,pc);

if((origem==3)&&(destino==1))
movedisco(arg,origem,destino,pa,pb,pc);

if((origem==3)&&(destino==2))
movedisco(arg,origem,destino,pa,pb,pc);

return;
}

void instrucoes(){
printf("\n- voce so pode movimentar um disco de cada vez.");
printf("\n\n- Um disco maior NAO pode ficar em cima de um menor.");
printf("\n\n- O jogo termina quando voce conseguir colocar todos os discos (do maior ao menor) no pino C.");
printf("\n\n- Bom jogo!!\n\n\n");
system("pause");
system("cls");
main();
return;
}

int main(){
int opcao,veta[5],vetb[5],vetc[5],arg=5,i;
printf("\n*Jogo desenvolvido por Camila e Rose*\n");
printf("\n\n\n ----------TORRE DE HANOI----------\n\n");

//Enquanto opcao for diferente de 3
while (opcao != 3){
printf(" 1 - Jogar\n");
printf(" 2 - Insrucoes\n");
printf(" 3 - Sair\n\n");

printf(" Digite opcao: ");
scanf("%i",&opcao);
system("cls");

if(opcao==1){

for(i=0;i<arg;i++){
veta[i]=i+1;
vetb[i]=0;
vetc[i]=0;
}
jogar(arg,&veta,&vetb,&vetc);//chama funcao jogar
}
if(opcao==2){
instrucoes();
}

return 0;
}
}

Link para o comentário
Compartilhar em outros sites

Não precisa se desculpar, meu comentário é justamente para criar impacto e fazer com que as pessoas procurem opções melhores.

Você pode usar ponteiro como um array, é muito mais fácil e menos propenso a erros. Até porque todo array é passado para função como ponteiro.

Quando eu falei do CODE, era pra você usá-lo para ele manter a indentação do código :confused:

Desse jeito continua ruim de ler.

Pegue do seu editor, que eu acredito esteja indentado e copie dentro das tags code que ele vai manter as indentações.

Ok?

Aproveitando a sua deixa, ponteiros não são a única forma de passar por referência, existe outro recurso na linguagem que faz isso o operador &. Que também é pouco utilizado e evita muitas dores de cabeça.

Agora se você só precisa passar de ano, realmente apenas siga o que o professor te passa, mas se pretende se tornar uma programadora em C precisa largar esses conceitos e melhorar bastante.

No aguardo.

Link para o comentário
Compartilhar em outros sites

  • 9 meses depois...

Bom dia Edmorte,

 

Na resposta anterior do tópico disse que postaria seu código iterativo da torre de hanói que está melhor se ocorresse manifesto.

Por favor, peço que poste sua resolução iterativa do problema da torre de hanói.

 

obrigado!

 

Cara procura um post meu de Hanói, já postei ele em C++ usando classes a muito tempo.

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!