Текстовая приключенческая игра

Я наблюдаю за техническим лагерем, где один из них создал код для текстовой видеоигры, в которой у него проблемы с отображением результатов. Хотя программа компилируется и работает правильно, она не добавит здоровья игроку, когда выбрано «лечение», и мы также получим ноль, когда пользователь выберет «атака». У меня ограниченные знания в программировании, и я стараюсь помочь ему как можно лучше, чтобы его опыт здесь был приятным и полезным. Если бы вы могли предложить любую помощь или совет, мы были бы очень благодарны. Вот код:

// Test for hard stuff.cpp : Defines the entry point for the console application.
//
// Bigger proj
// Constructors will make characters with rolling statistics

#include "stdafx.h"#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace std;
// declaring function for hit power
//int power( int str, int def);

int command;class character
{
public:
character();
//~character();
string name;
float str;
float def;
float health;   // hit points
float regen;    // health regen amount
float roll;     // for random value
float ouch;     // amount of attack damage
float getAttack(void);
float getHeal(void);
void setRegen(float reg);
//void setHeal(float healAmt);

private:};

character::character()
{
srand(time_t(NULL));
str = rand() % 30 + 5;
def = rand() % 30 + 5;
health = 100;
//Output to check the constructor is running properly
cout<< "Character has been created.\n";
}

void character::setRegen( float reg )
{
regen = reg;
}float character::getAttack()
{
//defines the magnitude/power of attack
//function shows how much damage is inflicted// ouch is how much damage is done
roll = rand() % 20 + 1; // range between 1 &20

if (roll <= 11)
{
ouch = str - (def /2);
}

else if ((roll <= 17) && (roll >= 12))
{
ouch = (str * 2) - (def / 2);
}

else if ((roll <= 20) && (roll >= 18))
{
ouch = (str * 3) - (def / 2);
//cout << "CRITICAL HIT!!";
}

return ouch;

}

float character::getHeal()
{
//this is what happens when you chose to heal
regen = rand() % 20 + 3;
cout << "regen value= " << regen<< ".\n";
return regen;
}

/*character::~character()
{
str = 0;
def = 0;
health = 0;
// Output to check the destructor is running properly
cout << "Character has been destroyed\n";
} */int _tmain(int argc, _TCHAR* argv[])
{
//Class objects
character user, computer;
//Hard code in a name for the computer's player
computer.name = "ZOID\n";

float attackDamage;
float healthAdded;

user.setRegen(void);

//Recieve data for the user's player
cout<< "Please enter a name for your character:\n";
cin>> user.name;

//Output name and stats to the user
cout<< "\nYour name is: " << user.name << endl;
cout << "here are your statistics: \n"<< "strength:   " << user.str << endl
<< "Defense:    " << user.def << endl
<< "Health:     " << user.health << endl;

cout<< "oh no an oppenent appeared!!!\n";
cout<< "you will have to fight him!" << endl<< endl;

cout << "opponent's health: 100"  << endl

<< "what would you like to do: heal (1), attack(2), or run(3).\n";
cin>> command;switch(command)
{
case 1 :

healthAdded = user.getHeal();

cout<< ""<<user.name <<" has regenerated " << healthAdded << " health.\n";

break;

case 2 :

attackDamage = user.getAttack();

cout << "" <<user.name <<" did " << attackDamage << " damage to the opponent!\n";

break;

case 3:

cout<< ""<<user.name<<" got away!\n";

break;

default:
cout<< "Please enter a valid choice!";

} //end switch

return 0;

}

7

Решение

Я постараюсь помочь как можно лучше за раз. Мои номера строк могут немного отличаться от ваших, поэтому не стесняйтесь осмотреться.

В:

 115     user.setRegen(void);

setRegen объявлен принять float:

 20 class character
21 {
22 public:
.
.
.
34     void setRegen(float reg);

Так что вы не можете пройти void, Кстати, в C ++ принято просто ничего не передавать при вызове функции, которая не принимает параметров, вместо передачи явного void, Однако явное void все в порядке.

getHeal() Функция вычисляет случайное количество, чтобы вылечить персонажа, но фактически не увеличивает health переменная-член. Вы можете реализовать исцеление таким образом, см. Строку 92:

 87 float character::getHeal()
88 {
89     //this is what happens when you chose to heal
90     regen = rand() % 20 + 3;
91     cout << "regen value= " << regen<< ".\n";
92     health += regen;
93     return regen;
94 }   Z

Вы также не снижаете здоровье оппонента при атаке. Один из способов сделать это — передать ссылку оппоненту на getAttack() и изменив его там:

 58 float character::getAttack(character& opponent)
59 {
60 //defines the magnitude/power of attack
61     //function shows how much damage is inflicted
62
63
64     // ouch is how much damage is done
65     roll = rand() % 20 + 1; // range between 1 &20
66
67     if (roll <= 11)
68     {
69         ouch = str - (def /2);
70     }
71
72     else if ((roll <= 17) && (roll >= 12))
73     {
74         ouch = (str * 2) - (def / 2);
75     }
76
77     else if ((roll <= 20) && (roll >= 18))
78     {
79         ouch = (str * 3) - (def / 2);
80         //cout << "CRITICAL HIT!!";
81     }
82
83     opponent.health -= ouch;
84
85     return ouch;
86
87 }

Вам также необходимо изменить объявление (прототип) для getAttack():

 20 class character
21 {
22 public:
.
.
.
32     float getAttack(character& opponent);

…и как это называется main():

152         case 2 :
153
154             attackDamage = user.getAttack(computer);
155
156             cout << "" <<user.name <<" did " << attackDamage << " damage to the opponent!\n";
157
158             break;

Я также заметил, что программа вообще не зацикливается. Он просто принимает одно действие, выполняет его и завершает работу. Игра может быть веселее, если она будет повторяться, пока один из игроков не умрет.

И последнее, что при использовании случайных чисел, вы звоните srand ровно один, обычно в начале выполнения программы. Вы звоните это каждый раз, когда character создано.

Вот это бесстыдная заглушка для одного из моих предыдущих ответов об использовании rand,

Я сделал несколько модификаций для вас. Вот ссылка на ideone с тем же кодом, что и ниже:

// Test for hard stuff.cpp : Defines the entry point for the console application.
//
// Bigger proj
// Constructors will make characters with rolling statistics

//#include "stdafx.h"#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace std;
// declaring function for hit power
//int power( int str, int def);

int command;class character
{
public:
character();
//~character();
string name;
float str;
float def;
float health;   // hit points
float regen;    // health regen amount
float roll;     // for random value
float ouch;     // amount of attack damage
float getAttack(character& opponent);
float getHeal(void);
void setRegen(float reg);
bool IsAlive() const;
//void setHeal(float healAmt);

private:};

character::character()
{
str = rand() % 30 + 5;
def = rand() % 30 + 5;
health = 100;
//Output to check the constructor is running properly
cout<< "Character has been created.\n";
}

bool character::IsAlive() const
{
return health > 0.0f;
}

void character::setRegen( float reg )
{
regen = reg;
}float character::getAttack(character& opponent)
{
//defines the magnitude/power of attack
//function shows how much damage is inflicted// ouch is how much damage is done
roll = rand() % 20 + 1; // range between 1 &20

if (roll <= 11)
{
ouch = str - (def /2);
}

else if ((roll <= 17) && (roll >= 12))
{
ouch = (str * 2) - (def / 2);
}

else if ((roll <= 20) && (roll >= 18))
{
ouch = (str * 3) - (def / 2);
//cout << "CRITICAL HIT!!";
}

opponent.health -= ouch;

return ouch;

}

float character::getHeal()
{
//this is what happens when you chose to heal
regen = rand() % 20 + 3;
cout << "regen value= " << regen<< ".\n";
health += regen;
return regen;
}
/*character::~character()
{
str = 0;
def = 0;
health = 0;
// Output to check the destructor is running properly
cout << "Character has been destroyed\n";
} */int main()
{
srand(time_t(NULL));
//Class objects
character user, computer;
//Hard code in a name for the computer's player
computer.name = "ZOID\n";

float attackDamage;
float healthAdded;

user.setRegen(42.0);

//Recieve data for the user's player
cout<< "Please enter a name for your character:\n";
cin>> user.name;

//Output name and stats to the user
cout<< "\nYour name is: " << user.name << endl;
cout << "here are your statistics: \n"<< "strength:   " << user.str << endl
<< "Defense:    " << user.def << endl
<< "Health:     " << user.health << endl;

cout<< "oh no an oppenent appeared!!!\n";
cout<< "you will have to fight him!" << endl<< endl;

cout << "opponent's health: 100"  << endl;while (user.IsAlive() && computer.IsAlive())
{
cout << "Str: " << user.str << "\t"<< "Def: " << user.def << "\t"<< "Health: " << user.health << "\t"<< "\n";

cout << "what would you like to do: heal (1), attack(2), or run(3).\n";
cin>> command;

switch(command)
{
case 1 :

healthAdded = user.getHeal();

cout<< ""<<user.name <<" has regenerated " << healthAdded << " health.\n";

break;

case 2 :

attackDamage = user.getAttack(computer);

cout << "" <<user.name <<" did " << attackDamage << " damage to the opponent!\n";

break;

case 3:

cout<< ""<<user.name<<" got away!\n";

break;

default:
cout<< "Please enter a valid choice!";

} //end switch
}
return 0;

}
6

Другие решения

В общем, один из способов решения этой проблемы состоит в том, чтобы исследовать, что происходит построчно, и определить, что делает каждая строка. Иногда это долго (правда, много раз), но также делает хорошую работу, чтобы вы ничего не пропустили. В этом конкретном случае давайте рассмотрим проблему лечения.

Когда вы вводите оператор switch и нажимаете случай 1 (исцеление), это первое, что делает код, это назначает результаты user.getHeal () для healthAdded. Отсюда вы должны войти в getHeal () и посмотреть, что он делает. getHeal () получает номер регенерации и назначает его регенерации. Затем он печатает regen и, наконец, возвращает значение, которое вы сохранили в regen.

Теперь, когда мы знаем, что делает getHeal (), мы можем вернуться к нашему случаю 1: и полностью сказать, что делает первая строка. Он принимает значение регенерации, встроенное в getHeal (), и назначает его для healthAdded.

case 1: затем печатает значение в healthAdded до перерыва; заявление. Перерыв; заканчивает дело 1.

Итак, что ваш код сделал в форме быстрого списка:

  • генерировать исцеляющую ценность
  • напечатайте это дважды

То, что вы хотели сделать, это изменить здоровье пользователя на основе значения регенерации, поэтому у вас есть пропущенный шаг: изменение значения user.health с помощью номера регенерации, который вы встроили в getHeal ().

Проблема с ущербом от атаки аналогична, попробуйте сравнить то, что вы хотите, чтобы код делал в целевых терминах, с тем, что вы видите на самом деле.

2