## 数据库字段说明 # status 0:已开启;1:正在评测;2:通过评测;3:锁定 # modify_time: 与challenges表的modify_time联合使用,2个字段一致,则标识测试集未修改,反之,被修改 # answer_open: 查看查看答案的深度, 0: 未查看过答案, 其他数值与challenge_answer的level值相关 # answer_deduction: 查看答案扣分的百分比;如 查看答案 扣除70% # class Game < ApplicationRecord default_scope { order("games.created_at desc") } has_many :outputs, -> { order('query_index DESC') } has_many :challenge_samples, :dependent => :destroy has_many :game_codes, :dependent => :destroy has_many :evaluate_records, -> { order('id DESC') }, :dependent => :destroy belongs_to :myshixun belongs_to :user belongs_to :challenge has_one :run_code_message, :dependent => :destroy #全部关卡数 scope :ch_games, lambda { |challenge_id| where(challenge_id:challenge_id) } # 已通关的数量 scope :finished_num, -> (challenge_id) { where(:challenge_id => challenge_id, :status => 2)} # 正在通关的数量 scope :doing_num, -> (challenge_id) { where(:challenge_id => challenge_id, :status => [0,1])} #用户的全部关卡 scope :user_games, lambda { |user_id,challenge_id| where("user_id = ? AND challenge_id = ?",user_id,challenge_id) } validates :identifier, uniqueness: true # 根据得分比例来算实际得分(试卷、实训作业) def real_score score (final_score.to_f / challenge.all_score) * score end # 判断实训是否全部通关 def had_done Game.where(myshixun: self.myshixun_id).where("status != 2").count > 0 ? 0 : 1 end def owner self.user end def had_passed? self.status == 2 end # 因为outputs是按qurey_index倒序,所有first取的qurey_index的最大值 # 之所以加1是因为,存的时候要递增,如果仅取的话,则注意:必须减一 def query_index # Output.unscope(:order).maximum("query_index").where(game_id: self.id) self.outputs.unscope(:order).maximum("query_index") end # 用户在game关卡中获得的金币和经验值 # st: 0 实战类型;1 选择题类型 def user_get_gold_and_experience shixun_status, challenge if challenge.st == 0 # 实战类型 if self.status == 2 # 通关了则取实际得分,没通关则取总分 gold = (shixun_status <= 1) ? 0 : self.final_score.to_i # 只要过关了,查看了答案经验值就是0;通关前查看了答案金final_score为负数 experience = (shixun_status <= 1 || self.final_score.to_i < 0) ? 0 : challenge.score.to_i else gold = challenge.score.to_i experience = gold end else if self.status == 2 gold = (shixun_status <= 1) ? 0 : self.final_score.to_i experience = (shixun_status <= 1 || self.final_score.to_i < 0) ? 0 : challenge.score.to_i else # 选择题只有在全对的时候才会获取final score总分,错任何一个题final_score就为0 gold = challenge.choose_score experience = challenge.choose_score end end [gold, experience] end # 上一关 def prev_of_current_game shixun_id, myshixun_id, challenge_position Game.find_by_sql("select identifier from games where myshixun_id=#{myshixun_id} and challenge_id=(select id from challenges where shixun_id=#{shixun_id} and position=#{challenge_position - 1})").first.try(:identifier) end # 下一关 def next_of_current_game shixun_id, myshixun_id, challenge_position Game.find_by_sql("select * from games where myshixun_id=#{myshixun_id} and challenge_id=(select id from challenges where shixun_id=#{shixun_id} and position=#{challenge_position + 1})").first.try(:identifier) end # 针对api形式取下一关identifier def next_game shixun_id, myshixun_id, challenge_position Game.find_by_sql("select * from games where myshixun_id=#{myshixun_id} and challenge_id=(select id from challenges where shixun_id=#{shixun_id} and position=#{challenge_position + 1})").first end # 因为outputs是按qurey_index倒序,所有first取的qurey_index的最大值 # 之所以加1是以为,存的时候要递增,如果仅取的话,则注意:必须减一 def next_query_index if self.outputs.try(:first).present? self.outputs.first.try(:query_index).to_i + 1 else 1 end end def choose_correct_num query_index self.outputs.where(query_index: query_index, result: 1).count end # 评测次数 #def evaluate_count # self.outputs.pluck(:query_index).first #end # 用户关卡得分 def get_user_final_score end # 按评测次数的查询 def distinct_query_index self.outputs.group("outputs.query_index").reorder("query_index asc") end def lastest_code self.game_codes.first.try(:new_code) # game_code = GameCode.where(:game_id => self.id).first # game_code.try(:new_code) end end