-
Notifications
You must be signed in to change notification settings - Fork 482
/
grid.rb
90 lines (81 loc) · 2.95 KB
/
grid.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# == Schema Information
#
# Table name: levels
#
# id :integer not null, primary key
# game_id :integer
# name :string(255) not null
# created_at :datetime
# updated_at :datetime
# level_num :string(255)
# ideal_level_source_id :integer
# solution_level_source_id :integer
# user_id :integer
# properties :text(65535)
# type :string(255)
# md5 :string(255)
# published :boolean default(FALSE), not null
# notes :text(65535)
#
# Indexes
#
# index_levels_on_game_id (game_id)
# index_levels_on_name (name)
#
require "csv"
class Grid < Blockly
before_save :update_maze
serialized_attrs :maze, :maze_data
def self.create_from_level_builder(params, level_params)
level = new(level_params.merge(user: params[:user], game: Game.custom_maze, level_num: 'custom'))
level.create_maze(level_params, params)
level
end
def create_maze(level_params, params)
size = params[:size].to_i
if params[:maze_source]
file_contents = CSV.new(params[:maze_source].read)
contents = self.class.load_maze(file_contents, size)
elsif level_params[:maze_data]
contents = JSON.parse(level_params[:maze_data])
else
raise ArgumentError.new("Maze level data not found")
end
self.maze_data = contents.to_json
save!
end
def update_maze
min_total_value = properties['min_collected'].try(:to_i)
if read_attribute(:maze).present?
properties.update(self.class.parse_maze(read_attribute(:maze), min_total_value))
write_attribute(:maze, nil)
elsif maze_data.present?
properties.update(self.class.parse_maze(maze_data, min_total_value))
self.maze_data = nil
elsif property_changed?('min_collected')
self.class.parse_maze(serialized_maze, min_total_value)
end
end
# contents - should respond to read by returning a 2d square array
# with the given size, representing a blockly level.
# Throws ArgumentError if there is a non integer value in the array.
def self.load_maze(maze_file, size)
raw_maze = maze_file.read[0...size]
raw_maze.map {|row| row.map {|cell| Integer(cell)}}
end
# Parses the 2d array contents.
# If type is "Maze" return a single entry hash with 'maze' mapping to a 2d
# array that Blockly can render.
# Throws ArgumentError if there is a non integer value in the array.
def self.parse_maze(maze_json, _ = nil)
maze_json = maze_json.to_json if maze_json.is_a? Array
{'maze' => JSON.parse(maze_json).map {|row| row.map {|cell| Integer(cell)}}.to_json}
end
def filter_level_attributes(level_hash)
%w(maze initial_dirt raw_dirt).map do |maze_type|
prop = level_hash['properties']
prop[maze_type] = prop[maze_type].to_json if prop[maze_type].is_a?(Array)
end
super(level_hash)
end
end