使用其他对象反序列化它的对象
问题描述:
我正在命令行中玩双棋棋局游戏。我为每一种类型的棋子和一个板类都有一堂课。董事会类看起来是这样的:使用其他对象反序列化它的对象
class Board
attr_accessor :board, :choice
def initialize
@board = Array.new(8){Array.new(8," ")}
@choice = choice
end
end
我的其他类是这样的:
class Bishop
attr_accessor :x_position, :y_position, :piece, :color, :counter, :moves
def initialize(position,boolean)
@x_position = position[0]
@y_position = position[1]
@piece = boolean ? "♝" : "♗"
@color = boolean ? "white" : "black"
@counter = 0
@moves = [[+1,-1],
[+1,+1],
[-1,+1],
[-1,-1]]
end
我说我的作品与板这样的:
@board[0][0] = Rook.new([0,0],false)
这些都是我的方法序列化和反序列化数据:
def to_json
JSON.generate({board: @board})
end
def save_game(string)
File.open("saved.json", "w") do |game_file|
game_file.write(string)
end
end
def load_game
game_file = File.read("saved.json")
data = JSON.parse(game_file)
@board = data["board"]
end
保存后,saved.json文件看起来像这样:
{"board":[[" ","#<Knight:0x00000000e4fc28>","#<Bishop:0x00000000e4fa20>","#<Queen:0x00000000e4f890>","#<King:0x00000000e4f610>","#<Bishop:0x00000000e4f3e0>","#<Knight:0x00000000e4f278>","#<Rook:0x00000000e4e1c0>"],[" "," "," "," "," "," "," "," "],[" "," "," "," "," "," "," "," "],[" "," "," "," "," "," "," "," "],[" "," "," "," "," "," "," "," "],[" "," "," "," "," "," "," "," "],[" "," "," "," "," "," "," "," "],["#<Rook:0x00000000e4fd90>","#<Knight:0x00000000e4ed78>","#<Bishop:0x00000000e4eb70>","#<Queen:0x00000000e4ea08>","#<King:0x00000000e4e7b0>","#<Bishop:0x00000000e4e580>","#<Knight:0x00000000e4e3f0>"," "]]}
当我尝试加载回数据,显示板上的方法抛出这个错误:
0 1 2 3 4 5 6 7
+----+----+----+----+----+----+----+----+
0| /home/jacob/Desktop/chess/board.rb:30:in `block (2 levels) in display': undefined method `piece' for "#<Knight:0x00000000e4fc28>":String (NoMethodError)
from /home/jacob/Desktop/chess/board.rb:27:in `each'
from /home/jacob/Desktop/chess/board.rb:27:in `each_with_index'
from /home/jacob/Desktop/chess/board.rb:27:in `block in display'
from /home/jacob/Desktop/chess/board.rb:20:in `each'
from /home/jacob/Desktop/chess/board.rb:20:in `each_with_index'
它看起来像我问题是对象以字符串的形式返回?
我的显示方法:
def display
axis = 0
print " 0 1 2 3 4 5 6 7"
@board.each_with_index do |row,index|
print "\n"
@draw = " +----+----+----+----+----+----+----+----+"
puts @draw
print axis
axis +=1
if index.even?
row.each_with_index do|column,i|
if i.odd?
if column != " "
print "|"+" #{column.piece} ".bruno
else print "|"+" #{column} ".bruno
end
else
if column != " "
print "|"+" #{column.piece} "
else print "|"+" #{column} "
end
end
end
else
row.each_with_index do|column,j|
if j.even?
if column != " "
print "|"+" #{column.piece} ".bruno
else print "|"+" #{column} ".bruno
end
else
if column != " "
print "|"+" #{column.piece} "
else print "|"+" #{column} "
end
end
end
end
print "|"
end
print "\n"
print @draw
end
答
没有,问题是,你的对象是保存为字符串。在这种情况下,反序列化可以正常工作。你必须明确指定你的游戏片断应该是什么json表示。就像这样:
class Rook
def to_json(*)
{ name: 'rook', position: 'A1', status: 'in_game' }.to_json
end
end
pieces = [Rook.new]
pieces.to_json # => "[{\"name\":\"rook\",\"position\":\"A1\",\"status\":\"in_game\"}]"
JSON.parse(pieces.to_json) # => [{"name"=>"rook", "position"=>"A1", "status"=>"in_game"}]
关于反序列化,你必须做相反的事情。从解析JSON文件中获得纯ruby哈希来构建正确的游戏类。
或者如果你实际上不关心JSON,只想创建一些保存文件的形式,那么Marshal
是你最好的朋友。无需重写任何内容。零摩擦。
pieces = [Rook.new]
Marshal.dump(pieces) # => "\x04\b[\x06o:\tRook\x00" # write this to a file
# restore it later
Marshal.load("\x04\b[\x06o:\tRook\x00") # => [#<Rook:0x007fb50f825570>]
+0
我把它运用到了元帅身上。谢谢。 –
哪个部分属于哪个文件?没有它,我们不能跟踪回溯。而且你所显示的那个地方没有任何地方叫'piece',这是导致错误的原因。 – sawa
件是每种类型的件类中的一个实例。 –