简体   繁体   中英

How can i create a one-dimensional array to hold several two-dimensional arrays?

I have a game I've been working on. It is a text based RPG adventure game. I hope to have the player navigate the world using simple text commands. I have set it up so that the world should be divided into "regions" or arrays. Each region is of the custom datatype Location and is composed of a two-dimensional array. I will use two variables to track the players location which are really the two index values of the spots location on the "region" grid. When the player types in a directional command such as "north","south","east", or "west" it will increase or decrease these values to "move" the player. When they reach transition zones it will move them to another "region". I was thinking that i could have an array that holds all the regions. the transition zones would merely raise or lower the index of the master array to "transition" to the next zone. I would of course have the transition space have a value to store where on the next region's grid the player would end up on. I was just wondering how to make this "master array" to hold the region arrays. Just ask if there is anything i didn;t explain well enough. Thank you in advance.

struct Location
{
    int type, destX, destY;
    // 1 = battlefield
    //  areas where random encounters will at some future date occur
    // 2 = town
    //  areas where hopefully the foolhardy adventurer will be able to speak
    // to merchants and towns folk
    // 3 = dungeon
    //  areas with long travel times and the promise of an end boss
    //  but more importantly really awesome loot
    // 4 = transition points
    //
    string name, desc;
};

This is how I envisioned it.

EgForest

[][][]
[][][]
[][][]
^
Transition Zone would move player to the destination in the following "region" using stored values destX and destY

SRavine

this spot is the destination
V
[][][][][]
[][][][][]
[][][][][]
[][][][][]

Just regarding the headline of your question, this is you create one dimensional arrays of two-dimensional arrays in C++:

std::vector<std::vector<std::vector<Entity>>> v;

That's a multidimensional where each sub-array can have a size that is independent of each other.

Note that C++ has also fixed-size-arrays (one-dimensional, too):

std::array<std::array<std::array<int,16>,16,16>> 
         array_16_of_array_16_of_array_16_of_int;

Generally, prefer standard-containers over direct arrays. This opens you up for a world of algorithms (eg the algorithm header) and helper methods ( .size() ).

Unfortunately, C++ has no builtin multidimensional containers, but some libraries provide them, or you could make your own. A basic implementation may look like this:

template <typename T>
class surface {
public:
    typedef size_t size_type;

    surface(size_type w, size_type h) : width_(w), height_(h), data_(w*h) {}

    size_type width()  const { return width_;  }
    size_type height() const { return height_; }
    size_type size()   const { return width_*height_; }

    // These are for when you need to loop over all elements
    // without interest in coordinates.
    T  operator[] (size_type i) const { return data_[i]; }
    T& operator[] (size_type i)       { return data_[i]; }

    T  operator() (size_type x, size_type y) const { return data_[y*width_+x]; }
    T& operator() (size_type x, size_type y)       { return data_[y*width_+x]; }

    T at(size_type i) const {
        if (i>=size()) throw std::out_of_range(....);
        return (*this)[i];
    }
    T& at(size_type i) {
        if (i>=size()) throw std::out_of_range(....);
        return (*this)[i];
    }
    T at(size_type x, size_type y) const {
        if (x>=width_ || y>=height_) throw std::out_of_range(....);
        return (*this)(x,y);
    }
    T& at(size_type x, size_type y) {
        if (x>=width_ || y>=height_) throw std::out_of_range(....);
        return (*this)(x,y);
    }

private:
    size_type width_, height_;
    std::vector<T> data_;
};

...

surface<Foo> x(256,256);

x(16,12) = Foo();
x[16+12*256] = Foo();

Depending on the size and access ordering on your array, you may use other indexers (eg Morton/Z-Order indexing).

template <typename T, typename Indexer=LinearIndexer>
...
    T  operator() (size_type x, size_type y) const { return data_[Indexer()(x,y)]; }

...

surface<int, Morton> foo(102400, 102400);

And possibly you even templatize the container too allow for exotic cases like containers that can just-in-time-load/save from/to disk.

3 dimensional array is the answer.

int world[4][5][6];

4 is the amount of regions, 5 and 6 the 2D array. If you need variable sizes for the areas, use pointers and allocate the amount you need.

You could reduce all matrices into one big one-dimensional array. For each region you know its offset withing the array, and its width and height. Navigation within a region is simple, +/- 1 for east/west, +/- region_width for south/north. Special code is needed when traversing region's bounds, either to prevent it, or to jump to another region.

I would propose that you change the world from bunch of matrices into a graph. A location in a graph would have at least 4 (but maybe more) exit slots. A slot would have an identifier for direction (apart from n, s, e, w, there could be "up", "down", "door", "stairs" and anything you like), either implicit (known for the slot) or explicit (stored with the slot), and also identifier of the location to where this slot leads. This identifier could be location's index in the "one big 1D array". The drawback to this approach is more bookkeeping. The benefit is that you have more freedom in creating your world. The graph shines in special cases. You could have more than 4 exits, one-way passages, or mind-boggling areas like sewers where you think you go north, but it leads you west, or some such. The graph solution is used by CircleMUD, and probably most other MUD's.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM