Class: Map
- Inherits:
-
Object
- Object
- Map
- Defined in:
- lib/IFMapper/Map.rb,
lib/IFMapper/MapPrinting.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#creator ⇒ Object
Returns the value of attribute creator.
-
#date ⇒ Object
Returns the value of attribute date.
-
#height ⇒ Object
Returns the value of attribute height.
-
#name ⇒ Object
Returns the value of attribute name.
-
#section ⇒ Object
Returns the value of attribute section.
-
#sections ⇒ Object
Returns the value of attribute sections.
-
#width ⇒ Object
Returns the value of attribute width.
Instance Method Summary collapse
- #_check_section ⇒ Object
- #copy(b) ⇒ Object
- #delete_connection(c) ⇒ Object
- #delete_connection_at(idx) ⇒ Object
- #delete_room(r) ⇒ Object
- #delete_room_at(idx) ⇒ Object
- #delete_room_only(r) ⇒ Object
- #delete_section_at(idx) ⇒ Object
-
#fit ⇒ Object
Change map’s width and height to make sure all rooms and connections will fit in map.
-
#free?(x, y) ⇒ Boolean
Return true or false if map is free at location x,y.
-
#initialize(name) ⇒ Map
constructor
A new instance of Map.
-
#marshal_dump ⇒ Object
Used for saving class with Marshal.
-
#marshal_load(v) ⇒ Object
Used for loading class with Marshal.
- #new_connection(roomA, exitA, roomB, exitB = nil) ⇒ Object
- #new_room(x, y) ⇒ Object
- #new_section ⇒ Object
-
#pack_sections(xmax, ymax) ⇒ Object
This code section is largely a copy of similar code used in IFM’s C code.
- #shift(x, y, dx, dy) ⇒ Object
-
#verify_integrity ⇒ Object
Auxiliary debugging function to verify the integrity of the map.
Constructor Details
#initialize(name) ⇒ Map
Returns a new instance of Map.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/IFMapper/Map.rb', line 118 def initialize(name) @section = 0 @name = name @creator = '' @width = 8 @height = 11 @date = nil # Add at least one section @sections = [] new_section end |
Instance Attribute Details
#creator ⇒ Object
Returns the value of attribute creator.
8 9 10 |
# File 'lib/IFMapper/Map.rb', line 8 def creator @creator end |
#date ⇒ Object
Returns the value of attribute date.
9 10 11 |
# File 'lib/IFMapper/Map.rb', line 9 def date @date end |
#height ⇒ Object
Returns the value of attribute height.
15 16 17 |
# File 'lib/IFMapper/Map.rb', line 15 def height @height end |
#name ⇒ Object
Returns the value of attribute name.
7 8 9 |
# File 'lib/IFMapper/Map.rb', line 7 def name @name end |
#section ⇒ Object
Returns the value of attribute section.
11 12 13 |
# File 'lib/IFMapper/Map.rb', line 11 def section @section end |
#sections ⇒ Object
Returns the value of attribute sections.
12 13 14 |
# File 'lib/IFMapper/Map.rb', line 12 def sections @sections end |
#width ⇒ Object
Returns the value of attribute width.
14 15 16 |
# File 'lib/IFMapper/Map.rb', line 14 def width @width end |
Instance Method Details
#_check_section ⇒ Object
189 190 191 192 |
# File 'lib/IFMapper/Map.rb', line 189 def _check_section @section = @sections.size - 1 if @section >= @sections.size new_section if @sections.size == 0 end |
#copy(b) ⇒ Object
133 134 135 136 137 138 139 140 141 |
# File 'lib/IFMapper/Map.rb', line 133 def copy(b) @section = b.section @sections = b.sections @name = b.name @creator = b.creator @width = b.width @height = b.height @date = b.date end |
#delete_connection(c) ⇒ Object
154 155 156 |
# File 'lib/IFMapper/Map.rb', line 154 def delete_connection(c) @sections[@section].delete_connection(c) end |
#delete_connection_at(idx) ⇒ Object
158 159 160 |
# File 'lib/IFMapper/Map.rb', line 158 def delete_connection_at( idx ) @sections[@section].delete_connection_at(idx) end |
#delete_room(r) ⇒ Object
176 177 178 |
# File 'lib/IFMapper/Map.rb', line 176 def delete_room(r) @sections[@section].delete_room(r) end |
#delete_room_at(idx) ⇒ Object
168 169 170 |
# File 'lib/IFMapper/Map.rb', line 168 def delete_room_at(idx) @sections[@section].delete_room_at(idx) end |
#delete_room_only(r) ⇒ Object
172 173 174 |
# File 'lib/IFMapper/Map.rb', line 172 def delete_room_only(r) @sections[@section].delete_room_only(r) end |
#delete_section_at(idx) ⇒ Object
194 195 196 197 |
# File 'lib/IFMapper/Map.rb', line 194 def delete_section_at(idx) @sections.delete_at(idx) _check_section end |
#fit ⇒ Object
Change map’s width and height to make sure all rooms and connections will fit in map
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/IFMapper/Map.rb', line 76 def fit # First, adjust map's width and height @width = @height = 3 minXY = [] maxXY = [] @sections.each { |section| next if section.rooms.empty? sizes = section.min_max_rooms minXY.push sizes[0] maxXY.push sizes[1] w = maxXY[-1][0] - minXY[-1][0] h = maxXY[-1][1] - minXY[-1][1] # We store +3 to allow for complex connections if needed. @width = w + 3 if w >= @width - 2 @height = h + 3 if h >= @height - 2 } # Okay, minXY[]/maxXY[] contains all the minXY/maxXY positions of # each section. With that info and @weight/@height, we can # start shifting all nodes in the section so that they will fit. idx = 0 @sections.each { |p| next if p.rooms.size == 0 x = y = 0 x = 1 - minXY[idx][0] if minXY[idx][0] < 1 y = 1 - minXY[idx][1] if minXY[idx][1] < 1 x = @width - maxXY[idx][0] - 2 if maxXY[idx][0] >= @width - 1 y = @height - maxXY[idx][1] - 2 if maxXY[idx][1] >= @height - 1 idx += 1 next if x == 0 and y == 0 # nothing to shift p.rooms.each { |r| r.x += x r.y += y } } end |
#free?(x, y) ⇒ Boolean
Return true or false if map is free at location x,y
146 147 148 |
# File 'lib/IFMapper/Map.rb', line 146 def free?(x, y) return @sections[@section].free?(x,y) end |
#marshal_dump ⇒ Object
Used for saving class with Marshal
34 35 36 |
# File 'lib/IFMapper/Map.rb', line 34 def marshal_dump [ @name, @creator, @date, @section, @sections, @width, @height ] end |
#marshal_load(v) ⇒ Object
Used for loading class with Marshal
21 22 23 24 25 26 27 28 29 |
# File 'lib/IFMapper/Map.rb', line 21 def marshal_load(v) @name = v.shift @creator = v.shift @date = v.shift @section = v.shift @sections = v.shift @width = v.shift @height = v.shift end |
#new_connection(roomA, exitA, roomB, exitB = nil) ⇒ Object
163 164 165 |
# File 'lib/IFMapper/Map.rb', line 163 def new_connection( roomA, exitA, roomB, exitB = nil ) @sections[@section].new_connection(roomA, exitA, roomB, exitB) end |
#new_room(x, y) ⇒ Object
180 181 182 |
# File 'lib/IFMapper/Map.rb', line 180 def new_room( x, y ) @sections[@section].new_room(x, y) end |
#new_section ⇒ Object
184 185 186 187 |
# File 'lib/IFMapper/Map.rb', line 184 def new_section @sections.push( Section.new ) @section = @sections.size - 1 end |
#pack_sections(xmax, ymax) ⇒ Object
This code section is largely a copy of similar code used in IFM’s C code. It tries to pack multiple map sections into a single page.
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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/IFMapper/MapPrinting.rb', line 23 def pack_sections(xmax, ymax) spacing = 0.0 # initialize -- one section per page pages = [] @sections.each { |sect| xlen, ylen = sect.rooms_width_height sect.xoff = 0.0 sect.yoff = 0.0 page = Page.new(xlen+2, ylen+2) pages.push page page.sections << sect } ratio = xmax.to_f / ymax packed = 1 while packed > 0 newpages = [] pos = packed = 0 while pos < pages.size p1 = pages[pos] x1 = p1.xlen y1 = p1.ylen # Check if it's better off rotated p1.rotate = ((x1 < y1 and xmax > ymax) or (x1 > y1 and xmax < ymax)) # Check if this is the last page if pos + 1 == pages.size newpages.push p1 break end # Get following page p2 = pages[pos+1] x2 = p2.xlen y2 = p2.ylen # Try combining pages in X direction xc1 = x1 + x2 + spacing yc1 = [y1, y2].max v1 = (xc1 <= xmax and yc1 <= ymax) r1 = xc1.to_f / yc1 # Try combining pages in Y direction xc2 = [x1, x2].max yc2 = y1 + y2 + spacing v2 = (xc2 <= xmax and yc2 <= ymax) r2 = xc2.to_f / yc2 # See which is best if v1 and v2 if (ratio - r1).abs < (ratio - r2).abs v2 = false else v1 = false end end # Just copy page if nothing can be done if not v1 and not v2 newpages.push(p1) pos += 1 next end # Create merged page page = Page.new xo1 = yo1 = xo2 = yo2 = 0 if v1 page.xlen = xc1 page.ylen = yc1 xo2 = x1 + spacing if y1 < y2 yo1 = (yc1 - y1) / 2 else yo2 = (yc1 - y2) / 2 end end if v2 page.xlen = xc2 page.ylen = yc2 yo1 = y2 + spacing if x1 < x2 xo1 = (xc2 - x1) / 2 else xo2 = (xc2 - x2) / 2 end end # Copy sections to new page, updating offsets opsects = p1.sections opsects.each { |sect| page.sections.push sect sect.xoff += xo1 sect.yoff += yo1 } opsects = p2.sections opsects.each { |sect| page.sections.push sect sect.xoff += xo2 sect.yoff += yo2 } # Add merged page to list and go to next page pair newpages.push page pos += 2 packed += 1 end pages = newpages end # Give each section its page info and clean up num = 0 pages.each { |page| psects = page.sections xlen = page.xlen ylen = page.ylen rflag = page.rotate num += 1 psects.each { |sect| sect.page = num sect.pxlen = xlen sect.pylen = ylen sect.rotate = rflag } } return num end |
#shift(x, y, dx, dy) ⇒ Object
150 151 152 |
# File 'lib/IFMapper/Map.rb', line 150 def shift(x, y, dx, dy) @sections[@section].shift(x, y, dx, dy) end |
#verify_integrity ⇒ Object
Auxiliary debugging function to verify the integrity of the map
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/IFMapper/Map.rb', line 47 def verify_integrity @sections.each { |sect| sect.rooms.each { |r| r.exits.each_with_index { |e, idx| next if not e if not sect.connections.include?(e) $stderr.puts "Exit #{e} in room, but not in section #{sect.name}." r.exits[idx] = nil sect.connections.delete(e) end } } sect.connections.each { |c| a = c.roomA b = c.roomB if not a.exits.index(c) or (b and not b.exits.rindex(c)) $stderr.puts "Exit #{c} not present in room." sect.connections.delete(c) end } } end |