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.2 KiB

6 years ago
## 数据库字段说明
# 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) }
# 已通关的数量
6 years ago
scope :finished_num, -> (challenge_id) { where(:challenge_id => challenge_id, :status => 2)}
6 years ago
# 正在通关的数量
6 years ago
scope :doing_num, -> (challenge_id) { where(:challenge_id => challenge_id, :status => [0,1])}
6 years ago
#用户的全部关卡
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 < 0 ? 0 : final_score).to_f / challenge.all_score) * score
6 years ago
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为负数
5 years ago
experience = (shixun_status <= 1 || self.final_score.to_i < 0) ? 0 : self.final_score.to_i
6 years ago
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
6 years ago
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
# 评测次数
6 years ago
#def evaluate_count
# self.outputs.pluck(:query_index).first
#end
6 years ago
# 用户关卡得分
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