Ruby和指针 [英] Ruby and pointers

查看:259
本文介绍了Ruby和指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为一款小游戏编程地下城生成器.

I'm programming a Dungeon Generator for a litte game.

地牢是由房间组成的. room的其他房间为connections.

Dungeons are made of rooms. A room has connections to other rooms.

room.connections = [room_a, room_b]

room.number = 1 # unique id

room.connections = [room_a, room_b]
and
room.number = 1 # unique id

现在我需要按房间号来选择房间.

Now I need to pick a room by it's number.

我首先使用recursive_scan方法执行了此操作,该方法不起作用,因为房间可能会进入圆圈,并引发StackOverflowError.因此,我将一个名为already_scanned的数组与房间号放在一起,这些房间号已被放入方法的args中.然后它并没有扫描所有房间-顺便说一句,我不知道为什么,由于我逻辑上的不了解,它本来应该起作用.

I did this first with a recursive_scan method, which did not work because rooms can lead into circles, which throws a StackOverflowError. So I put an array called already_scanned with the room numbers, which were already picked into the args of the method. Then it didn't scan all rooms - btw, I have no idea why, by my logical undstandness it should have worked.

然后,我尝试将所有房间也放入一个数组中,然后迭代该数组以找到所需的房间-但在这里,我遇到了一个问题,每个房间基本上都与其他每个房间相连,至少与其他房间相连.因此数组变得和dungeon_size * array_of_rooms.length一样大.

Then I tried to put all rooms also in an array and then iterate the array for the wanted room - but here I get the problem, every room is basically connected to every other room, at least with some other rooms betwenn it; so the array gets as big as dungeon_size * array_of_rooms.length.

我现在需要的是一个显式指针-我知道ruby中几乎每个var都是一个指针,除了Fixnums和Float(也许还有其他).即使该数组变大,所以我需要一个真正的指针.

What I need now is an explicit pointer - I know almost every var in ruby is a pointer, except Fixnums and Float (and maybe some other). Even though, the array gets to big, so I need a real pointer.

(我还尝试设置一个object_ids数组并通过ObectSpace加载它们,但是可悲的是-因为我经常必须加载这些房间-带有所需object_id的房间已经被回收,如错误消息所解释.)

(I also tried to setup an array of object_ids and load them via ObectSpace, but sadly - because I often have to load the rooms - the rooms with the wanted object_id are already recycled then, as an error message explains.)

这是我的递归扫描方法:

This is my recursive scan method:

def room(number)
  recursive_scan(@map, number, []) # @map is the entrance room
end

private

def recursive_scan(room, number, scanned)
  scanned << room.room_number
  if room.room_number == number
    room
  else
    r = nil
    room.connections.each do |next_room|
      if !scanned.include?(next_room.room_number)
        r = recursive_scan(next_room, number, scanned)
      end
    end
    r
  end
end

推荐答案

Ruby中的所有内容都已经成为参考.

Everything in Ruby is already a reference.

为什么不仅仅维护房间索引?

Why not just maintain a room index?

rooms[room.number] = room

然后您可以使用rooms[i]获得任何东西.我可以通过简单地修改Room的 initialize 方法来使索引不断更新.

Then you can get anything with rooms[i]. I would keep the index up to date incrementally by simply modifying the initialize method of Room.

def initialize
  rooms[self.number] = self
  . . .
end

这不会占用太多空间,因为数组只是一个索引,它实际上没有房间的副本.从数组中获得的每个引用与通过程序中任何其他机制获得的引用本质上是相同的,并且该引用和经典指针之间的唯一真正区别是垃圾回收的开销.

This won't take up much space because the array is just an index, it doesn't actually have copies of the rooms. Each reference obtained from the array is essentially the same thing as a reference obtained via any other mechanism in your program, and the only real difference between the reference and a classic pointer is a bit of overhead for garbage collection.

如果曾经删除过房间(不只是在退出之前),则在删除时将要设置rooms[x] = nil.

If rooms are ever deleted (other than just before exit) you will want to set the rooms[x] = nil when on deletion.

我不明白为什么您需要先创建数据结构然后为房间建立索引,但是FWIW您应该能够进行递归枚举,并使用房间索引数组中的房间存在作为behere-here标志. .我不确定为什么以前没用过,但是如果写得很仔细的话,确实是必须的.

I don't see why you need to create the data structure first and then index the rooms, but FWIW you should be able to do that recursive enumeration and use the rooms presence in the room index array as the been-here flag. I'm not sure why it didn't work before but it really has to if written carefully.

这篇关于Ruby和指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆