JJMUniz Posted February 9, 2014 at 05:46 AM Report #544514 Posted February 9, 2014 at 05:46 AM Olá pessoal estou com um grande problema, preciso fazer com que meu programa em C execute duas funções ao mesmo tempo. --> para ser mais específico estou criando um jogo de labirinto onde o personagem(um caractere) se movimenta sozinho tentando achar o caminho mais curto ate a saída percorrendo um labirinto(matriz de char), só que em determinado ponto eu quero duplicar este personagem para isso criei uma nova função de execução e preciso fazer com que ela seja executada ao mesmo tempo que o main fazendo assim meus personagens andarem por caminhos diferentes no meu labirinto.
HappyHippyHippo Posted February 9, 2014 at 09:50 AM Report #544518 Posted February 9, 2014 at 09:50 AM o que pretendes é possível, mas não imaginas a quantidade de problemas que originam ao tentar resolver o problema através desse método. o melhor seria apresentares o código que tens para apresentar uma segunda solução possível que passará por uma generalização do processo de decisão do movimento de uma personagem IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
JJMUniz Posted February 10, 2014 at 04:40 AM Author Report #544609 Posted February 10, 2014 at 04:40 AM Aqui esta o código, fiz uns comentários para tentar explica-lo #include <stdio.h> #include <stdlib.h> int m,n,i,j; float x,y,menor1,menor2,menorC=80,menorB=80,menorE=80,menorD=80; //a variavel abaixo e o mapa do labirinto char labirinto [20][32]={ '1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1', '@',' ','1','1','1',' ','1','1',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','1','1', '1',' ','1','1','1',' ','1','1',' ','1','1','1',' ','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1',' ',' ','1', '1',' ','1','1','1',' ',' ',' ',' ','1','1','1',' ',' ','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1',' ','1', '1',' ','1','1','1','1','1','1','1','1','1','1',' ',' ','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1',' ','1', '1',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','1','1',' ','1', '1','1','1','1','1','1','1','1','1','1','1','1','1',' ','1','1','1','1','1',' ','1','1','1','1','1','1','1',' ','1','1',' ','1', '1',' ','1','1','1','1','1','1','1','1','1','1','1',' ','1','1','1','1','1',' ',' ','1','1','1','1','1','1',' ','1','1',' ','1', '1',' ',' ',' ',' ','1','1','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1',' ','1', '1','1','1','1',' ','1','1','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1',' ','1', '1','1','1','1',' ','1','1','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1',' ','1', '1',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1',' ','1', '1',' ','1','1','1','1','1','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1',' ','1', '1',' ','1','1','1','1','1','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1',' ','1', '1',' ','1','1','1','1','1','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ','1','1',' ','1', '1',' ','1','1','1','1','1','1','1','1','1','1','1',' ','1','1','1','1','1','1',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','1', '1',' ','1','1','1','1','1','1','1','1','1','1','1',' ','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1',' ','1', '1',' ',' ',' ',' ',' ',' ',' ',' ',' ','1','1','1',' ','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1',' ','1', '1','1','1','1','1','1','1','1','1',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','1','1','1',' ','1', '1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1',' ','1'}; _flushall(); void movimenta2(int m, int n); int main() { m=1; n=0; //fiz uma rotina, onde só terminará o game quando encontrar a saída float adj [20][32]; for(i=0;i<20;i++){ for(j=0;j<32;j++){ adj[i][j]=0;//zerando a matriz de adjacência }//for interno }//for externo for(i=0;i<20;i++){ for(j=0;j<32;j++){ if(labirinto[i][j]!='1'){ adj[i][j]=((i+j)+2); }else if(labirinto[i][j]=='@'){//atribuindo os devidos valores a matriz de adajcência adj[i][j]=0; } else{ adj[i][j]=-1; } }//for interno }//for externo while(1) { for(i=0;i<20;i++){ for(j=0;j<32;j++){ printf("%c",labirinto[i][j]); } printf("\n"); } //Como fiz utilizando variaveis do tipo char, a cada comando do teclado //preciso alterar o local novo e do antigo, se a condicao for aceita //o corpo só se movera se o programa achar o ' ' (espaco). if (adj[m+1][n]!= -1 && labirinto[m+1][n]!='1'){//se for possivel andar para baixo ele calcula a distância x=adj[m][n]; y=adj[m+1][n]; menor1=y-x; x=adj[m+1][n]; y=adj[19][30]; menor2=y-x; menorB=menor2-menor1; } if ( adj[m-1][n]!= -1 && labirinto[m-1][n]!='1'){//se for possivel andar para cima ele calcula a distância x=adj[m][n]; y=adj[m-1][n]; menor1=y-x; x=adj[m-1][n]; y=adj[19][30]; menor2=y-x; menorC=menor2-menor1; } if ( adj[m][n+1]!=-1 && labirinto[m][n+1]!='1') {//se for possivel andar para a direita ele calcula a distância x=adj[m][n]; y=adj[m][n+1]; menor1=y-x; x=adj[m][n+1]; y=adj[19][30]; menor2=y-x; menorD=menor2-menor1; } if ( adj[m][n-1]!= -1 && labirinto[m][n-1]!='1' ) {//se for possivel andar para a esquerda ele calcula a distância x=adj[m][n]; y=adj[m][n-1]; menor1=y-x; x=adj[m][n-1]; y=adj[19][30]; menor2=y-x; menorE=menor2-menor1; } //faz as devidas comparações a fim de decidir para onde vai ce movimentar if(menorC<menorD&&menorC<menorB&&menorC<menorE){ m = m - 1; if(labirinto[m][n] == ' '){ labirinto [m][n]= '@'; labirinto [m+1][n]=' '; } } if(menorD<menorC&&menorD<menorB&&menorD<menorE){ n = n + 1; if(labirinto[m][n] == ' '){ labirinto [m][n]= '@'; labirinto [m][n-1]=' '; } } if(menorE<menorC&&menorE<menorB&&menorE<menorD){ n = n - 1; if(labirinto[m][n] == ' '){ labirinto [m][n]= '@'; labirinto [m][n+1]=' '; } } if(menorB<menorC&&menorB<menorE&&menorB<menorD){ m = m + 1; if(labirinto[m][n] == ' '){ labirinto [m][n]= '@'; labirinto [m-1][n]=' '; } } /*Aqui esta um dos meus problemas, ha pontos em que a distancia é giual tanto para um lado quanto para o outro então nesses if's digo que quando ele encontrar direita e baixo iguais opte pela direita e quando encontrar direita e esquerda igualis opte pela direita por isso quero criar uma função para quando encontrar dois pontos mandar um caratere por um lado e outro por outro lado. */ if(menorD==menorB){ movimenta2(m,n); m = m + 1; if(labirinto[m][n] == ' '&& adj[m][n]!= -1){ labirinto [m][n]= '@'; labirinto [m-1][n]=' '; } } if(menorD==menorE){ movimenta2(m,n); n = n + 1; if(labirinto[m][n] == ' '&& adj[m][n]!= -1){ labirinto [m][n]= '@'; labirinto [m][n-1]=' '; } } getch(); if(labirinto [19][30] == '@')//quando chega a saida acaba break; system("cls"); } system("cls"); for(i=0;i<20;i++){ for(j=0;j<32;j++){ printf("%c",labirinto[i][j]); } printf("\n"); } printf("PARABENS, VOCE CONSEGEUIU ESCAPAR!!!!!!!\n"); getch(); return 0; } /*a função e práticamente igual o código de cima mas muda as opções de movimento quando encontra distâncias iguais*/ void movimenta2(int m,int n){ //fiz uma rotina, onde só terminará o game quando encontrar a saída float adj [20][32]; for(i=0;i<20;i++){ for(j=0;j<32;j++){ adj[i][j]=0; }//for interno }//for externo for(i=0;i<20;i++){ for(j=0;j<32;j++){ if(labirinto[i][j]!='1'){ adj[i][j]=((i+j)+2); }else if(labirinto[i][j]=='@'){ adj[i][j]=0; } else{ adj[i][j]=-1; } }//for interno }//for externo while(1) { for(i=0;i<20;i++){ for(j=0;j<32;j++){ printf("%c",labirinto[i][j]); } printf("\n"); } if (adj[m+1][n]!= -1 ){ x=adj[m][n]; y=adj[m+1][n]; menor1=y-x; x=adj[m+1][n]; y=adj[19][13]; menor2=y-x; menorB=menor2-menor1; } if ( adj[m-1][n]!= -1 ){ x=adj[m][n]; y=adj[m-1][n]; menor1=x-y; x=adj[m-1][n]; y=adj[19][13]; menor2=y-x; menorC=menor2-menor1; } if ( adj[m][n+1]!=-1 ) { x=adj[m][n]; y=adj[m][n+1]; menor1=y-x; x=adj[m][n+1]; y=adj[19][13]; menor2=y-x; menorD=menor2-menor1; } if ( adj[m][n-1]!= -1 ) { x=adj[m][n]; y=adj[m][n-1]; menor1=x-y; x=adj[m][n-1]; y=adj[19][13]; menor2=y-x; menorE=menor2-menor1; } if(menorC<menorD&&menorC<menorB&&menorC<menorE){ m = m - 1; if(labirinto[m][n] == ' '){ labirinto [m][n]= '@'; labirinto [m+1][n]=' '; } } if(menorD<menorC&&menorD<menorB&&menorD<menorE){ n = n + 1; if(labirinto[m][n] == ' '){ labirinto [m][n]= '@'; labirinto [m][n-1]=' '; } } if(menorE<menorC&&menorE<menorB&&menorE<menorD){ n = n - 1; if(labirinto[m][n] == ' '){ labirinto [m][n]= '@'; labirinto [m][n+1]=' '; } } if(menorB<menorC&&menorB<menorE&&menorB<menorD){ m = m + 1; if(labirinto[m][n] == ' '){ labirinto [m][n]= '@'; labirinto [m-1][n]=' '; } } if(menorD==menorB){ n=n+1; if(labirinto[m][n] == ' '&& adj[m][n]!= -1){ labirinto [m][n]= '@'; labirinto [n-1][n]=' '; } } if(menorD==menorE){ n = n - 1; if(labirinto[m][n] == ' '&& adj[m][n]!= -1){ labirinto [m][n]= '@'; labirinto [m][n+1]=' '; } } getch(); if(labirinto [19][30] == '@') break; system("cls"); } system("cls"); for(i=0;i<20;i++){ for(j=0;j<32;j++){ printf("%c",labirinto[i][j]); } printf("\n"); } printf("PARABENS, VOCE CONSEGEUIU ESCAPAR!!!!!!!\n"); getch(); } sim o calculo do movimento deve ser feito assim com base no algoritmo de busca "A*".
mundo Posted February 10, 2014 at 09:36 AM Report #544613 Posted February 10, 2014 at 09:36 AM Epa identa o código sff, pões o codigo entre [ code = c] e [ /code] sem os espaços
HappyHippyHippo Posted February 10, 2014 at 09:56 AM Report #544617 Posted February 10, 2014 at 09:56 AM separa o código de decisão para uma uma função mantendo o main o mais pequeno possível. depois indica quando pretendes ter duas funções de decisão a correr "em simultâneo" IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
KTachyon Posted February 10, 2014 at 10:34 AM Report #544620 Posted February 10, 2014 at 10:34 AM Usa libdispatch. Aquilo que dizem ser complexo passa a ser praticamente trivial. “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” -- Tony Hoare
Rui Carlos Posted February 10, 2014 at 03:35 PM Report #544654 Posted February 10, 2014 at 03:35 PM Suspeito que aquilo que pretendes é uma espécie de pesquisa breadth-first. Duvido que precises realmente de concorrência (que é algo que tornará o programa desnecessariamente complexo para o nível em que estás). Rui Carlos Gonçalves
JJMUniz Posted February 10, 2014 at 05:13 PM Author Report #544680 Posted February 10, 2014 at 05:13 PM (edited) Rui estou sim tentando fazer uma busca, só que uma busca em um grafo,por isso no código uso a matriz de adjacência. KTachyon, poderia falar um pouco mais sobre libdispatch ? Edited February 10, 2014 at 05:14 PM by JJMUniz
Rui Carlos Posted February 10, 2014 at 05:21 PM Report #544683 Posted February 10, 2014 at 05:21 PM Se fores ao link que te indiquei, vais ler que "n graph theory, breadth-first search (BFS) is a strategy for searching in a graph [...]". Rui Carlos Gonçalves
KTachyon Posted February 10, 2014 at 09:19 PM Report #544740 Posted February 10, 2014 at 09:19 PM (edited) KTachyon, poderia falar um pouco mais sobre libdispatch ? Deverá ser fácil de interpretar #import <dispatch/dispatch.h> int main(int argc, const char * argv[]) { dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_queue_create("qualquer coisa", DISPATCH_QUEUE_CONCURRENT); for (int i = 0; i < 5; i++) dispatch_group_async(group, queue, ^{ printf("hello world concorrente #%d\n", i); }); dispatch_group_wait(group, DISPATCH_TIME_FOREVER); printf("e foram felizes para sempre\n"); return 0; } Só para facilitar, imagina que tens os dois procedimentos que queres executar em simultâneo ao chamares as funções func1 e func2: #import <dispatch/dispatch.h> int main(int argc, const char * argv[]) { dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_queue_create("qualquer coisa", DISPATCH_QUEUE_CONCURRENT); dispatch_group_async(group, queue, ^{ func1(); }); dispatch_group_async(group, queue, ^{ func2(); }); dispatch_group_wait(group, DISPATCH_TIME_FOREVER); printf("e foram felizes para sempre\n"); return 0; } Edited February 10, 2014 at 09:25 PM by KTachyon “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” -- Tony Hoare
JJMUniz Posted February 11, 2014 at 06:21 AM Author Report #544783 Posted February 11, 2014 at 06:21 AM Isso mesmo Rui, li com calma o artigo e é isso mesmo que estou tentando fazer. KTachyon seguirei se conselho vou tentar esta implementação.
KTachyon Posted February 11, 2014 at 08:51 AM Report #544787 Posted February 11, 2014 at 08:51 AM Precisas de ter o libdispatch para o poderes importar e, se queres fazer uso de blocks (^{}), tens que utilizar um compilador que os suporte, como o Clang. “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” -- Tony Hoare
HappyHippyHippo Posted February 11, 2014 at 09:30 AM Report #544788 Posted February 11, 2014 at 09:30 AM Isso mesmo Rui, li com calma o artigo e é isso mesmo que estou tentando fazer. não existe necessidade nenhuma de fazer paralelismo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Flinger Posted February 11, 2014 at 09:57 AM Report #544799 Posted February 11, 2014 at 09:57 AM @KTachyon Por muito tentadora que me pareça essa lib, é algo que vem do IOS, e embora exista um port para Linux, não sei até que ponto eu me atiraria para algo nesse estado, visto que nem sequer posso utilizar o gcc. Além disso, o que faz nesse exemplo base não é complicado de implementar usando as threads por meios mais normais. Acredito que tenha outras potencialidades, mas para algo tão simples eu não me daria ao trabalho de mudar de compilador. Se pode ser feito sem recurso a paralelismo, ainda melhor.
KTachyon Posted February 11, 2014 at 11:37 AM Report #544817 Posted February 11, 2014 at 11:37 AM É open source (e os blocks são uma extensão do C). Não vem do iOS, mas sim do Mac OS X. Segundo o que sei, está integrada no FreeBSD. Já tem uns 6 anos, e antes de criticares por "ser Apple", agradecia que fosses ler um pouco mais sobre o assunto. O problema com gestão de threads é ser pesada. Isso é um problema que o pessoal normalmente resolve com thread pools, mas o problema é que a criação das thread pools depende dos recursos do sistema. Se tiveres uma thread pool demasiado pequena não consegues aproveitar os recursos do sistema, se tiveres uma thread pool demasiado grande, perdes performance com mudanças de contexto. Para além disso, tens que conseguir gerir o código que vais executar em cada uma das threads. Não há uma forma de simplesmente despejares código para uma thread específica e esperar que ela execute. Com libdispatch não precisas de saber quantas threads tens disponíveis, podes despejar o código que queres, quando queres, em runtime. O sistema escala para os recursos do sistema que estão disponíveis e é extremamente leve. Para além disso, em muitos casos em que precisarias de utilizar locks e semáforos para gerir a utilização concorrente de recursos, com GCD consegues gerir os acessos sem a necessidade de locks, forçando os acessos sequenciais ao recurso num getter/setter. Isto é apenas um peek. Existem muito mais funcionalidades que tornam a libdispatch a framework ideal para gerir concorrência. “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” -- Tony Hoare
Flinger Posted February 11, 2014 at 12:08 PM Report #544818 Posted February 11, 2014 at 12:08 PM (edited) O meu problema com isso não é ser Apple, é não ser POSIX. O grande problema dos ports é a falta de compatibilidade com muitas plataformas. Falas em FreeBSD, e o as grandes distribuições Linux? Pelo que vi pela net, vejo grandes potencialidades à biblioteca, mas em todo o lado (Excepto Apple) me parece mais um Workinprogress do que propriamente um produto terminado. E posso-te desde já dar mais uma razão. Se vejo problemas em compilar isso para uma qualquer distro Linux, imagino agora para um arm, onde normalmente pouco mais tenho do que uma toolchain com o gcc. No entanto reconheço que possivelmente a minha realidade me levou a torcer o nariz ao uso da Lib, depois da primeira pesquisa (inicialmente até fiquei empolgado pois parece-me bastante útil). Além do mais parti do princípio que seria para usar Linux, quando no tópico não existe nenhuma alusão a esse facto. Existem ports para Windows, mas, mais uma vez, me parece mais um Workinprogress do que algo terminado. Por estas dificuldades e interrogações todas, dificilmente usaria essa solução para resolver algo bem mais simples como este problema. Edited February 11, 2014 at 12:09 PM by Flinger
Rui Carlos Posted February 11, 2014 at 12:36 PM Report #544826 Posted February 11, 2014 at 12:36 PM Por muito boa que seja a libdispatch, acho que bastaria olhar para o código do autor do tópico para perceber que não é grande ideia usar paralelismo (ou concorrência) nesta situação. Rui Carlos Gonçalves
JJMUniz Posted February 12, 2014 at 02:42 AM Author Report #544978 Posted February 12, 2014 at 02:42 AM Então Rui e Flinger, poderiam me dar alguma sugestão ? desde já agradecido.
KTachyon Posted February 12, 2014 at 09:28 AM Report #544984 Posted February 12, 2014 at 09:28 AM A sugestão é não utilizares concorrência, se bem que penso que ainda não deu para perceber exactamente o que pretendes fazer. Eu começava por limpar o código, uma vez que tens aí uma série de repetições de código que deviam estar encapsuladas em funções. Em resposta ao Flinger: - A libdispatch não é un work in progress. A API tem é crescido. - A instalação em Linux é tão simples como apt-get install libdispatch-dev - Estranhamente, tenho andado a compilar para ARM com o Clang... “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” -- Tony Hoare
Flinger Posted February 12, 2014 at 09:35 AM Report #544986 Posted February 12, 2014 at 09:35 AM Em resposta ao Flinger: - A libdispatch não é un work in progress. A API tem é crescido. - A instalação em Linux é tão simples como apt-get install libdispatch-dev - Estranhamente, tenho andado a compilar para ARM com o Clang... Então, se assim é, só me resta retirar o que disse. Não foi essa a ideia com que fiquei ao fazer uma pesquisa rápida pela net.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now