galaxy 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/encodings.xml +5 -0
- data/.idea/galaxy.iml +10 -0
- data/.idea/misc.xml +14 -0
- data/.idea/modules.xml +9 -0
- data/.idea/vcs.xml +8 -0
- data/.idea/workspace.xml +486 -0
- data/LICENSE +20 -0
- data/README.rdoc +36 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/doc/plan.txt +5 -0
- data/doc/pseudo.txt +43 -0
- data/features/galaxy.feature +9 -0
- data/features/step_definitions/galaxy_steps.rb +0 -0
- data/features/support/env.rb +4 -0
- data/galaxy.gemspec +95 -0
- data/galaxy/.loadpath +5 -0
- data/galaxy/.project +17 -0
- data/galaxy/.settings/org.eclipse.mylyn.tasks.ui.prefs +4 -0
- data/galaxy/.settings/org.eclipse.wst.sse.core.prefs +5 -0
- data/galaxy/experiments.rb +26 -0
- data/lib/galaxy.rb +8 -0
- data/lib/galaxy/models/bombing.rb +64 -0
- data/lib/galaxy/models/fleet.rb +62 -0
- data/lib/galaxy/models/group.rb +178 -0
- data/lib/galaxy/models/models.rb +16 -0
- data/lib/galaxy/models/planet.rb +181 -0
- data/lib/galaxy/models/product.rb +84 -0
- data/lib/galaxy/models/race.rb +112 -0
- data/lib/galaxy/models/route.rb +60 -0
- data/lib/galaxy/order.rb +24 -0
- data/lib/galaxy/report.rb +176 -0
- data/lib/galaxy/section.rb +226 -0
- data/lib/galaxy/utils.rb +109 -0
- data/lib/galaxy/virtual_base.rb +165 -0
- data/spec/spec_helper.rb +9 -0
- data/test/test_helper.rb +4 -0
- data/test/unit/models_test.rb +1469 -0
- data/test/unit/report_test.rb +187 -0
- data/test/unit/utils_test.rb +421 -0
- data/test/unit/virtual_base_test.rb +224 -0
- metadata +123 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'galaxy/models/models'
|
2
|
+
|
3
|
+
class Group < ActiveRecord::Base
|
4
|
+
virtual
|
5
|
+
tableless :columns => [
|
6
|
+
[:num, :integer],
|
7
|
+
[:xx, :float],
|
8
|
+
[:yy, :float],
|
9
|
+
[:num_ships, :integer ],
|
10
|
+
[:num_before, :integer], # Number of ships BEFORE battle (for Battle Groups only)
|
11
|
+
[:drive, :float],
|
12
|
+
[:weapons, :float],
|
13
|
+
[:shields, :float],
|
14
|
+
[:cargo, :float],
|
15
|
+
[:cargo_type, :string],
|
16
|
+
[:qty, :float],
|
17
|
+
[:range, :float],
|
18
|
+
[:speed, :float],
|
19
|
+
[:mass, :float],
|
20
|
+
[:status, :string] # May cause problems with AR?
|
21
|
+
]
|
22
|
+
belongs_to :race
|
23
|
+
belongs_to :product
|
24
|
+
belongs_to :planet
|
25
|
+
belongs_to :fleet
|
26
|
+
belongs_to :from, :class_name => 'Planet'
|
27
|
+
|
28
|
+
attr_accessor :battles
|
29
|
+
|
30
|
+
def initialize match, state
|
31
|
+
super()
|
32
|
+
update_group match, state
|
33
|
+
end
|
34
|
+
|
35
|
+
# Update information on this Group (based on match size and state hash given)
|
36
|
+
def update_group match, state
|
37
|
+
race = product = planet = from = fleet = nil
|
38
|
+
# Make attributes hash based on match size (many constructors)
|
39
|
+
hash = case match.size
|
40
|
+
when 16 # Your Group
|
41
|
+
race = state[:race]
|
42
|
+
p 'No planet!', match, state unless planet = Planet.lookup(match[9])
|
43
|
+
p 'No from!', match, state unless from = Planet.lookup(match[10]) unless match[10] == '-'
|
44
|
+
p 'No fleet!', match, state unless fleet = Fleet.lookup(race.name + '.' + match[14]) unless match[14] == '-'
|
45
|
+
product = Product.lookup(race.name + '.' + match[2])
|
46
|
+
product = Product.lookup(race.name + '.' + match[2])
|
47
|
+
{:num=>match[0].to_i, :num_ships=>match[1].to_i, :drive=>match[3].to_f, :weapons=>match[4].to_f,
|
48
|
+
:shields=>match[5].to_f, :cargo=>match[6].to_f, :cargo_type=>match[7], :qty=>match[8].to_f,
|
49
|
+
:range=>match[11].to_f, :speed=>match[12].to_f, :mass=>match[13].to_f, :status=>match[15]}
|
50
|
+
|
51
|
+
when 11 # (known) * Group
|
52
|
+
race = state[:race]
|
53
|
+
p 'No planet!', match, state unless planet = Planet.lookup(match[8])
|
54
|
+
p 'No product!', match, state unless product = Product.lookup(race.name + '.' + match[1])
|
55
|
+
{:num_ships=>match[0].to_i, :drive=>match[2].to_f, :weapons=>match[3].to_f, :shields=>match[4].to_f,
|
56
|
+
:cargo=>match[5].to_f, :cargo_type=>match[6], :qty=>match[7].to_f, :speed=>match[9].to_f, :mass=>match[10].to_f}
|
57
|
+
|
58
|
+
when 10 # Battle Group
|
59
|
+
race = state[:race]
|
60
|
+
planet = state[:planet]
|
61
|
+
product = Product.lookup(race.name + '.' + match[1])
|
62
|
+
@battles = state[:battles]
|
63
|
+
{:num_before=>match[0].to_i, :drive=>match[2].to_f, :weapons=>match[3].to_f,
|
64
|
+
:shields=>match[4].to_f, :cargo=>match[5].to_f, :cargo_type=>match[6], :qty=>match[7].to_f,
|
65
|
+
:num_ships=>match[8].to_i, :status=>match[9]}
|
66
|
+
|
67
|
+
when 5 # Incoming Group
|
68
|
+
planet = Planet.new [match[1]], state.merge({:race=>nil,:product=>nil,:created_by=>self}) unless planet = Planet.lookup(match[1])
|
69
|
+
from = Planet.new [match[0]], state.merge({:race=>nil,:product=>nil,:created_by=>self}) unless from = Planet.lookup(match[0])
|
70
|
+
{:range=>match[2].to_f, :speed=>match[3].to_f, :mass=>match[4].to_f}
|
71
|
+
|
72
|
+
when 2 # Unidentified Group - TODO implement track calculation
|
73
|
+
{:xx=>match[0].to_f, :yy=>match[1].to_f}
|
74
|
+
|
75
|
+
when 0 # All init data given in a state hash
|
76
|
+
state
|
77
|
+
else {}
|
78
|
+
end
|
79
|
+
# Set all the attributes given in hash
|
80
|
+
hash.each do |key, value|
|
81
|
+
setter = key.to_s.concat('=').to_sym
|
82
|
+
if self.respond_to? setter then self.send setter, value else raise ArgumentError end
|
83
|
+
end
|
84
|
+
# Add this Group to appropriate collections it belongs to
|
85
|
+
# auto-delete from previous collection should be handled by Owner class through collection callbacks
|
86
|
+
race.groups << self if race
|
87
|
+
product.groups << self if product
|
88
|
+
planet.groups << self if planet
|
89
|
+
fleet.groups << self if fleet
|
90
|
+
from.sent_groups << self if from
|
91
|
+
add if self.class.dataset # Add instantiated model to dataset if it is established
|
92
|
+
end
|
93
|
+
|
94
|
+
# Accessor methods
|
95
|
+
def eta ; from ? range/speed : 0 end
|
96
|
+
|
97
|
+
def x
|
98
|
+
return xx if xx
|
99
|
+
return planet.x if planet and !from
|
100
|
+
return 0 if planet and from # game.geometry.group_pos(self)[0]
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def y
|
105
|
+
return yy if yy
|
106
|
+
return planet.y if planet and !from
|
107
|
+
return 0 if planet and from # game.geometry.group_pos(self)[0]
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
|
111
|
+
def destination ; planet end
|
112
|
+
|
113
|
+
def origin ; from end
|
114
|
+
alias source origin
|
115
|
+
|
116
|
+
def key
|
117
|
+
if num # Your Group or other known race from additional reports
|
118
|
+
race.name + '.' + num.to_s
|
119
|
+
else # Impossible to define primary key (no combination of parameters is unique)
|
120
|
+
nil
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def distance planet
|
125
|
+
#game.geometry.distance (self, planet2)
|
126
|
+
0
|
127
|
+
end
|
128
|
+
|
129
|
+
# Boolean tests on Groups
|
130
|
+
def from_battle? ; @battles and @battles > 0 end # This Group is known from Battle
|
131
|
+
|
132
|
+
def incoming? ; !your? and from and planet and planet.your? end
|
133
|
+
|
134
|
+
def unidentified? ; !race end
|
135
|
+
alias unknown? unidentified?
|
136
|
+
|
137
|
+
def active?
|
138
|
+
return true unless from_battle? # All Groups are "real", unless they are known only from Battle
|
139
|
+
!your? and num_ships > 0 and planet.unknown? and planet.battles == self.battles # Not killed Groups from LAST Battle on UNKNOWN PLanet are "real" too
|
140
|
+
end
|
141
|
+
alias real? active?
|
142
|
+
|
143
|
+
def your_active? ; active? and your? end # Only includes your "active" (NOT from_battle) groups
|
144
|
+
|
145
|
+
def drone? ; (product and product.drone?) or (incoming? and mass == 1) end
|
146
|
+
|
147
|
+
def <=>(other) # Default comparable is num_ships
|
148
|
+
case other
|
149
|
+
when nil then 1
|
150
|
+
when Group then # key <=> other.key
|
151
|
+
return 0 if key and self.key == other.key
|
152
|
+
if num_ships and other.num_ships then num_ships <=> other.num_ships else -1 end
|
153
|
+
# Meaningful comparison only possible for groups with known num_ships
|
154
|
+
when Race then race ? race <=> other : -1
|
155
|
+
when Planet then
|
156
|
+
return 0 if from and from == other
|
157
|
+
planet ? planet <=> other : -1
|
158
|
+
when Product then product ? product <=> other : -1
|
159
|
+
when Fleet then fleet ? fleet <=> other : -1
|
160
|
+
when Integer then num_ships ? num_ships <=> other : -1
|
161
|
+
when String then self <=> other.downcase.to_sym
|
162
|
+
when Symbol then
|
163
|
+
return active? ? 0 : 1 if other == :active or other == :real or other == :alive
|
164
|
+
return from_battle? ? 0 : 1 if other == :from_battle or other == :battle
|
165
|
+
return incoming? ? 0 : 1 if other == :incoming
|
166
|
+
return unidentified? ? 0 : 1 if other == :unidentified or other == :unknown
|
167
|
+
return 0 if race and race == other
|
168
|
+
return 0 if product and product == other
|
169
|
+
return 0 if planet and planet == other
|
170
|
+
return 0 if from and from == other
|
171
|
+
return 0 if fleet and fleet == other
|
172
|
+
return 0 if status and status.downcase.include? other.to_s
|
173
|
+
return 0 if key and key.downcase.include? other.to_s
|
174
|
+
-1
|
175
|
+
else raise ArgumentError, 'Comparison with a wrong type'
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end #Group
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# First, 'models.rb' serves as 'super-class-equivalent' for Models, activating all the
|
2
|
+
# VirtualBase enhancements that can be used in Model classes (macros, class methods, instance methods)
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_record'
|
5
|
+
require 'galaxy/virtual_base.rb'
|
6
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ":memory:", :timeout => 500)
|
7
|
+
ActiveRecord::Base.send(:include, ActiveRecord::VirtualBase)
|
8
|
+
|
9
|
+
# Second, 'models.rb' serves as collector, allowing clients to require 'models.rb' instead of individual Model files
|
10
|
+
require 'galaxy/models/race'
|
11
|
+
require 'galaxy/models/product'
|
12
|
+
require 'galaxy/models/planet'
|
13
|
+
require 'galaxy/models/bombing'
|
14
|
+
require 'galaxy/models/route'
|
15
|
+
require 'galaxy/models/fleet'
|
16
|
+
require 'galaxy/models/group'
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'galaxy/models/models'
|
2
|
+
|
3
|
+
class Planet < ActiveRecord::Base
|
4
|
+
virtual
|
5
|
+
tableless :columns => [
|
6
|
+
[ :num, :integer],
|
7
|
+
[ :x, :float ],
|
8
|
+
[ :y, :float ],
|
9
|
+
[ :name, :string ],
|
10
|
+
[ :size, :float ],
|
11
|
+
[ :pop, :float ],
|
12
|
+
[ :ind, :float ],
|
13
|
+
[ :res, :float ],
|
14
|
+
[ :cap, :float ],
|
15
|
+
[ :mat, :float ],
|
16
|
+
[ :col, :float ],
|
17
|
+
[ :l, :float ]
|
18
|
+
]
|
19
|
+
belongs_to :race
|
20
|
+
belongs_to :product
|
21
|
+
has_many_linked :bombings
|
22
|
+
has_many_linked :fleets
|
23
|
+
has_many_linked :groups
|
24
|
+
has_many_linked :sent_fleets, :class_name => 'Fleet', :foreign_key => 'from_id'
|
25
|
+
has_many_linked :sent_groups, :class_name => 'Group', :foreign_key => 'from_id'
|
26
|
+
has_many_linked :routes, :before_add => :add_route, :after_remove => :remove_route #, after_remove => :remove_hmt
|
27
|
+
has_many_linked :incoming_routes, :foreign_key => 'target_id', :class_name => 'Route', :after_remove => :remove_route #, :after_remove => :remove_hmt
|
28
|
+
|
29
|
+
attr_accessor :battles, :progress, :created_by
|
30
|
+
|
31
|
+
def add_route(route)
|
32
|
+
# Find if target Route of this cargo type already exist, remove previous Route if found
|
33
|
+
routes.each do |r|
|
34
|
+
remove_route r if r == route.cargo
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def remove_route(route)
|
39
|
+
route.kill
|
40
|
+
end
|
41
|
+
|
42
|
+
def targets
|
43
|
+
routes.map {|r| r.target}
|
44
|
+
end
|
45
|
+
|
46
|
+
def suppliers
|
47
|
+
incoming_routes.map {|r| r.planet}
|
48
|
+
end
|
49
|
+
|
50
|
+
def Planet.new_or_update match, state
|
51
|
+
# Lookup by both num and name is necessary since Routes/Fleets/Bombings create planets by name only
|
52
|
+
num = match[0][0,1] == '#' ? match[0] : '#' + match[0].to_s
|
53
|
+
name = match[3]
|
54
|
+
planet = Planet.lookup(num)
|
55
|
+
planet ||= Planet.lookup(name) if name
|
56
|
+
if planet
|
57
|
+
planet.update_planet match, state
|
58
|
+
else
|
59
|
+
new match, state
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize match, state
|
64
|
+
super()
|
65
|
+
update_planet match, state
|
66
|
+
end
|
67
|
+
|
68
|
+
# Update information on Planet (based on match size and state hash given)
|
69
|
+
def update_planet match, state
|
70
|
+
# Make attributes hash based on match size (4 possible constructors
|
71
|
+
hash = case match.size
|
72
|
+
when 13 # Your Planet/ * Planet
|
73
|
+
prod_name = match[8]
|
74
|
+
prod_key = state[:race] ? state[:race].name + '.' + prod_name : nil
|
75
|
+
product = Product.lookup(prod_name)
|
76
|
+
product ||= Product.lookup(prod_key) if prod_key
|
77
|
+
product.planets << self if product
|
78
|
+
{:num=>match[0].to_i, :x=>match[1].to_f, :y=>match[2].to_f, :name=>match[3], :size=>match[4].to_f,
|
79
|
+
:pop=>match[5].to_f, :ind=>match[6].to_f, :res=>match[7].to_f, :cap=>match[9].to_f,
|
80
|
+
:mat=>match[10].to_f, :col=>match[11].to_f, :l=>match[12].to_f}
|
81
|
+
|
82
|
+
when 8 # Uninhabited Planet
|
83
|
+
{:num=>match[0].to_i, :x=>match[1].to_f, :y=>match[2].to_f, :name=>match[3], :size=>match[4].to_f,
|
84
|
+
:res=>match[5].to_f, :cap=>match[6].to_f, :mat=>match[7].to_f}
|
85
|
+
|
86
|
+
when 6 # Ships In Production
|
87
|
+
total_mass = match[3].to_f / 10 # Mass values given in "Material units", divide by 10
|
88
|
+
produced_mass = match[4].to_f / 10
|
89
|
+
percentage = produced_mass/total_mass # Calculate ship production progress
|
90
|
+
{:progress=>percentage}
|
91
|
+
|
92
|
+
when 3 # Unidentified Planet
|
93
|
+
{:num=>match[0].to_i, :x=>match[1].to_f, :y=>match[2].to_f}
|
94
|
+
|
95
|
+
when 2 # Battle/Bombing generated Planet (known num and name)
|
96
|
+
if state[:section] = 'Battle_planets'
|
97
|
+
self.battles = state[:battles] = self.battles ? self.battles + 1 : 1
|
98
|
+
state[:planet] = self
|
99
|
+
end
|
100
|
+
{:num=>match[0].to_i, :name=>match[1]}
|
101
|
+
|
102
|
+
when 1 # Route/Fleet/Bombing generated Planet (given EITHER #num or name)
|
103
|
+
match[0][0,1] == '#' ?
|
104
|
+
{:num=>match[0][1..-1].to_s} :
|
105
|
+
{:name=>match[0]}
|
106
|
+
|
107
|
+
when 0 # All init data given in a state hash
|
108
|
+
state
|
109
|
+
else {}
|
110
|
+
end
|
111
|
+
# Set all the attributes given in hash
|
112
|
+
hash.each do |key, value|
|
113
|
+
setter = key.to_s.concat('=').to_sym
|
114
|
+
if self.respond_to? setter then self.send setter, value else raise ArgumentError end
|
115
|
+
end
|
116
|
+
state[:race].planets << self if state[:race]
|
117
|
+
num ? add(numkey) : add if self.class.dataset # Add instantiated/updated model to dataset if dataset established
|
118
|
+
@created_by = state[:created_by]
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
def key ; name ? name : numkey end
|
123
|
+
def numkey ; num ? '#' + num.to_s : nil end
|
124
|
+
|
125
|
+
def distance planet
|
126
|
+
#game.geometry.distance (planet1, planet2)
|
127
|
+
0
|
128
|
+
end
|
129
|
+
|
130
|
+
def produced_full_mat
|
131
|
+
@progress end
|
132
|
+
|
133
|
+
def produced_by_mat
|
134
|
+
return nil unless self.product and self.product.ship?
|
135
|
+
produced_mass = @progress*self.product.mass
|
136
|
+
available_mass = self.mat/10
|
137
|
+
missing_mass = self.product.mass - produced_mass - available_mass
|
138
|
+
if missing_mass < 0
|
139
|
+
@progress
|
140
|
+
else
|
141
|
+
missing_l = (1/self.res+10)*missing_mass #
|
142
|
+
return 1-(available_mass + missing_l/10)/(produced_mass+available_mass+missing_l/10)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
alias produced produced_by_mat
|
146
|
+
|
147
|
+
# Boolean tests on Planets
|
148
|
+
def aster? ; size and size < 1 end
|
149
|
+
|
150
|
+
def max_size? ; size and size == 2500 end
|
151
|
+
|
152
|
+
def uninhabited? ; !race and size end
|
153
|
+
alias free? uninhabited?
|
154
|
+
|
155
|
+
def unidentified? ; !race and !size end
|
156
|
+
alias unknown? unidentified?
|
157
|
+
|
158
|
+
def <=>(other)
|
159
|
+
case other
|
160
|
+
when nil then 1
|
161
|
+
when Planet then num <=> other.num
|
162
|
+
when Race then race ? race <=> other : -1
|
163
|
+
when Product then product ? product <=> other : -1
|
164
|
+
when Bombing then bombings.any? {|r| r == other} ? 0 : 1 #Planet is bigger than Bombing
|
165
|
+
when Fleet then fleets.any? {|r| r == other} ? 0 : sent_fleets.any? {|r| r == other} ? 0 : 1 #Planet is bigger than Fleet
|
166
|
+
when Route then routes.any? {|r| r == other} ? 0 : incoming_routes.any? {|r| r == other}? 0 : 1 #Planet is bigger than Route
|
167
|
+
when Integer then num <=> other
|
168
|
+
when String then self <=> other.downcase.to_sym
|
169
|
+
when Symbol then
|
170
|
+
return aster? ? 0 : 1 if other == :aster or other == :asteroid or other == :min
|
171
|
+
return max_size? ? 0 : 1 if other == :max_size or other == :max
|
172
|
+
return uninhabited? ? 0 : 1 if other == :uninhabited or other == :free or other == :empty
|
173
|
+
return unidentified? ? 0 : 1 if other == :unidentified or other == :unid or other == :unknown
|
174
|
+
return 0 if name and name.downcase.to_sym == other
|
175
|
+
return 0 if race and race == other
|
176
|
+
return 0 if product and product == other
|
177
|
+
key <=> other.to_s
|
178
|
+
else raise ArgumentError, 'Comparison with a wrong type'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end #Planet
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'galaxy/models/models'
|
2
|
+
|
3
|
+
class Product < ActiveRecord::Base
|
4
|
+
virtual
|
5
|
+
tableless :columns => [
|
6
|
+
[:name, :string],
|
7
|
+
[:drive, :float],
|
8
|
+
[:weapons, :float],
|
9
|
+
[:shields, :float],
|
10
|
+
[:cargo, :float],
|
11
|
+
[:guns, :integer],
|
12
|
+
[:mass, :float],
|
13
|
+
[:prod_type, :string]
|
14
|
+
]
|
15
|
+
belongs_to :race
|
16
|
+
has_many_linked :bombings
|
17
|
+
has_many_linked :groups
|
18
|
+
has_many_linked :planets
|
19
|
+
|
20
|
+
def initialize match, state
|
21
|
+
case match.size
|
22
|
+
when 7 then # This is a ship design
|
23
|
+
super({:name=>match[0], :drive=>match[1].to_f, :guns=>match[2].to_i, :weapons=>match[3].to_f,
|
24
|
+
:shields=>match[4].to_f, :cargo=>match[5].to_f, :mass=>match[6].to_f, :prod_type=>'ship'})
|
25
|
+
|
26
|
+
when 5 then # This is a science
|
27
|
+
super({:name=>match[0], :drive=>match[1].to_f, :weapons=>match[2].to_f, :shields=>match[3].to_f,
|
28
|
+
:cargo=>match[4].to_f, :prod_type=>'research'})
|
29
|
+
|
30
|
+
when 0 then # This is Cap/Mat/Col/Drive/Weapon/Shields/Cargo init, all init data given in a hash
|
31
|
+
super state # :name=>state[:name], :prod_type=>state[:prod_type]
|
32
|
+
end
|
33
|
+
# Add this Product to appropriate Race collections it belongs to
|
34
|
+
# auto-delete from previous collection should be handled by Race class through collection callbacks
|
35
|
+
state[:race].products << self if state[:race]
|
36
|
+
add if self.class.dataset # Add instantiated model to dataset if it is defined
|
37
|
+
end
|
38
|
+
|
39
|
+
def key
|
40
|
+
full_name = research? ? name + '_Research' : name
|
41
|
+
full_name = race.name + '.' + full_name if race
|
42
|
+
full_name
|
43
|
+
end
|
44
|
+
|
45
|
+
# Boolean tests on Products
|
46
|
+
def cap? ; prod_type == 'cap' end
|
47
|
+
|
48
|
+
def mat? ; prod_type == 'mat' end
|
49
|
+
|
50
|
+
def terraforming? ; research? and name == '_TerraForming' end
|
51
|
+
|
52
|
+
def moving? ; name[0..3].downcase == 'move' end
|
53
|
+
|
54
|
+
def ship? ; mass != nil end
|
55
|
+
|
56
|
+
def drone? ; drive == 1 and mass == 1 end
|
57
|
+
|
58
|
+
def research? ; prod_type == 'research' end
|
59
|
+
|
60
|
+
def in_use? ; !bombings.empty? or !planets.empty? or !groups.empty? end
|
61
|
+
alias science? research?
|
62
|
+
|
63
|
+
def <=>(other)
|
64
|
+
case other
|
65
|
+
when nil then 1
|
66
|
+
when Race then race ? race <=> other : -1
|
67
|
+
when Product then (ship? and mass != other.mass) ? mass <=> other.mass : key <=> other.key
|
68
|
+
when Bombing then bombings.any? {|r| r == other} ? 0 : 1 #Product is bigger than Bombing
|
69
|
+
when Planet then planets.any? {|r| r == other} ? 0 : 1 #Product is bigger than Planet
|
70
|
+
when Integer then ship? ? mass <=> other : 1 #Science is bigger than anything
|
71
|
+
when Float then ship? ? mass <=> other : 1 #Science is bigger than anything
|
72
|
+
when String then self <=> other.downcase.to_sym
|
73
|
+
when Symbol then
|
74
|
+
return drone? ? 0 : 1 if other == :drone or other == :dron
|
75
|
+
return research? ? 0 : 1 if other == :research or other == :science or other == :tech
|
76
|
+
return moving? ? 0 : 1 if other == :move or other == :moving
|
77
|
+
return terraforming? ? 0 : 1 if other == :terraform or other == :terraforming
|
78
|
+
return 0 if prod_type.downcase.to_sym == other
|
79
|
+
return 0 if key.downcase.include? other.to_s
|
80
|
+
key <=> other.to_s
|
81
|
+
else raise ArgumentError, 'Comparison with a wrong type'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|