lib/gamefic/action.rb
# frozen_string_literal: true module Gamefic # The handler for executing a command response. # class Action include Scriptable::Queries # @return [Actor] attr_reader :actor # @return [Response] attr_reader :response # @return [Array<Match>] attr_reader :matches # @return [String, nil] attr_reader :input # @param actor [Actor] # @param response [Response] # @param matches [Array<Match>] # @param input [String, nil] def initialize(actor, response, matches, input = nil) @actor = actor @response = response @matches = matches @input = input end def verb response.verb end def command @command ||= Command.new(response.verb, matches.map(&:argument), response.meta?, input) end def queries response.queries end def arguments matches.map(&:argument) end def execute response.execute(actor, *arguments) self end # The total substantiality of the action, based on how many of the # arguments are concrete entities and whether the action has a verb. # def substantiality arguments.that_are(Entity).length + (verb ? 1 : 0) end # The total strictness of all the matches. # # The higher the strictness, the more precisely the tokens from the user # input match the arguments. For example, if the user is interacting with a # pencil, the command TAKE PENCIL is stricter than TAKE PEN. # # @return [Integer] def strictness matches.sum(0, &:strictness) end # The precision of the response. # # @return [Integer] def precision response.precision end def valid? response.accept?(actor, command) end def invalid? !valid? end def meta? response.meta? end # Sort an array of actions in the order in which a Dispatcher should # attempt to execute them. # # Order is determined by the actions' substantiality, strictness, and # precision. In the event of a tie, the most recently defined action has # higher priority. # # @param actions [Array<Action>] # @return [Array<Action>] def self.sort(actions) actions.sort_by.with_index do |action, idx| [-action.substantiality, -action.strictness, -action.precision, idx] end end end end