Поиск пустых комнат в приключенческой игре?

Я работаю над приключенческой игрой для проекта C++. Цель в основном состоит в том, чтобы иметь кучу комнат, определенных классом. Затем соедините их все вместе, используя карту. У меня все работает, кроме проверки наличия места и проверки того, что ввод не принимается за пустую комнату. Например, он сказал бы «Там ничего нет», а затем повторно предложил бы пользователю направление движения. В настоящее время моя программа просто падает, если в направлении нет места, и это направление выбрано. В настоящее время я настроил его, чтобы, по крайней мере, убедиться, что введено правильное направление (север, юг, восток или запад), но он не проверяет, доступно ли это направление. Кто-нибудь знает хороший способ сделать это?

main.cpp

    #include <iostream>
    #include <string>
    #include <map>

    #include "room.h"

    using namespace std;

    int main()
    {
        /* ---------- Variable Declerations ---------- */
        string exitChoice;

        /* ---------- Room Intialization ---------- */
        room *kitchen = new room("Kitchen", "You are in the Kitchen. Pots and pans dangle above your head as you look across the room.");
        room *diningRoom = new room("Dining Room", "You are in the Dining Room. You see a large table in the center of the room complete with a set of chairs. It seems no one has ate here in quite som time.");
        room *garage = new room("Garage", "You are in the Garage. There are tools spread across the concerte floor complete with a Jeep Grand Cherokee on jack stands.");
        room *masterBed = new room("Master Bed Room", "You are in the Bed Room. A large Master Bed greets you as you walk into the room. You can see a large master bath as weel in the backround");
        room *hallway = new room("Hallway", "You are in the Hallway. A large set of stairs leads to the second floor, complete with a set to the basement. You also see a grand front door.");
        room *familyRoom = new room("Family Room", "You are in the Family Room. You see a dark leather couch in front of you as well as a brand new LCD TV. It aappears South Park is on TV.");
        room *bathRoom = new room("Bath Room", "You are in the Bath Room. A small room containing just a toilet is in front of you.");
        room *frontLawn = new room("Front Lawn", "You are in the Front Lawn. You are on a pathway and observe freshly cut grass as well as several trees scattered across the yard.");
        room *backLawn = new room("Back Lawn", "You are in the Back Lawn. You see 'Spot' running around chasing a tennis ball, as well as his dog house. A large wooden fence keeps him in the yard.");

        /* ----------Room Links---------- */

        /* Kitchen */
        kitchen->link(diningRoom, "North");
        kitchen->link(garage, "East");
        kitchen->link(masterBed, "South");
        kitchen->link(hallway, "West");

        /* Dining Room */
        diningRoom->link(kitchen, "South");
        diningRoom->link(familyRoom, "West");

        /* Master Bed Room */
        masterBed->link(kitchen, "North");
        masterBed->link(bathRoom, "West");

        /* Garage */
        garage->link(kitchen, "West");
        garage->link(backLawn, "East");

        /* Back Lawn */
        backLawn->link(garage, "West");

        /* Family Room */
        familyRoom->link(diningRoom, "East");
        familyRoom->link(hallway, "South");

        /* Hallway */
        hallway->link(familyRoom, "North");
        hallway->link(kitchen, "East");
        hallway->link(bathRoom, "South");
        hallway->link(frontLawn, "West");

        /* Front Lawn */
        frontLawn->link(hallway, "East");

        /* Bath Room */
        bathRoom->link(hallway, "North");
        bathRoom->link(masterBed, "East");

        /* ----------Gameplay---------- */
        room *currentRoom = kitchen;

        while (exitChoice != "quit")
        {
            currentRoom->printRoom();
            cout << endl;

            currentRoom->printLiked();

            cout << "Which exit? (Or 'quit'):";
            cin >> exitChoice;

            if(exitChoice != "quit" && exitChoice != "North" && exitChoice != "South" && exitChoice != "East" && exitChoice != "West")
            {
                cout << "Invalid Entry!" << endl;
                cout << "Which exit? (Or 'quit'):";
                cin >> exitChoice;
            }

            cout << "You move to the " << exitChoice << "..." << endl;
            currentRoom->getLinked(exitChoice);

            currentRoom = currentRoom->getLinked(exitChoice);
        }
    }

комната.ч

#ifndef ROOM_H
#define ROOM_H

using namespace std;

#include <string>
#include <iostream>
#include <map>

class room
{
    private:
        string name;
        string description;

    public:

    /* Constructor Prototypes */
    room(string, string);
    room(string);

    /* Get Name */
    string getName()
    {
        return name;
    }

    /* Get Description */
    string getDescription()
    {
        return description;
    }

    /* Print Room Information */
    void room :: printRoom()
    {
        cout << "--" << getName() << "--" << endl;
        cout << getDescription() << endl;
    }

    /* Map */
    map<string, room*> exits;

    /* Link Function*/
    void link(room *room, string direction)
    {
        exits[direction] = room;
    }

    /* Print Linked Rooms */
    void printLiked()
    {
        map<string, room*> :: iterator it;

        cout << endl;

        for(it = exits.begin(); it != exits.end(); ++it)
        {
            cout << "Exit: ";
            cout << it->first << " (" << it->second->getName() << ")" << endl;

        }

        cout << endl;
    }

    /* Get linked room */
    room* getLinked(string direction)
    {
        map<string, room*> :: iterator it;

        it = exits.find(direction);

        if(it != exits.end())
        {
            return it->second;
        }
        else
        {
            return NULL;
        }


    }





};

#endif

room.cpp

 #include <iostream>
    #include <string>
    #include <map>

    using namespace std;

    #include "room.h"

        /* Constructor with Name and Description */
        room :: room(string _name, string _description)
        {
            name = _name;
            description = _description;
        }


        /* Contrsuctor with Name */
        room :: room(string _name)
        {
            name = _name;
        }

новый фрагмент файла main.cpp

        room* possibleNewRoom = currentRoom->getLinked(exitChoice);

        if (possibleNewRoom != 0)
        {
            currentRoom = possibleNewRoom;

            cout << "You move to the " << exitChoice << "..." << endl;
            currentRoom->getLinked(exitChoice);

            currentRoom = currentRoom->getLinked(exitChoice);
        }
        else
        {
            cout << "There are no exits in that direction." << endl;
        }

person Community    schedule 22.11.2012    source источник


Ответы (2)


Тебе нужно:

room* possibleNewRoom = currentRoom->getLinked(exitChoice);

if (possibleNewRoom != 0)
{
    currentRoom = possibleNewRoom;
}
else
{
    std::cout << "Ouch - you cannot move that way" << std::endl;
}
person Keith    schedule 22.11.2012

Наиболее распространенный способ сделать это — ввести направленные элементы в класс Room:

class Room {
    // ...
    Room *north, *south, *east, *west;
    // ...
    Room() : north(NULL), south(NULL), east(NULL), west(NULL)
    { /* ... */ }
};

Затем вы соединяете комнаты друг с другом следующим образом:

Room* kitchen = new Room // ...
Room* hallway = new Room // ...
kitchen->north = hallway;
hallway->south = kitchen;

Когда вы пытаетесь двигаться в направлении, вы просто проверяете, является ли элемент для этого направления NULL:

// Player wants to go north.
if (this->north == NULL) {
    // Tell the player that's not possible.
} else {
    // OK, we can go to this->north.
}

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

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

person Nikos C.    schedule 22.11.2012
comment
Наличие отдельных именованных элементов для подключенных комнат делает менее удобным написание обобщенных алгоритмов, например для всех подключенных комнат выполните X. Было бы лучше иметь какую-то карту из обобщенного перечисления направлений (СЕВЕР, ЮГ, ВОСТОК, ЗАПАД, ВВЕРХ ПО ЛЕСТНИЦЕ, ВВЕРХ ПО ВЕРЕВКЕ, ВНИЗ ПО ЛЮКУ, СЕВЕРО-ВОСТОК, DENNIS и т. д.) - person HostileFork says dont trust SE; 22.11.2012
comment
Спасибо за ответ. Я вижу, что это работает очень хорошо, если бы проект пошел дальше, но, учитывая мои оценки для проекта, ответ Кита работал лучше. - person ; 22.11.2012
comment
@HostileFork Я не согласен с этим. ВВЕРХ — это не направление. Это действие. И никакая карта не должна быть в этом замешана. Когда игра обрабатывает UP LADDER, она должна просто переместить игрока в другое место. Общие свойства направления света предназначены для обработки простых команд ВВЕРХ, а не ПОДЪЕМА ПО ЛЕСТНИЦЕ. - person Nikos C.; 22.11.2012
comment
Мы должны согласиться, чтобы не согласиться. Эти игры, как правило, графические, с несколькими выходами из каждой комнаты. Вы можете быть в комнате с лестницей и веревкой, ведущими вверх, и я бы сказал, что ИДТИ — это глагол, а ВВЕРХ — вообще искусственная конструкция, которая не применяется системой (как предполагает ваш волшебный портал). Если бы это не было классным упражнением, я бы посоветовал заглянуть в библиотеку Boost Graph, чтобы представлять игровую карту... потому что графы - это то, о чем эти игры. - person HostileFork says dont trust SE; 22.11.2012
comment
Карты @HostileFork негибки в динамической среде. У вас должна быть только одна карта, которая пытается расположить физический игровой мир с точки зрения сторон света. Взаимодействия не должны осуществляться с картами. Например, для вашего примера с лестницей вы можете взять лестницу и разместить ее в другом месте. Это означало бы, что вы должны обновить свою карту, когда это произойдет. Но на самом деле вам даже не нужна карта. Все, что вам нужно, — это обработчики действий игрока, которые анализируют текущее состояние мира и перемещают игрока по мере необходимости. Внедрение графов в этот процесс усложняет работу, а выгоды нет. - person Nikos C.; 22.11.2012
comment
Если вы считаете, что выходы — это объекты, то это совершенно другая модель, но она также не совсем совместима с вашими N полями фиксированного направления в объекте. Немного напоминает мне Adventure Construction Set... ваша игра была написана на основе системы стеков и триггеры, а коробка с деталями, которая у вас была, могла делать такие вещи, как создание Object ID 134: невидимая крышка, а затем лампа могла использовать команду удаления всех объектов с ID в стеке. Зависит от игры; если разреженная 2D/3D-матрица использует для этого абстракцию, если это использует график. - person HostileFork says dont trust SE; 22.11.2012