/*************************************************************************** * * Função: TAB &mover uma peça no tabuleiro * ****/ int TAB_verificaVencedor(Tabuleiro *tabuleiro, char idJogador1, char idJogador2) { int x, y; int existe1 = 0, existe2 = 0; //Assertivas de entrada #ifdef _DEBUG if(!tabuleiro) printf("\n tabuleiro não existe \n"); if(idJogador1 != 'x' || idJogador2 != 'o') printf("\n Erro na associação de caracteres correspondentes ao jogador1 e/ou jogador2 \n"); #endif LIS_IrFinalLista(tabuleiro->lista); for(y = TabuleiroAltura - 1; y >= 0; --y) { LIS_tppLista lista = (LIS_tppLista)LIS_ObterValor(tabuleiro->lista); LIS_IrInicioLista(lista); for(x = 0; x < TabuleiroLargura; ++x) { Peca *peca = LIS_ObterValor(lista); if(peca) { if(PEC_obterCaracter(peca) == idJogador1) existe1 = 1; else if(PEC_obterCaracter(peca) == idJogador2) existe2 = 1; if(existe1 && existe2) // existe peca dos 2 jogadores no tabuleiro. jogo continua return -1; } LIS_AvancarElementoCorrente(lista, 1); } LIS_AvancarElementoCorrente(tabuleiro->lista, -1); } if(existe1 && !existe2) // so ha pecas do jogador 1 presentes. ele ganhou return 0; if(!existe1 && existe2) // so ha pecas do jogador 2 presentes. ele ganhou return 1; //Assertivas de saida #ifdef _DEBUG printf("Caso indefinido em TAB_verificaVencedor"); #endif return -2; }/* Fim função: TAB verifica vencedor */
/*************************************************************************** * * $FC Função: JOG &Jogar jogo * $ED Descrição da função * * Está função é toda encarregada de posicionar as pecas no * tabuleiro, identificar se uma determinada movimentação de peça * pode ou não ser realizada, principalmente da cargo de todas as * especificações de jogo detalhadas em "especificacao.pdf" * localizado nos documentos do projeto. * * $EP Parâmetros * $P Jogo *jogo * * $FV Valor retornado * * Não há valor retornado, está função recebe * coordenadas de jogo e de movimentação e as aplica no * tabuleiro, o exibindo (prompt de comando) modificado * após a realização de todos os passos. * * ***********************************************************************/ JOG_tpCondRet jogar(Jogo *jogo) { int linhaDe, linhaPara, linhaRemover = -1; char colunaDe, colunaPara, colunaRemover = -1; char idJogador[2] = {'x', 'o'}; int jogadorAtual = 0; int vencedor = -1; int distX, distY; Peca *pecaDe = NULL, *pecaPara = NULL, *pecaRemover = NULL; PecaTipo tipo; //Assertivas de entrada #ifdef _DEBUG if(!jogo) return JOG_CondRetJogoInexistente; if(!jogo->tabuleiro) return JOG_CondRetTabuleiroInexistente; #endif TAB_inicializar(jogo->tabuleiro, idJogador[0], idJogador[1]); do { TAB_imprimir(jogo->tabuleiro); printf("Vez do jogador %c.\n", idJogador[jogadorAtual]); printf("Entre com a linha da peca: "); scanf("%d", &linhaDe); //Tratamento de exceção #ifdef _DEBUG if( !linhaDe || linhaDe > 8 || linhaDe < 1){ printf("Linha fora dos limites do tabuleiro"); continue; } #endif printf("Entre com a coluna da peca: "); scanf(" %c", &colunaDe); //Tratamento de exceção #ifdef _DEBUG if(!colunaDe || tolower(colunaDe) < 'a' || tolower(colunaDe) > 'h'){ printf("Coluna fora dos limites do tabuleiro"); continue; } #endif colunaDe = tolower(colunaDe); pecaDe = TAB_obterCasa(jogo->tabuleiro, linhaDe, colunaDe); if(!pecaDe) { printf("Nao ha nenhuma peca nessa posicao. Tente novamente.\n"); continue; } if(PEC_obterCaracter(pecaDe) != idJogador[jogadorAtual]) { printf("Essa peca pertence a outro jogador. Tente novamente.\n"); continue; } printf("Entre com a linha de destino: "); scanf("%d", &linhaPara); //Tratamento de exceção #ifdef _DEBUG if( !linhaPara || linhaPara > 8 || linhaPara < 1){ printf("Linha fora dos limites do tabuleiro"); } #endif if(linhaPara < 1 || linhaPara > 8) { printf("Linha de destino invalida. Tente novamente.\n"); continue; } tipo = PEC_obterTipo(pecaDe); if(tipo == PecaNormal) { // jogador0 vai para cima, jogador 1 vai para baixo int direcao = jogadorAtual == 0 ? 1 : -1; if((linhaPara - linhaDe) * direcao <= 0) { printf("Direcao de movimento invalida. Tente novamente.\n"); continue; } } printf("Entre com a coluna de destino: "); scanf(" %c", &colunaPara); //Tratamento de exceção #ifdef _DEBUG if( !colunaPara || tolower(colunaPara) < 'a' || tolower(colunaPara) > 'h'){ printf("Coluna fora dos limites do tabuleiro"); } #endif colunaPara = tolower(colunaPara); if(colunaPara < 'a' || colunaPara > 'h' ) { printf("Coluna de destino invalida. Tente novamente.\n"); continue; } pecaPara = TAB_obterCasa(jogo->tabuleiro, linhaPara, colunaPara); if(pecaPara) { printf("Ja existe uma peca nessa posicao. Tente novamente.\n"); continue; } distX = abs(colunaPara - colunaDe); if(distX == 0) { printf("A peca se move nas diagonais. Tente novamente.\n"); continue; } distY = abs(linhaPara - linhaDe); if(distX > 2 || distY > 2) { printf("Movimento muito distante. Tente novamente.\n"); continue; } if(distX == 2 && distY == 2) { linhaRemover = (linhaPara + linhaDe) / 2; colunaRemover = (colunaPara + colunaDe) / 2; pecaRemover = TAB_obterCasa(jogo->tabuleiro, linhaRemover, colunaRemover); if(!pecaRemover) { printf("Movimento muito distante sem peca para comer. Tente novamente.\n"); linhaRemover = -1; colunaRemover = -1; continue; } else if(PEC_obterCaracter(pecaRemover) == idJogador[jogadorAtual]) { printf("Voce nao pode comer sua propria peca. Tente novamente.\n"); linhaRemover = -1; colunaRemover = -1; continue; } } else if(distX != 1 || distY != 1) { printf("Movimento invalido. Tente novamente.\n"); continue; } TAB_setarCasa(jogo->tabuleiro, linhaDe, colunaDe, NULL, 0); TAB_setarCasa(jogo->tabuleiro, linhaPara, colunaPara, pecaDe, 0); if(linhaRemover != -1 && colunaRemover != -1) { TAB_setarCasa(jogo->tabuleiro, linhaRemover, colunaRemover, NULL, 1); linhaRemover = -1; colunaRemover = -1; } if(tipo == PecaNormal && ((jogadorAtual == 0 && linhaPara == 8) || (jogadorAtual == 1 && linhaPara == 1))) { PEC_setarTipo(pecaDe, PecaDama); printf("A peca do jogador %c virou DAMA.\n", idJogador[jogadorAtual]); } jogadorAtual = !jogadorAtual; } while((vencedor = TAB_verificaVencedor(jogo->tabuleiro, idJogador[0], idJogador[1])) == -1); printf("O jogador %c venceu!\n", idJogador[vencedor]); jogo->funcaoEstado = menu; }/* Fim função: JOG &Jogar jogo */
TST_tpCondRet TST_EfetuarComando(char *ComandoTeste) { int inxLista = -1; int numLidos = -1; int CondRetEsp = -1; char StringDado[DIM_VALOR]; int i; int CondRet; int tipo = -1; int caracter = -1; StringDado[0] = 0; /* Efetuar reset de teste de peca */ if(strcmp(ComandoTeste, RESET_PECA_CMD) == 0) { for(i = 0; i < DIM_VT_PECA; i++) vtPecas[i] = NULL; return TST_CondRetOK; } /* fim ativa: Efetuar reset de teste de lista */ /* Testar Criar peca */ else if(strcmp(ComandoTeste, CRIAR_PECA_CMD) == 0) { numLidos = LER_LerParametros("iis", &inxLista, &tipo, StringDado); if((numLidos != 3) || (!ValidarInxPeca(inxLista, VAZIO))) return TST_CondRetParm; vtPecas[inxLista] = PEC_criar(tipo, StringDado[0]); return TST_CompararPonteiroNulo(1, vtPecas[inxLista], "Erro em ponteiro de nova peca."); } /* fim ativa: Testar Criar peca */ /* Testar Destruir peca*/ else if(strcmp(ComandoTeste, DESTRUIR_PECA_CMD) == 0) { numLidos = LER_LerParametros("ii", &inxLista, &CondRetEsp); if((numLidos != 2) || (!ValidarInxPeca(inxLista, INDIFERENTE))) return TST_CondRetParm; CondRet = PEC_destruir(vtPecas[inxLista]); vtPecas[inxLista] = NULL; return TST_CompararInt(CondRetEsp, CondRet, "Condicao de retorno errada ao destruir a peca.") ; } /* fim ativa: Testar Destruir peca */ /* Testar Obter Tipo da peca*/ else if(strcmp(ComandoTeste, OBTER_TIPO_CMD) == 0) { numLidos = LER_LerParametros("ii", &inxLista, &CondRetEsp); if((numLidos != 2) || (!ValidarInxPeca(inxLista, NAO_VAZIO))) return TST_CondRetParm; tipo = PEC_obterTipo(vtPecas[inxLista]); return TST_CompararInt(CondRetEsp, tipo, "Tipo errado ao obter tipo."); } /* fim ativa: Testar Obter Tipo da peca */ /* Testar Setar Tipo da peca*/ else if(strcmp(ComandoTeste, SETAR_TIPO_CMD) == 0) { numLidos = LER_LerParametros("iii", &inxLista, &tipo, &CondRetEsp); if((numLidos != 3) || (!ValidarInxPeca(inxLista, INDIFERENTE))) return TST_CondRetParm; CondRet = PEC_setarTipo(vtPecas[inxLista], tipo); return TST_CompararInt(CondRetEsp, CondRet, "Condicao de retorno errada ao setar tipo da peca."); } /* fim ativa: Testar Setar Tipo da peca */ /* Testar Obter Caracter da peca*/ else if(strcmp(ComandoTeste, OBTER_CARACTER_CMD) == 0) { numLidos = LER_LerParametros("is", &inxLista, StringDado); if((numLidos != 2) || (!ValidarInxPeca(inxLista, NAO_VAZIO))) return TST_CondRetParm; caracter = PEC_obterCaracter(vtPecas[inxLista]); return TST_CompararEspaco(StringDado, &caracter, 1, "Caracter errado ao obter caracter."); } /* fim ativa: Testar Obter Caracter da peca */ /* Testar Setar Caracter da peca*/ else if(strcmp(ComandoTeste, SETAR_CARACTER_CMD) == 0) { numLidos = LER_LerParametros("isi", &inxLista, StringDado, &CondRetEsp); if((numLidos != 3) || (!ValidarInxPeca(inxLista, INDIFERENTE))) return TST_CondRetParm; CondRet = PEC_setarCaracter(vtPecas[inxLista], StringDado[0]); return TST_CompararInt(CondRetEsp, CondRet, "Condicao de retorno errada ao setar caracter da peca."); } /* fim ativa: Testar Setar Caracter da peca */ return TST_CondRetNaoConhec; } /* Fim função: TPEC &Testar peca */