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.
educoder/app/models/game.rb

138 lines
5.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

## 数据库字段说明
# 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 : self.final_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.choose_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