root/trunk/lib/fm/periodicobject.rb

Revision 287, 9.1 KB (checked in by ged, 9 months ago)

Checkpoint commit

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Rev Author URL Id
Line 
1#!/usr/bin/ruby
2
3require 'fm/mixins'
4require 'fm/gameobject'
5
6#
7# The FaerieMUD::PeriodicObject class, a derivative of FaerieMUD::GameObject.
8# PeriodicObjects are values in a periodic system. A periodic system is one
9# which exhibits periodicity -- the tendency of sub-attributes to recur at
10# regular intervals, sharing attributes between similarly-positioned elements.
11#
12# In FaerieMUD, the "periodic system" you'll be dealing with is generally The
13# Pattern, which is based on the Periodic Table of Elements and parts of several
14# theories of developmental psychology and unified science. This set of periodic
15# objects, exemplified by Developmental Objects, are an attempt to model the
16# periodic nature of emergent objects, which are entities which emerge out of
17# complex systems.
18#
19# The periods of The Pattern represent the degrees of emergence which occur as
20# an emergent entity differentiates itself from its environment or substrate. In
21# each of these periods, the emerging entity (whether mind or society or
22# whatever) goes through a similar sequence of reactions to its newly
23# differentiated self.
24#
25# == SVNId
26#
27# $Id$
28#
29# == To Do
30#
31# * Make a method that returns the number of the balance which is referred to by
32#   the object's vocabulary.
33#
34# == Authors
35#
36# * Michael Granger <ged@FaerieMUD.org>
37#
38# :include: LICENSE
39#
40#---
41#
42# Please see the file LICENSE for licensing details.
43#
44class FaerieMUD::PeriodicObject < FaerieMUD::GameObject
45        include FaerieMUD::AccessorFunctions, FaerieMUD::HTML
46        contributors :scotus, :ged
47
48        # Subversion rev
49        SVNRev = /([\d\.]+)/.match( %q{$Rev$} )[1]
50
51        # Subversion ID
52        SVNId = %q$Id$
53
54        require 'fm/periodicobject/element'
55
56
57        ### Balance names
58        BALANCE_NAMES = {
59                -1 => "Pre-natal",
60                0 => "Incorporative",
61                1 => "Impulsive",
62                2 => "Imperial",
63                3 => "Interpersonal",
64                4 => "Institutional",
65                5 => "Interindividual",
66        }
67
68        ### Eco-relations array (number part of group name as index)
69        # +-----------------+
70        # |  8  |  1  |  2  |
71        # | -,- | -,0 | -,+ |
72        # +-----+-----+-----+      +----------+
73        # |  7  |     |  3  | --\  |  <group> |
74        # | 0,- |     | 0,+ | --/  |<relation>|
75        # +-----+-----+-----+      +----------+
76        # |  6  |  5  |  4  |
77        # | +,- | +,0 | +,+ |
78        # +-----------------+
79        ECO_RELATIONS = [
80                nil,
81                ['-','0'],
82                ['-','+'],
83                ['0','+'],
84                ['+','+'],
85                ['+','0'],
86                ['+','-'],
87                ['0','-'],
88                ['-','-'],
89        ]
90
91
92
93        #############################################################
94        ###     I N S T A N C E   M E T H O D S
95        #############################################################
96
97        ### Initialize a new PeriodicObject with the specified element (which can be any argument
98        ### supported by FaerieMUD::PeriodicObject::Element.fetch).
99        def initialize( element, options={} )
100                @element = Element.fetch( element )
101                super( options )
102        end
103
104
105
106        ######
107        public
108        ######
109
110        # The FaerieMUD::PeriodicObject::Element associated with this
111        # PeriodicObject.
112        attr_locked_accessor :element
113
114
115        ### Returns a new instance of the receiving class that is the sum of the
116        ### receiver and +other+.
117        def +( other )
118                elem = nil
119
120                case other
121                when FaerieMUD::PeriodicObject
122                        elem = self.element + other.element
123                when FaerieMUD::PeriodicObject::Element
124                        elem = self.element + other
125                else
126                        elem = self.element + Element.fetch( other )
127                end
128
129                return self.class.new( elem )
130        end
131
132
133        ### Returns a new instance of the receiving class that is the result of
134        ### subtracting the element of +other+ from the receiver.
135        def -( other )
136                elem = nil
137
138                case other
139                when FaerieMUD::PeriodicObject
140                        elem = self.element - other.element
141                when FaerieMUD::PeriodicObject::Element
142                        elem = self.element - other
143                else
144                        elem = self.element - Element.fetch(other)
145                end
146
147                return self.class.new( elem )
148        end
149
150
151        ### Returns a new instance of the receiver's class that is the result of
152        ### subtracting the given number of +balances+ from its element.
153        def <<( balances )
154                elem = self.element << balances
155                return self.class.new( elem )
156        end
157
158
159        ### Returns a new instance of the receiver's class that is the result of
160        ### adding the given number of +balances+ to its element.
161        def >>( balances )
162                elem = self.element >> balances
163                return self.class.new( elem )
164        end
165
166
167        ### Returns +true+ if the receiver's element is the same as +other+'s.
168        def ==( other )
169                return false unless other.is_a?( FaerieMUD::PeriodicObject )
170                return self.element == other.element
171        end
172
173
174        ### Comparable -- Returns the results of comparing the atomic number of the
175        ### receiver and +other+.
176        def <=>( other )
177                return nil unless other.is_a?( FaerieMUD::PeriodicObject )
178                return self.element <=> other.element
179        end
180
181
182        ### Returns the receiver's element as its atomic number (an Integer).
183        def to_i
184                return @element.number
185        end
186
187
188        ### Returns the receiver's element as a Float.
189        def to_f
190                return @element.number.to_f
191        end
192
193
194        ### Return the receiver as a String
195        def to_s
196                return "<%s: %s>" % [
197                        self.class.name.sub( /.*::/, '' ),
198                        @element.name,
199                ]
200        end
201
202
203        ### Return the receiver as a String suitable for debugging
204        def inspect
205                return "<%s: %s (%d)>" % [
206                        self.class.name,
207                        self.element.name,
208                        self.element.number,
209                ]
210        end
211
212
213        ### Returns the balance to which the receiver belongs. This is the 'row'
214        ### on the periodic table to which the receiver's element belongs.
215        def balance
216                return self.element.period - 2
217        end
218
219
220        ### Returns the name of the balance to which the receiver belongs.
221        def balanceName
222                return BALANCE_NAMES[ self.balance ]
223        end
224
225
226        ### Returns the dependence attribute of the element (either
227        ### 'inclusive' or 'independent').
228        def dependence
229                return (self.balance % 2).nonzero? ? 'inclusive' : 'independent'
230        end                     
231
232
233        ### Balance >= 0
234
235        ### For objects of balance 0 or higher, returns the eco-relation for the
236        ### receiver as an array of two strings, each of which is either '+',
237        ### '-', or '0'. This method returns +nil+ if called on a periodic
238        ### object whose balance is less than 0.
239        def ecorelation
240                return [nil,nil] unless self.balance >= 0
241                return ECO_RELATIONS[ self.element.group_name.to_i ]
242        end
243
244
245        ### Balance >= 2
246
247        ### Returns either :current or :previous to indicate which vocabulary
248        ### the object uses to describe itself and the world around it.
249        def historical_orientation
250                return nil unless self.balance >= 2
251                if @element.series == 'A'
252                        return :current
253                else
254                        return :previous
255                end
256        end
257
258        ### Returns the period number of the vocabulary the object uses to describe
259        ### itself and the world around it.
260        def vocabulary
261                return nil unless self.balance >= 2
262                if @element.series == 'A'
263                        return self.balance
264                else
265                        return (( self.balance ) - 1 )
266                end
267        end
268
269
270
271        #########
272        protected
273        #########
274
275
276        HTML = FaerieMUD::HTML
277
278        ### Implementation of the instance-variable HTML constructor from
279        ### FaerieMUD::GameObject. Return the object's instance variables as a
280        ### series of HTML fragments. If +inline+ is +true+, each object will be
281        ### wrapped in <span> elements for inline display. If it is false, they will
282        ### be wrapped in a <div> element. Any variables listed in the +skiplist+
283        ### will not be shown.
284        def html_ivar_section( inline=false, *skiplist )
285                elemtable = HTML.element( 'table', :class => "faeriemud-periodicobject-element" ) {
286                        HTML.element( 'tbody' ) do
287                                HTML.element( 'tr' ) {
288                                        HTML.element( 'td',
289                                                :class => "element-group element-leftside",
290                                                :title => "Group" ) do
291                                                "%s (%d)" % [ self.element.group_name, self.element.group ]
292                                        end <<
293                                        HTML.element( 'td',
294                                                :class => "element-atomic-number",
295                                                :title => "Atomic number" ) do
296                                                "%d" % self.element.atomic_number
297                                        end <<
298                                        HTML.element( 'td',
299                                                :class => "element-ecorelation element-rightside",
300                                                :title => "Eco-relation" ) do
301                                                if self.balance >= 0
302                                                        "[ %s, %s ]" % self.ecorelation
303                                                else
304                                                        "[ ?, ? ]"
305                                                end
306                                        end
307                                }
308                        end <<
309                        HTML.element( 'tbody' ) do
310                                HTML.element( 'tr' ) {
311                                        HTML.element( 'td',
312                                                :title => "Chemical Symbol",
313                                                :class => "element-symbol",
314                                                :colspan => "3" ) do
315                                                self.element.symbol.to_s.capitalize
316                                        end
317                                } <<
318                                HTML.element( 'tr' ) {
319                                        HTML.element( 'td',
320                                                :title => "Chemical Name",
321                                                :class => "element-name",
322                                                :colspan => "3" ) do
323                                                self.element.name.to_s.capitalize
324                                        end
325                                } <<
326                                HTML.element( 'tr' ) {
327                                        HTML.element( 'td',
328                                                :title => "Balance",
329                                                :class => "element-balance",
330                                                :colspan => "3" ) do
331                                                self.balanceName
332                                        end
333                                } <<
334                                HTML.element( 'tr' ) {
335                                        HTML.element( 'td',
336                                                :title => "Dependence",
337                                                :class => "element-dependence",
338                                                :colspan => "3" ) do
339                                                self.dependence
340                                        end
341                                }
342                        end <<
343                        HTML.element( 'tbody' ) do
344                                HTML.element( 'tr' ) {
345                                        HTML.element( 'td',
346                                                :title => "Required experience of k=1.0,c=1.0",
347                                                :class => "element-experience element-leftside" ) do
348                                                "%d" % (self.element.number * self.element.period)
349                                        end <<
350                                        HTML.element( 'td' ) do "&nbsp;" end <<
351                                        HTML.element( 'td' ) do "&nbsp;" end
352                                }                               
353                        end
354                }
355
356                superlist = super( inline, "@element", *skiplist )
357
358                return HTML.element( 'table', :class => "element-spacer" ) {
359                        HTML.element( 'tr' ) {
360                                HTML.element( 'td' ) { elemtable } +
361                                HTML.element( 'td' ) { superlist.join("") }
362                        }
363                }
364        end
365
366end # class FaerieMUD::PeriodicObject
Note: See TracBrowser for help on using the browser.