4

Este programa debe hacer que dos bots se ataquen entre ellos, primero uno luego el otro, e hice una funcion de ataque pero no se cómo hacerla general para cuando la llame la primera vez las variables que esten dentro de la función correspondan a las del robot A, luego ataca el robot b y vuelvo a llamar la función y las variables deben coincidir con las del robot B.

#include "pch.h"
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

struct Bots
{
    const int regen = 5;
    int hp = rand() % 50 + 50;
    int attack = rand() % 10 + 10;
    int shield = 100;
    int mana = 10;
};

void BotsAttack();

int main()
{
    int remain;
    srand(time(NULL));
    Bots botA;
    Bots botB;


    if (botA.shield < 100 || botA.mana < 100)
    {
    botA.shield += 5;
    botA.mana += 5;
    }

    _getch();

}

void BotsAttack() {
    if (botA.mana >= botA.attack)
    {
        if (botA.attack > botB.shield)
        {
            remain = botB.shield - botA.attack;
            botB.hp += remain;
            botB.shield = 0;
            printf("El BotA ataca con %d de danyo.\nDestruye el escudo y la vida restante del BotB es %d", botA.attack, botB.hp);
        }
        else
        {
            botB.shield -= botA.attack;
            printf("El BotA ataca con %d e impacta con el escudo de l BotB pero no lo destruye", botA.attack);
        }
    }
    else
    {
        printf("Bot A no pudo atacar por que no le alcanza el mana\n");
    }
}
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82

2 Answers2

5

la solución mas simple seria implementar la función BotsAttack() que acepte dos parametros, una referencia al Bot atacante y la otra al bot defensor:

void BotsAttack(Bots &atacante, Bots &defensor) {
    int remain;
    if (atacante.mana >= atacante.attack)
    {
        if (atacante.attack > defensor.shield)
        {
            remain = defensor.shield - atacante.attack;
            defensor.hp += remain;
            defensor.shield = 0;
            printf("El atacante ataca con %d de danyo.\nDestruye el escudo y la vida restante del defensor es %d", atacante.attack, defensor.hp);
        }
        else
        {
            defensor.shield -= atacante.attack;
            printf("El atacante ataca con %d e impacta con el escudo de l BotB pero no lo destruye", atacante.attack);
        }
    }
    else
    {
        printf("El atacante no pudo atacar por que no le alcanza el mana\n");
    }
}

y despues puede hacer llamadas en main() de BotsAttack(botA, botB) para que A ataque a B y despues BotsAttack(botB, botA) para el caso opuesto.

Una solucion mas "orientada a objetos" pero sin encapsulación seria implementar metodos en tu struct Bots, metodos como attackBot(el_otro) , regenerarse() y un constructor. El codigo lo probe con clang++ en MacOSx pero debe funcionar bien en MS VC++

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string>

struct Bots
{
    const int regen = 5;

    std::string name;
    int hp;
    int attack;
    int shield;
    int mana;

    //Contructor con inicializacion
    Bots(std::string name_):
        name   {name_},
        hp     {rand() % 50 + 50},
        attack {rand() % 10 + 10},
        shield {100},
        mana   {10}
    {
    }

    //Metodo para mostrar su estado
    void showStats(){
        printf(" Stats para [%s] > [hp: %d] [attack: %d] [shield: %d] [mana: %d]\n",
            name.c_str(), hp, attack, shield, mana);
    }

    // Metodo de regeneracion
    void regenerate() 
    {
        if (this->shield < 100 || this->mana < 100) {
            this->shield += regen;
            this->mana += regen;
            printf(" [%s] >  se pudo regenerar [hp: %d] [attack: %d] [shield: %d] [mana: %d]\n",
                name.c_str(), hp, attack, shield, mana);
        }
    }

    //This ataca al otro
    void attackBot(Bots &other)
    {
        int remain;

        if (this->mana >= this->attack) {
            if (this->attack > other.shield) {
                remain = other.shield - this->attack;
                other.hp += remain;
                other.shield = 0;
                printf(" El %s ataca con %d de danyo.\nDestruye el escudo y la vida restante del %s es %d \n",
                 this->name.c_str(), this->attack,other.name.c_str(), other.hp);
            } else {
                other.shield -= this->attack;
                printf(" El %s ataca con %d e impacta con el escudo de el %s pero no lo destruye\n",
                 this->name.c_str(), this->attack, other.name.c_str());
            }
        } else {
            printf(" %s no pudo atacar por que no le alcanza el mana\n", this->name.c_str());
        }
    }
};


int main()
{
    int turno = 1;     //Contador de turnos
    srand(time(NULL)); //Semilla

    Bots botA("Bot A");//nuevo bot con nombre Bot A
    Bots botB("Bot B");    

    //ciclo de ataques
    while(botA.hp >= 0 && botB.hp >= 0){ //Verificar si estan vivos
        printf("====TURNO #%d =====================\n", turno);
        printf("----INICIO-----------\n");
        botA.showStats(); //Mostramos caracteristicas 
        botB.showStats();
        printf("----Regeneracion-----\n");
        botA.regenerate(); 
        botB.regenerate();
        printf("----Ataque-----------\n");
        botA.attackBot(botB); // A ataca B
        botB.attackBot(botA); // B ataca A

        turno++;
    } //Siguinte turno

    // la vida de alguno de los dos es menor o igual a 0 
    printf("====FIN #%d =====================\n", turno);
    botA.showStats();
    botB.showStats();

}
StvKrl
  • 376
  • 2
  • 4
3

Antes de compartir mi sugerencia, querría señalar algunos detalles de tu código:

  • Las cabeceras <stdio.h> , <stdlib.h> y <time.h> son de no de . Las cabeceras de C disponen de una versión adaptada a C++ que tiene el prefijo c y carece de extensión. Si realmente necesitas usar las cabeceras de C (que nunca será el caso) debes usar los equivalentes de C++ <cstdio> , <cstdlib> y <ctime> . Lee este hilo para saber por qué.
  • La cabecera <conio.h> ni siquera es estándar C y no existe en C++, consulta este hilo para saber por qué.
  • Las funciones rand() y srand() pertenecen a las librerías de C, se desaconseja usar esas utilidades en C++ pues pueden no ser portables y pueden ofrecer resultados y rendimiento cuestionables, por ello se está estudiando deprecarlo . A partir del estándar C++11 existe una completa librería de generación de números pseudoaleatorios que deberías usar en su lugar. Lee este hilo para saber por qué.
  • La función printf es las función de escritura en consola de C, en C++ se usa un objeto stream: std::cout.

Propuesta.

Puedes crear una función de ataque que le digas quién ataca y quién es atacado:

void Atacar(Bot &atacante, Bot &atacado) {
    if (atacante.mana >= atacante.attack)
    {
        if (atacante.attack > atacado.shield)
        {
            remain = atacado.shield - atacante.attack;
            atacado.hp += remain;
            atacado.shield = 0;

            std::cout << "El atacante ataca con" << atacante.attack
                      << " de danyo.\nDestruye el escudo y la vida restante"
                         " del atacado es " << atacado.hp;
        }
        else
        {
            atacado.shield -= atacante.attack;

            std::cout << "El atacante ataca con" << atacante.attack
                      << " e impacta con el escudo de el atacado pero"
                         " no lo destruye";
        }
    }
    else
    {
        std::cout << "Bot atacante no pudo atacar por que no le alcanza el mana\n";
    }
}

Con el código anterior, cuando quieras que A ataque a B, deberás hacer esta llamada:

Atacar(BotA, BotB);

Y cuando quieras hacer que B ataque a A:

Atacar(BotB, BotA);
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82