Ruby Marshal更新保存的值

时间:2014-08-01 19:29:06

标签: ruby save marshalling

我在Ruby中有文字冒险,我需要添加保存游戏的功能。好吧,我已经添加了,但这是一个巨大的黑客,我不满意它是如何工作的。我想用Marshal。我为我的一些课程制作了一个非常简短的版本,向您展示我是如何尝试用Marshal保存我的游戏的。以下是我尝试过的基本概念:

SAVE_FILE = "data"

class Player
    attr_accessor :current_room

    def initialize(name)
        @name = name
        @inventory = []
        @current_room = nil
    end
end

class Item
    attr_accessor :some_attribute

    def initialize(name, some_attribute = false)
        @name = name
        @some_attribute = some_attribute
    end
end

class Room
    attr_accessor :people

    def initialize(name, items, paths, people)
        @name = name
        @items = items
        @paths = paths
        @people = people
    end
end

class Person
    attr_accessor :items

    def initialize(name, items)
        @name = name
        @items = items
    end
end

player = rooms = nil

if File.file?(SAVE_FILE)
    # load game from the previous time
    File.open(SAVE_FILE) do |file|
        data = Marshal.load(file)
        player = data[:player]
        rooms = data[:rooms]
    end
else
    player = Player.new("Me")
    rooms = {
        castle: Room.new("Castle", [Item.new("pear"), Item.new("peach")], {n: :hallway, s: :forest}, []),
        forest: Room.new("Forest", [Item.new("sticks")], {n: :castle},
            [Person.new("Elf", [Item.new("Scroll")]
        )])
    }
    # init game
    player.current_room = rooms[:castle]

    # player does some stuff
    rooms[:forest].people[0].items[0].some_attribute = true

    data = {player: player, rooms: rooms}
    File.open(SAVE_FILE, 'w') do |file|
        Marshal.dump(data, file)
    end
end

p player
puts
rooms.each { |_, v| p v; puts } 

现在这非常有效,除非代码被更改。

如果我将房间改成这样:

rooms = {
    castle: Room.new("Castle", [Item.new("pear"), Item.new("peach"), Item.new("Guava")], {n: :hallway, s: :forest}, []),
    forest: Room.new("Forest", [Item.new("sticks")], {n: :castle, s: other_room},
        [Person.new("Elf", [Item.new("Scroll"), Item.new("This doesn't get added in"), Person.new("This guy doesn't either", [])]
    )])
}

我将项目类更改为:

class Item
    attr_accessor :some_attribute, :one_more

    def initialize(name, some_attribute = false, one_more = true)
        @name = name
        @some_attribute = some_attribute
        @one_more = one_more
    end
end

没有项目具有@one_more属性,并且未添加番石榴,以及名为“此内容未添加”的人员。林的路径属性也没有得到:s。我想不出一个简单的方法来解决这个问题,我想要更新的值,更新,而不是覆盖玩家所做的事情。

我确信我可以编写一些可怕的,丑陋的,有缺陷的代码,我会复制+粘贴到每个类中来解决这个问题,但我很想知道解决这个问题的最佳方法是什么

如果您想查看完整的源代码,请点击此处:https://github.com/INOVA-Technology/conquest

编辑:

要清楚,我知道为什么这不起作用。我只是想知道让它发挥作用的最佳方法是什么。

0 个答案:

没有答案