module BudgetGame
Constants
- PLUGIN
- STYLE_TITLE
Public Instance Methods
Source
# File lib/budget_game.rb, line 105 def buy(data:, items_text:) scenario = BudgetScenarios::SCENARIOS.find { |s| s[:id] == data["scenario_id"] } return { error: "No active scenario — use !budget" } unless scenario items = parse_items(items_text) return { error: "List at least one item." } if items.empty? total = items.sum { |item| price_item(item) } spent = data["spent"].to_i + total return { error: "Over budget ($#{data['budget']}) — spent would be $#{spent}." } if spent > data["budget"] data = data.dup data["spent"] = spent data["purchases"] = Array(data["purchases"]) + items score = score_run(data, scenario) data["score"] = score { data: data, message: "#{format_header('Purchased')}\nSpent $#{total} (total $#{spent}/$#{data['budget']})\nScore: #{score}/10" } end
Source
# File lib/budget_game.rb, line 148 def format_header(title) IrcFormat.report_header(tag: "BUDGET", title: title, style: STYLE_TITLE) end
Source
# File lib/budget_game.rb, line 137 def format_score(data) return format_header("No run") + "\nUse !budget to start a scenario." unless data lines = [format_header("Last score")] lines << "#{data['title']} — #{data['score'] || '?'}/10" lines << "Spent $#{data['spent']}/$#{data['budget']}" lines << "Items: #{Array(data['purchases']).join(', ')}" lines << IrcFormat.report_footer("budget build") lines.join("\n") end
Source
# File lib/budget_game.rb, line 65 def load_player(network:, channel:, user:, store: RabbotDb) key = "player:#{GameStore.norm_nick(user)}" GameStore.load(plugin: PLUGIN, network: network, channel: channel, key: key, store: store) end
Source
# File lib/budget_game.rb, line 75 def new_scenario(rand: ->(max) { Random.rand(0...max) }) scenario = BudgetScenarios.pick(rand: rand) { "scenario_id" => scenario[:id], "title" => scenario[:title], "budget" => scenario[:budget], "spent" => 0, "purchases" => [], "score" => nil } end
Source
# File lib/budget_game.rb, line 47 def parse_command(text) parts = text.to_s.strip.split(/\s+/) return { action: :new } if parts.empty? case parts[0].downcase when "help" { action: :help } when "buy", "shop" return { error: usage_message } if parts.length < 2 { action: :buy, items: parts[1..].join(" ") } when "score", "status" { action: :score } else { error: usage_message } end end
Source
# File lib/budget_game.rb, line 95 def parse_items(text) text.to_s.split(/[,;]+|\band\b/i).map(&:strip).reject(&:empty?) end
Source
# File lib/budget_game.rb, line 99 def price_item(item) base = 5 + (item.length % 12) base += 3 if item.length > 10 base end
Source
# File lib/budget_game.rb, line 70 def save_player(network:, channel:, user:, data:, store: RabbotDb) key = "player:#{GameStore.norm_nick(user)}" GameStore.save(plugin: PLUGIN, network: network, channel: channel, key: key, game: data, store: store) end
Source
# File lib/budget_game.rb, line 87 def scenario_message(data) lines = [format_header("Budget Build")] lines << "#{data['title']}" lines << "Budget: $#{data['budget']} — list purchases with !budget buy <items>" lines << IrcFormat.report_footer("solo challenge") lines.join("\n") end
Source
# File lib/budget_game.rb, line 127 def score_run(data, scenario) purchases = Array(data["purchases"]).map { |i| i.downcase } hits = scenario[:keywords].count { |kw| purchases.any? { |p| p.include?(kw) } } budget_left = data["budget"].to_i - data["spent"].to_i creativity = [purchases.length, 5].min survival = hits * 2 thrift = budget_left >= 10 ? 1 : 0 [survival + creativity + thrift, 10].min end
Source
# File lib/budget_game.rb, line 43 def usage_message "Usage: !budget | !budget buy <item list> | !budget score" end