В последние несколько дней я писал систему, облегчающую написание текстовых приключений (аналогично Colossal Cave или Zork). У меня возникла проблема с подсистемой Item.
Три рассматриваемых класса: Комната, Дверь и Предмет.
Когда я удаляю объект Item из вектора элемента комнаты, последний объект Door в векторе двери той же комнаты повреждается. Следует отметить, что все объекты Door и Item передаются по ссылке, что позволяет писать свои собственные подклассы Door и Item и при этом использовать их в системе. Что странно, так это то, что ЕДИНСТВЕННОЕ свойство поврежденного объекта двери - это атрибут «Местоположение», который сообщает игроку, где в комнате находится дверь. Все остальные атрибуты остаются нетронутыми, это говорит мне о том, что указатель на объект двери не был перемещен, но данные, на которые он указывает, были изменены.
Это вызывает ошибку в том, как игрок видит описания дверей. Для тестирования я не давал дверям специальных описаний, их слишком много, поэтому они используют мое внутреннее консервированное описание.
You are in a large parlour room. It is obviously that of a very wealthy man.
Adorning the walls are many dusty heads of big game.
There is a door in the direction of West.
There is a door in the direction of East.
There is a door in the direction of North.
Hanging on the wall, you see a really bad ass looking sword.
Parlour] pickup sword
Picked up the Sword of the Gods
You pick up the sword.
In doing so, you feel very powerful.
There is a door in the direction of West.
There is a door in the direction of East.
There is a door in the direction of ?.
Parlour]
Игрок все еще может перемещаться из комнаты в комнату, так что с остальными данными в дверном объекте все в порядке. Однако std :: string, в которой хранится свойство «Location», была изменена. Нигде в коде я не могу изменить этот атрибут.
Кто-нибудь может понять, почему это происходит? Есть ли у меня явно очевидная ошибка в моем коде или обработке объекта? Поскольку я не могу точно определить, в каком файле это происходит, необходимо опубликовать много кода.
Вы можете скачать zip-файл всего моего кода здесь: http://www.filedropper.com/advsys
Вот мой код, это, конечно, не все, так как у меня 467 строк в 9 файлах
Это называется, когда вы пытаетесь поднять меч.
void OnPickup() {
std::cout << "You pick up the sword." << std::endl;
std::cout << "In doing so, you feel very powerful." << std::endl;
int itemNum = ParentRoom->HasItem(Name);
if (itemNum != -1) {
// Wait, the item ISN'T in the room? Then how the hell did we get HERE?
// Whatever, error out.
std::cout << "For some strange reason, you were hallucinating about the " + Name + "." << std::endl;
} else {
PlayerRef->Inventory.push_back(new GodSword(ParentRoom, PlayerRef));
ParentRoom->RemoveItem(itemNum); // Corrupts a door
//delete ParentRoom->Items[itemNum]; // SEGFAULT
}
}
Двери и предметы распределяются следующим образом.
Новому экземпляру двери передается текстовое местоположение, его положение в комнате и указатель на место назначения. Предметам передается ссылка на комнату, в которой они находятся, и ссылка на игрока.
house["parlour"].Doors.push_back(new Door("North", 'N', &house["bedroom"]));
house["parlour"].Items.push_back(new GodSword(&house["parlour"], &player));
Элементы удаляются из комнаты, как это. Распечатки дверей распечатаны для отладки.
void Room::RemoveItem(int item) {
Items.erase(Items.begin() + item);
for (int i = 0; i < Doors.size(); i++) {
std::cout << Doors[i]->GetDescription() << std::endl;
}
}
Декларация номеров ниже.
class Room {
public:
std::vector<Door *> Doors;
std::vector<Item *> Items;
std::string LongDescription;
std::string ShortDescription;
std::string Name;
bool DescribeDoors;
bool DescribeItems;
bool BeenHere;
Room();
~Room();
int HasDoor(char dir);
int HasItem(std::string name);
void OutputDescription(bool forceLong=false);
void RemoveItem(int item);
};
Я не могу думать ни о чем другом, что мне нужно добавить. Если вам нужно увидеть другой файл, или как объявлен другой класс, и т. Д ... Вы можете найти ссылку на zip выше.