草庐IT

c++ - 在内存中实现无限 map

coder 2024-02-18 原文

我将不得不在程序内存中实现无穷无尽的 3D 栅格 map 。 map 可能会也可能不会从 [0;0;0] 开始。 map 的Y坐标限制为255,其他可能无限大。 (是的,现在,你可能已经猜到这是一张 Minecraft map )
我需要创建一些具有简单 McMap::getBlock(int x, short y, int z)McMap::setBlock(int x, short y, int z) 方法。意味着我需要能够读取和写入数据。我还希望能够删除 block ,从而释放内存
用户应该为此目的做什么?我认为最好的解决方案是一些具有这种结构的表:

int x|short y|int z|int block id|other values...
-----+-------+-----+------------+---------------
   55|     21|  666|           1|

但是我如何在不使用真正的 MySql 的情况下使用 C++ 实现它(那将是真正的矫枉过正)?另外,我不想在程序退出时保留 map ,所以我希望数据程序内存中。
再一次,假设 map 是无限的,因此坐标可能是任何。也不要忘记可以绘制非常远的点。
另外,需要注意一件非常重要的事情:我需要有一个有效的方法来阻止 X、Y 和 Z 坐标 - 我不想想遍历所有 block 找到其中之一。
我已经包含了boost图书馆。

最佳答案

我假设您可能不需要在内存时间内拥有 Minecraft 世界的整个可能区域,因为那将非常巨大 (1024000000 KM^2)。如果您只是想在内存中保留任何人通常会在游戏中最终访问的区域,我认为使用 STL(标准模板库)访问它是完全可行的。

Minecraft 世界总是以 16X16X255 block 的 block 形式加载到游戏中。您可以将程序 block 存储在 std::map 中。这种方法有几个优点。首先是它允许根据 Far Lands 的 wiki 条目表示远远超出 map 可玩区域的位置。 .它还允许对 Minecraft map 进行稀疏表示,这将非常类似于实际 Minecraft map 的渲染方式。只有您用于程序的 block 才会加载到 std::map 中,并希望保持合理的内存使用。您将能够代表任何区域,无论它在整个 Minecraft map 区域的可玩区域中的位置如何。

要实现这一点,您只需首先创建世界数据类型:

using namespace std;
struct Block
{
     // Whatever information you care to store here...
};
typedef vector<block> Chunk;
typedef map<int, map<int, Chunk> > World;

然后访问单个 block :

Block McMap::getBlock(int x, short y, int z)
{
    const int WIDTH = 16; // You might want to store these constants elsewhere
    const int HEIGHT = 255;
    int chunkx = x / WIDTH;
    int chunkz = z / WIDTH;
    return yourWorld[chunkx][chunkz][x + z * WIDTH + y * HEIGHT * WIDTH];
}

删除 block :

void McMap::eraseChunk(int x, int z)
{
    if (yourWorld.find(x)) // Tests to make sure that row exists in the map.
        yourWorld[x].erase(z);
}

使用此方法的另一个好处是,通过为 block 创建一个巧妙的构造函数,而不是像我那样仅使用 typdedef,您可以在需要访问新 block 时自动生成 block 世界 std::map 类似于 Minecraft 中仅当您访问它们时才生成 block 的方式。每当您访问映射中尚不存在的对象时,它都会调用该对象的默认构造函数。

关于c++ - 在内存中实现无限 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15720341/

有关c++ - 在内存中实现无限 map的更多相关文章

  1. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  2. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby-on-rails - 如何在 Ruby on Rails 中实现无向图? - 2

    我需要在RubyonRails中实现无向图G=(V,E)并考虑构建一个Vertex和一个Edge模型,其中Vertex有_多条边。由于边恰好连接两个顶点,您将如何在Rails中执行此操作?您是否知道任何有助于实现此类图表的gem或库(对重新发明轮子不感兴趣;-))? 最佳答案 不知道有任何现有库在ActiveRecord之上提供图形逻辑。您可能必须实现自己的Vertex、EdgeActiveRecord支持的模型(请参阅Rails安装的rails/activerecord中的vertex.rb和edge.rb/test/fixtur

  5. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. ruby - 在 ruby​​ 中使用 .try 函数和 .map 函数 - 2

    我需要从json记录中获取一些值并像下面这样提取curr_json_doc['title']['genre'].map{|s|s['name']}.join(',')但对于某些记录,curr_json_doc['title']['genre']可以为空。所以我想对map和join()使用try函数。我试过如下curr_json_doc['title']['genre'].try(:map,{|s|s['name']}).try(:join,(','))但是没用。 最佳答案 你没有正确传递block。block被传递给参数括号外的方法

  9. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  10. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

随机推荐