lib/ceml/script.rb in ceml-0.3.0 vs lib/ceml/script.rb in ceml-0.3.1
- old
+ new
@@ -1,72 +1,183 @@
module CEML
module Script
+ extend Forwardable
+ attr_writer :delegate
+ def delegate; @delegate || CEML.delegate; end
- def to_hash *fields
- fields.inject({}){ |h, s| x = send(s); h[s] = x if x; h }
+ # ===========
+ # = casting =
+ # ===========
+
+ def locations
+ @locations ||= (delegate.locations(self) || [])
end
- def script
- text_value
+ def launchable_location
+ criteria = awaited_criteria.sort_by{ |c| [-c.complexity, c.min_match] }
+ locations.find do |l|
+ people_used = []
+ criteria.all?{ |c| folks = l[c.hash] and c.satisfied_by_group?(folks, people_used) }
+ end
end
- def title
- super && !super.empty? && super.value
+ # public
+ def post candidate
+ criteria = awaited_criteria.select{ |c| c =~ candidate }
+ criteria.each{ |c| c.list_candidate(candidate) }
+ not criteria.empty?
end
- def name
- title || label
+ def awaited_criteria
+ return [] unless cast.type == :await
+ return cast.criteria(self)
end
- def radius
- casting_statement.empty? ? nil : casting_statement.radius
+
+ # ===============
+ # = likelihoods =
+ # ===============
+
+ def color(odds)
+ return :red if odds < 0.1
+ return :yellow if odds < 0.4
+ return :green
end
- def roles
- return [:agents] if casting_statement.empty?
- return casting_statement.roles
+ def likelihood(yesprob, needed, psize)
+ return 1 if needed <= 0
+ return 0 if psize < needed
+ return (needed..psize).inject(0) do |memo, yes_count|
+ memo + begin
+ no_count = psize - yes_count
+ ways_it_could_happen = psize.choose(yes_count)
+ prob_of_each = (yesprob ** yes_count) * ((1 - yesprob) ** no_count)
+ ways_it_could_happen * prob_of_each
+ end
+ end
end
- def dramatis_personae
- casting_statement.empty? ? nil : casting_statement
+ def availabilities(potential_count, committed_count = 0)
+ return {} unless script.dramatis_personae
+ min = script.dramatis_personae.min
+ needed = min - committed_count
+ possible = potential_count + committed_count
+ yesprob = 0.7 # just make this up for now
+ odds = likelihood(yesprob, needed, potential_count)
+
+ {
+ :odds => odds, :color => color(odds),
+ :availability_counts => {
+ :total => possible,
+ :unknown => potential_count
+ },
+ :estimated_size => yesprob * potential_count + committed_count,
+ :needed => min
+ }
end
- def max_to_invite
- dramatis_personae ? dramatis_personae.max : 0
+
+ # ========
+ # = cast =
+ # ========
+
+ DefaultDP = Struct.new :radius, :rolenames, :max, :type
+
+ def cast
+ return casting_statement if respond_to? :casting_statement
+ return DefaultDP.new nil, [:agents], 0, :nab
end
+ def_delegators :cast, :radius
+ def_delegator :cast, :max, :max_to_invite
+ def_delegator :cast, :rolenames, :roles
+ alias_method :dramatis_personae, :cast
alias_method :dp, :dramatis_personae
+ # casting_statement.roles.names
+
def simple?
(roles - [:agents, :organizer]).empty?
end
def expand_roles(roles)
roles.map{ |r| r == :agent ? [:agent, :agents] : r }.flatten.concat([:both, :all, :everyone])
end
+ def allowed_roles
+ allowed_roles = [:organizer, :agents]
+ allowed_roles += cast.rolenames
+ allowed_roles.uniq
+ end
+
+
+ # ================
+ # = instructions =
+ # ================
+
+ def instructions
+ return super if defined?(super)
+ return self if Instructions === self
+ nil
+ end
+
def instructions_for(roles)
- return [] if !instructions or instructions.empty?
+ return [] unless instructions
return instructions.for(expand_roles(roles))
end
def asks(roles)
- return [] if instructions.empty?
- instructions.asks([*roles])
+ return [] unless instructions
+ instructions.i_asks([*roles])
end
+ def tell(roles)
+ return unless instructions
+ instructions.i_tell([*roles])
+ end
+
+ def validate!
+ return unless instructions
+ instructions.validate_instructions!(allowed_roles)
+ end
+
+ def concludes_immediately?
+ !title and instructions.asks([:agents]).empty?
+ end
+
+
+ # =======
+ # = etc =
+ # =======
+
+ def to_hash *fields
+ fields.inject({}){ |h, s| x = send(s); h[s] = x if x; h }
+ end
+
+ def script
+ text_value
+ end
+
+ def title
+ if defined?(super)
+ super.title_value
+ elsif respond_to? :title_value
+ self.title_value
+ else nil
+ end
+ end
+
+ def name
+ title || label
+ end
+
def params
asks(:organizer).map do |ask|
[ask.var, ask.var.capitalize, ask.text]
end
end
- def tell(roles)
- return nil if instructions.empty?
- instructions.tell([*roles])
- end
-
def type
return 'mission' if title
return 'unknown' if instructions.empty?
return 'question' if not instructions.asks.empty?
return 'message' if instructions.tell(:agents)
@@ -87,60 +198,7 @@
else
"unknown"
end
end
end
-
- def validate!
- instructions.validate!(allowed_roles) unless instructions.empty?
- end
-
- def allowed_roles
- allowed_roles = [:organizer, :agents]
- allowed_roles += casting_statement.roles unless casting_statement.empty?
- allowed_roles
- end
-
- def concludes_immediately?
- !title and instructions.asks([:agents]).empty?
- end
-
- def color(odds)
- return :red if odds < 0.1
- return :yellow if odds < 0.4
- return :green
- end
-
- def likelihood(yesprob, needed, psize)
- return 1 if needed <= 0
- return 0 if psize < needed
- return (needed..psize).inject(0) do |memo, yes_count|
- memo + begin
- no_count = psize - yes_count
- ways_it_could_happen = psize.choose(yes_count)
- prob_of_each = (yesprob ** yes_count) * ((1 - yesprob) ** no_count)
- ways_it_could_happen * prob_of_each
- end
- end
- end
-
- def availabilities(potential_count, committed_count = 0)
- return {} unless script.dramatis_personae
- min = script.dramatis_personae.min
- needed = min - committed_count
- possible = potential_count + committed_count
- yesprob = 0.7 # just make this up for now
- odds = likelihood(yesprob, needed, potential_count)
-
- {
- :odds => odds, :color => color(odds),
- :availability_counts => {
- :total => possible,
- :unknown => potential_count
- },
- :estimated_size => yesprob * potential_count + committed_count,
- :needed => min
- }
- end
-
end
end