如何创建一维数组来保存多个二维数组?

时间:2012-07-26 08:02:46

标签: c++ arrays

我有一个我一直在努力的游戏。这是一款基于文本的RPG冒险游戏。我希望让玩家使用简单的文本命令导航世界。我已经设置好了,所以世界应该分为“区域”或数组。每个区域都是自定义数据类型Location,由二维数组组成。我将使用两个变量来跟踪玩家位置,这实际上是“区域”网格上的点位置的两个索引值。当玩家输入诸如“北”,“南”,“东”或“西”的方向命令时,它将增加或减少这些值以“移动”玩家。当它们到达过渡区时,它会将它们移动到另一个“区域”。我在想我可以有一个包含所有区域的数组。过渡区只会升高或降低主阵列的索引以“转换”到下一个区域。我当然会让过渡空间有一个值来存储玩家最终会在下一个区域的网格上的位置。我只是想知道如何制作这个“主阵列”来保存区域数组。只要问一下我是否有什么东西;解释得不够好。提前谢谢。

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;
};

这就是我设想它的方式
EgForest

[] [] []
[] [] []
[] [] []
   ^
    过渡区域将使用存储的值destX和destY
将玩家移动到下一个“区域”中的目的地
SRavine

这个地方是目的地 V
[] [] [] [] []
[] [] [] [] []
[] [] [] [] []
[] [] [] [] []

3 个答案:

答案 0 :(得分:0)

关于你问题的标题,你可以用C ++创建二维数组的一维数组:

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

这是一个多维度,每个子阵列的大小可以相互独立。

请注意,C ++也有固定大小的数组(也是一维的):

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

通常,比直接阵列更喜欢标准容器。这为您打开了一个算法世界(例如algorithm标题)和辅助方法(.size())。

不幸的是,C ++没有内置的多维容器,但有些库提供它们,或者你可以创建自己的容器。基本实现可能如下所示:

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();

根据数组的大小和访问顺序,您可以使用其他索引器(例如Morton / Z-Order索引)。

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);

甚至可能你甚至还要对容器进行模板化处理,以便容纳异乎寻常的容器,例如可以及时加载/保存到磁盘的容器。

答案 1 :(得分:0)

三维数组就是答案。

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

4是区域的数量,5和6是2D阵列。 如果您需要区域的可变大小,请使用指针并分配所需的金额。

答案 2 :(得分:0)

您可以将所有矩阵缩减为一个大的一维数组。对于每个区域,您都知道它与阵列的偏移量,宽度和高度。区域内的导航很简单,东/西为+/- 1,南/北为+/- region_width。遍历区域边界时需要特殊代码,要么阻止它,要么跳转到另一个区域。

我建议你将世界从一堆矩阵改为图形。图表中的位置将具有至少4个(但可能更多)的退出槽。一个插槽将有一个方向标识符(除了n,s,e,w,可能有“向上”,“向下”,“门”,“楼梯”和你喜欢的任何东西),要么隐式(对于插槽而言) )或显式(与插槽一起存储),以及该插槽所在位置的标识符。该标识符可以是“一大一维数组”中的位置索引。这种方法的缺点是更多的簿记。好处是你可以更自由地创造你的世界。该图表在特殊情况下闪耀。你可以有4个以上的出口,单向通道,或者你认为你向北走的像下水道这样的令人难以置信的地方,但它会引导你向西,或者其他一些。图形解决方案由CircleMUD使用,可能还有大多数其他MUD使用。