Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Cronometro

[Problema] Jogo - Ataques Negativos

Mensagens Recomendadas

Cronometro

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Localhost

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
daj

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();
                                                }

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cronometro

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
daj

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);

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cronometro

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
daj

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cronometro

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
daj

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Cronometro

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
daj

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.