Cronometro 0 Posted February 26, 2011 Report Share Posted February 26, 2011 Boa Noite. Estive hoje a criar um pequeno jogo para me divertir. Mas passa-se o seguinte, por vezes as variáveis de ataque assumem valores negativos, eu tentei fazer debug mas não consigo apanhar um caso em que dê números negativos. Código Completo: #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <time.h> #define TRUE 1 #define Action '1' #define Upgrades '2' #define Exit '3' #define Attack '1' #define Counter '2' #define CounterBonus 3 #define Defend '3' #define DefenseBonus 13 #define RtrnActionMenu '4' #define Space 32 int _Attack(int Attacker_dmg, int Defender_hp); // Simulacao de ataque com variacoes random. int _Boost(int BoostWhat, int Increment ); // Incrementacao de uma variavel. void _Pause(void); // Funcao Pause (Similar a funcao system("pause"); ). int main() { char Name[20]; int Rounds, Player_option, Enemy_option; int Player_hp = 100, Player_dmg = 10; int Enemy_hp = 85, Enemy_dmg = 8, Last_hp; Player_option = Enemy_option = Last_hp = Rounds = 0; printf("\n Name: "); scanf("%s", &Name); // Leitura do Nome. system("cls"); for(Rounds = 1; Rounds <= 15 ; Rounds++ ) // Ciclo que controla as Rondas. { printf("\n A Ninja level %d appeared!\n", Rounds); // Imprimir O numero de Rondas no ecra. while( Player_option != Exit ) // Ciclo do Menu Principal ( Quando a tecla digitada for igual a 3(Exit) o ciclo termina ). { printf("\nMenu\n"); printf("\n\t1. Action\n\t2. Upgrades\n\t3. Exit\n"); // Imprimir o "Menu" no Ecra. Player_option = getch(); // Leitura da opcao do utilizador. system("cls"); if( Player_option == Action ) // Se a opcao for igual a 1(Action), prosseguir. { while( Enemy_hp > 0 && Player_hp > 0 ) // Ciclo que controla a luta. { system("cls"); printf("\n Player HP: %d\n Enemy HP: %d\n", Player_hp, Enemy_hp); // Imprimir os hp's (Player e Enemy) no ecra. printf("\nAction Menu\n"); printf("\n\t1. Attack\n\t2. Counter-Attack\n\t3. Defend\n\t4. Return\n"); // Imprimir o "Action Menu" no ecra Player_option = getch(); // Leitura da opcao do utilizador. if( Player_option == RtrnActionMenu ) // Se a opcao for igual a 4(RtrnActionMenu) prosseguir. { system("cls"); if( Enemy_hp != 0 && Player_hp != 0 ) // Ciclo que termina o "Action Menu" e volta ao "Menu". { // Se o Player ou o Enemy tiverem hp, impossivel de retornar ao "Menu". printf("\n Cant do it! \n\n"); _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). } else break; } else if( Player_option == Attack ) // Se a opcao do utilizador for igual a 1, Prosseguir. { Last_hp = Enemy_hp; // Variável temporaria. Enemy_hp = _Attack(Player_dmg, Enemy_hp); // Variável Enemy_hp e igual ao retorno da funcao \ int _Attack(int Attacker_dmg, int Defender_hp) printf("\n Enemy Lost %dHP! \n\n", Last_hp-Enemy_hp); // Imprimir o dano. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). srand((unsigned)(time(NULL))); Enemy_option = rand() % 3 + 1; // Variavel random que controla as accoes do cpu(inimigo). if( Enemy_option == 1 ) // Se o numero gerado for igual a 1(Attack), Prosseguir. { Last_hp = Player_hp; // Variável temporaria. Player_hp = _Attack(Enemy_dmg, Player_hp); // Variável Player_hp e igual ao retorno da funcao \ int _Attack(int Attacker_dmg, int Defender_hp) printf("\n You Lost %dHP! \n\n", Last_hp-Player_hp); // Imprimir o dano. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). } else if( Enemy_option == 2 ) // Se o numero gerado for igual a 2(Counter-Attack), Prosseguir. { Last_hp = Player_hp; // Variavel temporaria. Player_hp = _Attack(Enemy_dmg+CounterBonus, Player_hp); // Variável Player_hp e igual ao retorno da funcao \ int _Attack(int Attacker_dmg, int Defender_hp) \ O dano e aumentado devido a opcao de Counter-Attack. printf("\n The Enemy Counter-Attacked!\n You Lost %dHP! \n\n", Last_hp-Player_hp); // Imprimir o dano. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). } else if( Enemy_option == 3 ) // Se o numero gerado for igual a 3(Defend), Prosseguir. { Enemy_hp = _Boost(Enemy_hp, DefenseBonus); // Aumento do HP do cpu(inimigo) de 13(DefenseBonus). printf("\n Enemy Gains %dHP! \n\n", DefenseBonus); // Imprimir o restauro de hp. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). } } else if( Player_option == Counter ) // Se a opcao do utilizador for igual a 2(Counter), Prosseguir. { srand((unsigned)(time(NULL))); Enemy_option = rand() % 3 + 1; // Variavel random que controla as accoes do cpu(inimigo). if( Enemy_option == 1 ) // Se o numero gerado for igual a 1(Attack), prosseguir. { Last_hp = Enemy_hp; // Variavel temporaria. Enemy_hp = _Attack(Player_dmg+CounterBonus, Enemy_hp); // Variável Player_hp e igual ao retorno da funcao \ int _Attack(int Attacker_dmg, int Defender_hp) \ O dano e aumentado devido a opcao de Counter-Attack. printf("\n You Counter-Attacked!\n Enemy Lost %dHP! \n\n", Last_hp-Enemy_hp); // Imprimir o dano. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). Last_hp = Player_hp; // Variavel temporaria. Player_hp = _Attack(Enemy_dmg, Player_hp); // Variável Player_hp e igual ao retorno da funcao \ int _Attack(int Attacker_dmg, int Defender_hp) printf("\n You Lost %dHP! \n\n", Last_hp-Player_hp); // Imprimir o dano no ecra. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). } else if( Enemy_option == 2 ) // Se o numero gerado for igual a 2(Counter), prosseguir. { printf("\n You Counter-Attacked!\n Nothing happened \n\n"); // Counter(utilizador) com Counter(cpu) \ = Miss. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). } else if( Enemy_option == 3 ) // Se o numero gerado for igual a 3(Defend), prosseguir. { printf("\n You Counter-Attacked!\n Nothing happened \n\n"); // Counter(utilizador) com Defend(cpu) \ = Miss. _Pause();// Funcao Pause (Similar a funcao system("pause"); ). Enemy_hp = _Boost(Enemy_hp, DefenseBonus); // Aumento do HP do cpu(inimigo) de 13(DefenseBonus). printf("\n Enemy Gains %dHP! \n\n", DefenseBonus); // Imprimir o restauro do hp no ecra. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). } } else if( Player_option == Defend ) // Se a opcao do utilizador for igual a 3(Defend), Prosseguir. { Player_hp = _Boost(Player_hp, DefenseBonus); // Aumento de HP de 13(DefenseBonus). printf("\n You Gain %dHP! \n\n", DefenseBonus); // Imprimir o Restauro de hp no ecra. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). srand((unsigned)(time(NULL))); Enemy_option = rand() % 3 + 1; // Variavel random que controla as accoes do cpu(inimigo). if( Enemy_option == 1 ) // Se o numero gerado for igual a 1(Attack), prosseguir. { Last_hp = Player_hp; // Variavel Temporaria. Player_hp = _Attack(Enemy_dmg, Player_hp); // Variável Player_hp e igual ao retorno da funcao \ int _Attack(int Attacker_dmg, int Defender_hp) printf("\n You Lost %dHP! \n\n", Last_hp-Player_hp); // Imprimir o dano no ecra. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). } else if( Enemy_option == 2 ) // Se o numero gerado for igual a 2(Counter), prosseguir. { printf("\n Nothing happened \n\n"); // Defend(Player) com Counter(Cpu) = Miss. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). } else if( Enemy_option == 3 ) // Se o numero gerado for igual a 3(Defend), prosseguir. { Enemy_hp = _Boost(Enemy_hp, DefenseBonus); // Aumento de HP(CPU) de 13(DefenseBonus). printf("\n Enemy Gains %dHP! \n\n", DefenseBonus); // Imprimir o hp no ecra. _Pause(); // Funcao Pause (Similar a funcao system("pause"); ). } } } // A PROXIMA PARTE DO CODIGO ESTA EM CONSTRUCAO. printf("\n\n\GAMEOVER\n\n"); // teste ( Modificar mais tarde ) return 0; // teste ( Modificar mais tarde ) } else if( Player_option == Upgrades ) { // Upgrades } } } } int _Attack(int Attacker_dmg, int Defender_hp) // Simulacao de ataque com variacoes random. { int temp_attack=0, minimal_damage; minimal_damage = Attacker_dmg - 4; // A variavel minimal_damage é igual ao damage efectuado pelo atacante menos 4. srand((unsigned)(time(NULL))); temp_attack = rand() % Attacker_dmg + minimal_damage; // Numero random entre minimal_damage e Attacker_dmg. return ( Defender_hp -= temp_attack ); // A funcao retorna o hp do defensor depois de ser atacado. } int _Boost(int BoostWhat, int Increment ) // Incremento de uma variavel. { return BoostWhat+Increment; // A funcao retorna o valor de uma variavel com um incremento. } void _Pause(void) // Funcao Pause (Similar a funcao system("pause"); ). { int click=0; printf("\n Please Click Space \n"); while( click != Space ) // Enquanto o utilizador nao pressionar espaço o ciclo nao termina. click = getch(); // Leitura da tecla pressionada. } Gostava de saber se me conseguem ajudar a descobrir qual é o problema que tenho no código... Antes de tudo obrigado. Cumprimentos Cronometro. Software is like sex: It’s better when it’s free. Link to post Share on other sites
Localhost 3 Posted February 26, 2011 Report Share Posted February 26, 2011 Com código (quase) todo na função main e sem estar devidamente comentado duvido muito que alguém vá sequer passar os olhos na diagonal no mesmo. here since 2009 Link to post Share on other sites
Cronometro 0 Posted February 26, 2011 Author Report Share Posted February 26, 2011 ok, vou adicionar comentários. Software is like sex: It’s better when it’s free. Link to post Share on other sites
daj 0 Posted February 26, 2011 Report Share Posted February 26, 2011 O que queres dizer com ataques negativos? Last_hp-Player_hp ou Last_hp-Enemy_hp nos printf são negativos? Tens pelo menos um caso em que não atribuis o valor correcto ao Last_hp. else if( Enemy_option == 2 ) { /* Deveria estar aqui: Last_hp = Player_hp */ Player_hp = _Attack(Enemy_dmg+CounterBonus, Player_hp); printf("\n The Enemy Counter-Attacked!\n You Lost %dHP! \n\n", Last_hp-Player_hp); _Pause(); } Link to post Share on other sites
Cronometro 0 Posted February 26, 2011 Author Report Share Posted February 26, 2011 aaaa obrigado daj, era isso mesmo, de qualquer maneira vou comentar tudo e meter aqui denovo. Software is like sex: It’s better when it’s free. Link to post Share on other sites
daj 0 Posted February 26, 2011 Report Share Posted February 26, 2011 Já agora, temp_attack = rand() % Attacker_dmg + minimal_damage; É isto que queres fazer? rand() dá-te um inteiro no intervalo [0, RAND_MAX] rand() % Attacker_dmg dá-te um inteiro no intervalo [0, Attacker_dmg[ rand() % Attacker_dmg + minimal_damage dá-te um inteiro no intervalo [minimal_damage, Attacker_dmg + minimal_damage[ Tu deves querer um inteiro no intervalo [minimal_damage, Attacker_dmg], não? temp_attack = rand() % (Attacker_dmg - minimal_damage + 1) + minimal_damage; ou, substituindo "minimal_damage" por "Attacker_dmg - 4" temp_attack = rand() % (4+1) + (Attacker_dmg - 4); Link to post Share on other sites
Cronometro 0 Posted February 26, 2011 Author Report Share Posted February 26, 2011 daj. O que eu quero com isso é. Dar um valor random entre minimal_damage ( Attacker_dmg - 4 ) e Attacker_dmg. Ou seja: temp_attack > Attacker_dmg e temp_attack < Attacker_dmg - 4. Eu fiz isto pois vou adicionar items que vao dar mais ataque e mais estabilidade diminuindo o valor entre o minimal_damage e o Attacker_dmg. Obrigado na mesma, podia ser uma falha minha. Software is like sex: It’s better when it’s free. Link to post Share on other sites
daj 0 Posted February 26, 2011 Report Share Posted February 26, 2011 Dar um valor random entre minimal_damage ( Attacker_dmg - 4 ) e Attacker_dmg. Então foi o que eu disse, é um valor no intervalo [minimal_damage, Attacker_dmg] (vá, também pode ser ]minimal_damage, Attacker_dmg[ com o que disseste). Ou seja: temp_attack > Attacker_dmg e temp_attack < Attacker_dmg - 4. Não é coerente com o que disseste em cima. Deveria ser temp_attack <= Attacker_dmg e temp_attack >= Attacker_dmg - 4 (ou sem as igualdades). Qualquer que seja o caso, não é isso que o teu código faz. Link to post Share on other sites
Cronometro 0 Posted February 26, 2011 Author Report Share Posted February 26, 2011 ups, desculpa faltoume os '='. tens razao, o meu programa nao faz isso, hmm estranho... Já agora, existe outra maneira de obter números random de forma mais "eficiente"? Software is like sex: It’s better when it’s free. Link to post Share on other sites
daj 0 Posted February 26, 2011 Report Share Posted February 26, 2011 Terás que detalhar mais o que entendes por eficiente para que outros te ajudem. Da minha parte, antecipando já a tua resposta, não conheço outra forma. Link to post Share on other sites
Cronometro 0 Posted February 26, 2011 Author Report Share Posted February 26, 2011 ok, eu depois vou procurar outra forma de os fazer. Mas por agora gostava de saber se sabes porque é que a função não gera o numero pretendido. Software is like sex: It’s better when it’s free. Link to post Share on other sites
daj 0 Posted February 26, 2011 Report Share Posted February 26, 2011 ok, eu depois vou procurar outra forma de os fazer. Mas qual é o mal da utilização do rand()? Mas por agora gostava de saber se sabes porque é que a função não gera o numero pretendido. Não estou a perceber do que estás a falar. Se te referes a porque é que rand() % Attacker_dmg + minimal_damage não gera um número no intervalo que queres, já te expliquei em cima. Se não ficou claro para ti, posso tentar detalhar um pouco mais. Não vejo de que mais possas estar a falar. Se não for disto, fornece mais detalhe. Link to post Share on other sites
Cronometro 0 Posted February 26, 2011 Author Report Share Posted February 26, 2011 já consegui, muito obrigado. Software is like sex: It’s better when it’s free. Link to post Share on other sites
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