/** * A função executa_comando é uma das funções mais importantes pois é ela que vai reagir aos comandos dados pelo utilizador. * A função irá receber a linha de comando separa la em dois, no comando e nos argumentos do comando, e passa los para as funções associadas aos comandos. * @param Tab Tabuleiro do jogo * @param DIM dimensão do tabuleiro * @param linha Recebe uma string que corresponde á linha lida da shell. * @returns torna um inteiro que verifica se foi ou não bem sucedida a função. */ int executa_comando(char *linha,int *DIM,Elem **Tab) { char cmd[1025]; char args[1025]; int nargs=sscanf(linha, "%s %[^\n]", cmd, args); if((strcmp(cmd, "b") == 0 || strcmp(cmd, "p") == 0 || strcmp(cmd, "i") == 0)) return executaJogada(args,cmd,DIM,Tab); if(strcmp(cmd, "cr") == 0 ) return executaCriaJogo(args,DIM,Tab); if(strcmp(cmd,"gr")==0 ) return executaGravaJogo(args,DIM,Tab); if(strcmp(cmd,"?")==0 && nargs==1) return ajuda(); if(strcmp(cmd,"trp")==0 && nargs==1) return trp(Tab,DIM); if(strcmp(cmd,"snd")==0 && nargs==1) return snd(Tab,DIM); if(strcmp(cmd,"pis")==0 && nargs==1) return pis(Tab,DIM); if(strcmp(cmd,"pds")==0 && nargs==1) return pds(Tab,DIM); if(strcmp(cmd,"vb")==0 && nargs==1) return vb(Tab,DIM); if(strcmp(cmd,"vp")==0 && nargs==1) return vp(Tab,DIM); if(strcmp(cmd,"vl")==0 && nargs==1) return vl(Tab,DIM); if(strcmp(cmd,"q")==0) exit(0); return mensagem_de_erro(E_COMMAND); }
/** * aplica o minimax em paralelo */ double parallelMiniMax(char time,t_jogada *jogada,t_jogo *jogoOrig,double alfa, double beta, int cor, unsigned int profundidade,unsigned int tempoMax,char primeiro,unsigned int t0) { #define MAXMOV 120 t_jogador *jogador; double maxFound = -2;; int filhos = 0; if(profundidade == 0) { return funcaoHeuristica(time,jogoOrig); } else { if(SDL_GetTicks() - t0 > tempoMax) { return -2; } char outroTime = (time==P1) ? P2 : P1; t_jogo jogo[MAXMOV]; t_jogada jogadaPossivel[MAXMOV]; double valor[MAXMOV]; t_miniMaxData parametros[MAXMOV]; SDL_Thread *threads[MAXMOV]; int c; for(c=0 ; c<MAXMOV ; c++) { memcpy(&jogo[c],jogoOrig,sizeof(*jogoOrig)); memcpy(&jogadaPossivel[c],jogada,sizeof(*jogada)); valor[c] = -3.0; parametros[c].time = outroTime; parametros[c].beta = -alfa; parametros[c].alfa = -beta; parametros[c].cor = -cor; parametros[c].profundidade = profundidade-1; parametros[c].tempoMax = tempoMax; parametros[c].primeiro = 0; parametros[c].t0 = t0; } if(time == P1) jogador = &jogoOrig->p1; else jogador = &jogoOrig->p2; unsigned int movimentos[14]; unsigned int numMov = 0; unsigned int capturas[14]; unsigned int numCapt = 0; //para cada peca do jogador, calcula seus movimentos possiveis int i; unsigned char *pecaPos[2] = {jogador->peaoPos,jogador->torrePos}; unsigned char numPeca[2] = {jogador->numPeoes,jogador->numTorres}; int t; for(c=0,t=0 ; t<2 ; t++) { for(i=0 ; i<numPeca[t] ; i++ ) { filhos++; unsigned int pos = pecaPos[t][i]; movimentosPossiveis(jogo[c].tabuleiro,pos,movimentos,&numMov,capturas,&numCapt); unsigned int peca = jogo[c].tabuleiro[pos]; //executa todas as jogadas possiveis unsigned int j; unsigned int *tipoMovimento[2] = {capturas,movimentos}; unsigned int numMovimento[2] = {numCapt,numMov}; int m; for(m=0 ; m<2 ; m++) { for(j=0 ; j<numMovimento[m] ; j++,c++) { ERR("c:%d\t",c); ERR("Jogo: %p\n",&jogo[c]); jogadaPossivel[c].time = time; jogadaPossivel[c].pecaOrigem = jogo[c].tabuleiro[pos]; jogadaPossivel[c].posOrigem = pos; jogadaPossivel[c].posDestino = tipoMovimento[m][j]; executaJogada(&jogo[c],&jogadaPossivel[c]); double val; //verifica se a jogada levara ao termino do jogo int estado = fimDeJogo(&jogo[c],outroTime); if(estado == DRAW) { valor[c] = 0; } else if(estado == time) { valor[c] = 1; } else if(estado == outroTime) { valor[c] = -1; } else { //aplica negamax em outra thread parametros[c].jogada = &jogadaPossivel[c]; parametros[c].jogoOrig = &jogo[c]; threads[c] = SDL_CreateThread(miniMaxThread,(void* )(¶metros[c])); } }//end for movimento }//end for tipo de movimento }//end for peca }//end for tipo de peca int totalBranches = c; maxFound = valor[0]; int maxIndex = 0; //espera todas as threads terminarem, selecionando a melhor jogada for(c=0 ; c<totalBranches ; c++) { //se nao eh um nodo folha if(valor[c] < -2.1) { int status; SDL_WaitThread(threads[c],&status); //copia o valor encontrado valor[c] = parametros[c].val; } if(valor[c] > maxFound) { maxFound = valor[c]; maxIndex = c; } } //if(primeiro) ERR("Para O: %u\t D:%u\n",jogadaPossivel[maxIndex].posOrigem,jogadaPossivel[maxIndex].posDestino); memcpy(jogada,jogadaPossivel+maxIndex,sizeof(*jogada)); } return maxFound; }
double miniMaxB(char time,t_jogada *jogada,t_jogo *jogoOrig,double alfa, double beta, int cor, unsigned int profundidade,unsigned int tempoMax,char primeiro,unsigned int t0) { t_jogador *jogador; int filhos = 0; if(profundidade == 0) { return funcaoHeuristica(time,jogoOrig); } else { if(SDL_GetTicks() - t0 > tempoMax) { return -2; } char outroTime = (time==P1) ? P2 : P1; t_jogo jogo; memcpy(&jogo,jogoOrig,sizeof(*jogoOrig)); t_jogada melhorJogada; if(time == P1) jogador = &jogo.p1; else jogador = &jogo.p2; unsigned int movimentos[14]; unsigned int numMov = 0; unsigned int capturas[14]; unsigned int numCapt = 0; //para cada peca do jogador, calcula seus movimentos possiveis int i; unsigned char *pecaPos[2] = {jogador->peaoPos,jogador->torrePos}; unsigned char numPeca[2] = {jogador->numPeoes,jogador->numTorres}; int t; t_jogo outroJogo; for(t=0 ; t<2 ; t++) { for(i=0 ; i<numPeca[t] ; i++ ) { filhos++; //faz uma copia do jogo original memcpy(&jogo,jogoOrig,sizeof(*jogoOrig)); memcpy(&outroJogo,jogoOrig,sizeof(*jogoOrig)); unsigned int pos = pecaPos[t][i]; movimentosPossiveis(jogo.tabuleiro,pos,movimentos,&numMov,capturas,&numCapt); unsigned int peca = jogo.tabuleiro[pos]; unsigned int k; //aplica o negamax para cada jogada possivel unsigned int j; unsigned int *tipoMovimento[2] = {capturas,movimentos}; unsigned int numMovimento[2] = {numCapt,numMov}; int m; for(m=0 ; m<2 ; m++) { for(j=0 ; j<numMovimento[m] ; j++) { //faz uma copia do jogo original memcpy(&jogo,jogoOrig,sizeof(*jogoOrig)); jogada->time = time; jogada->pecaOrigem = jogo.tabuleiro[pos]; jogada->posOrigem = pos; jogada->posDestino = tipoMovimento[m][j]; //copia a jogada t_jogada bakJogada; if(primeiro) memcpy(&bakJogada,jogada,sizeof(*jogada)); executaJogada(&jogo,jogada); double val; //verifica se a jogada levara ao termino do jogo int estado = fimDeJogo(&jogo,outroTime); if(estado == DRAW) { val = 0; } else if(estado == time) { val = 1; } else if(estado == outroTime) { val = -1; } else val = -miniMaxB(outroTime,jogada,&jogo,-beta,-alfa,-cor,profundidade-1,tempoMax,0,t0); if(val >= beta) { if(primeiro) memcpy(jogada,&bakJogada,sizeof(*jogada)); return val; } if (val > alfa) { if(primeiro) memcpy(&melhorJogada,&bakJogada,sizeof(*jogada)); alfa = val; } }//end for movimento }//end for tipo de movimento }//end for peca }//end for t if(primeiro) memcpy(jogada,&melhorJogada,sizeof(*jogada)); } return alfa; }