You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

174 lines
3.5 KiB

class GameController < ApplicationController
include QuizHelperMethods
skip_before_action :require_player!, only: [ :index, :start ]
before_action :set_node, only: [ :stage, :answer, :stage_result ]
helper_method :root_node,
:stage_index,
:n_stages,
:last_save_node
def index
@node = root_node
not_found and return unless @node
render action: @node.template
end
# POST
def start
player = Player.create(locale: I18n.locale.to_s)
session[:player_id] = player.id
redirect_to action: "facts"
end
def facts
@node = root_node&.children&.facts&.first
end
def intro
@node = root_node&.children&.intro&.first
end
def stage
end
# POST
def answer
@answer = @node.children.find_by(id: params[:value])
@answer = @answer.children.sample if @answer&.chance?
current_player.record_answer(stage_index, @answer.id)
apply_score(score_entry_for(stage_index, @answer))
bad_chance_outcome = @answer.parent&.chance? && @answer.bad_answer?
if stage_index >= n_stages && !bad_chance_outcome
redirect_to action: :done
else
redirect_to action: :stage_result, id: params[:id]
end
end
def stage_result
@result_node = @node.descendants.find_by(id: current_player.answer_id_for(stage_index))
not_found and return unless @result_node
end
def last_save
@node = last_save_node
end
# POST
def answer_last_save
@node = last_save_node
not_found and return unless @node
@answer = @node.children.find_by(id: params[:value])
current_player.record_last_save_answer(@answer.id)
apply_score(last_save_score_entry_for(@answer))
redirect_to action: :done
end
def done
if current_player.last_save_answer_id
@node = last_save_node
@result_node = @node.descendants.find_by(id: current_player.last_save_answer_id)
else
@node = stages.last
@result_node = @node.descendants.find_by(id: current_player.answer_id_for(stages.size))
end
end
def result
end
private
def root_node
@root_node ||= Node.roots.viewable.first
end
def last_save_node
@last_save_node ||= root_node.children.last_save.first
end
def stages
@stages ||= root_node.children.stage
end
def set_node
@node = stages[params[:id].to_i - 1]
not_found and return unless @node
end
def stage_index
@stage_index ||= stages.index(@node) + 1
end
def n_stages
@n_stages ||= stages.size
end
def url_from_param
return "" unless params[:url]
# return File.join('', params[:url]) if I18n.default_locale == I18n.locale
File.join("", I18n.locale.to_s, params[:url])
end
def question_scores
@@question_scores ||= JSON.parse(Rails.root.join("config", "question_scores.json").read)
end
def score_entry_for(stage_idx, answer_node)
stage_data = question_scores["stages"][stage_idx - 1]
return nil unless stage_data
if answer_node.parent&.chance?
chance_entry = stage_data["answers"][answer_node.parent.position - 1]
chance_entry&.dig("outcomes", answer_node.position - 1)
else
stage_data["answers"][answer_node.position - 1]
end
end
def last_save_score_entry_for(answer_node)
question_scores.dig("last_save", "answers", answer_node.position - 1)
end
def apply_score(entry)
return unless entry
current_player.add_to_score(
overall: entry["overall"].to_i,
impact: entry["impact"] || {}
)
end
end