Skip to content

Commit

Permalink
fixed get rivals to return in proper order
Browse files Browse the repository at this point in the history
  • Loading branch information
Karl Seguin committed Jun 22, 2012
1 parent 8084790 commit a6a026c
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 28 deletions.
20 changes: 12 additions & 8 deletions app/models/leaderboard.rb
Expand Up @@ -2,7 +2,7 @@ class Leaderboard
include MongoLight::Document
include ActiveModel::Validations
mongo_accessor({:game_id => :gid, :name => :n, :offset => :o, :type => :t, :mode => :m})

validates_length_of :name, :minimum => 1, :maximum => 30, :allow_blank => false, :message => 'please enter a name'
def mode
self[:mode] || LeaderboardMode::Normal
Expand All @@ -15,38 +15,42 @@ def create(name, offset, type, mode, game)
Leaderboard.new({:name => name, :offset => offset, :type => type, :game_id => game.id, :mode => mode})
end
end

def score_is_better?(new_score, old_score, scope)
return true if old_score.nil? || old_score == 0
return true if scope == LeaderboardScope::Daily && mode == LeaderboardMode::DailyTracksLatest
return true if mode == LeaderboardMode::AllTrackLatest
type == LeaderboardType::LowToHigh ? new_score < old_score : new_score > old_score
end

def sort
type == LeaderboardType::LowToHigh ? :asc : :desc
end


def inverse_sort
type == LeaderboardType::LowToHigh ? :desc : :asc
end

def score_comparer
type == LeaderboardType::LowToHigh ? '$lt' : '$gt'
end

def daily_stamp
now = Time.now.utc
time = now.midnight + -3600 * (offset || 0)
return time > now ? time - 86400 : time
end

def yesterday_stamp
daily_stamp - 86400
end

def weekly_stamp
now = Time.now.utc
time = now.at_beginning_of_week + -3600 * (offset || 0)
return time > now ? time - 604800 : time
end

def update(name, offset, type, mode)
self.name = name
self.offset = offset
Expand Down
3 changes: 2 additions & 1 deletion app/models/score.rb
Expand Up @@ -94,8 +94,9 @@ def get_rivals(leaderboard, player, scope)
conditions = Score.time_condition(leaderboard, scope)
conditions[:leaderboard_id] = leaderboard.id
conditions[prefix + '.p'] = {leaderboard.score_comparer => score.points}
options = {:fields => {prefix + '.p' => 1, :username => 1, prefix + '.d' => 1, prefix + '.dt' => 1, :_id => 0}, :sort => [prefix + '.p', leaderboard.sort], :limit => 3, :raw => true}
options = {:fields => {prefix + '.p' => 1, :username => 1, prefix + '.d' => 1, prefix + '.dt' => 1, :_id => 0}, :sort => [prefix + '.p', leaderboard.inverse_sort], :limit => 3, :raw => true}

#p conditions
find(conditions, options).map{|s| {:username => s[:username], :points => s[name][:points], :data => s[name][:data], :dated => s[name][:dated]}}
end

Expand Down
38 changes: 19 additions & 19 deletions spec/models/score/get_rivals_spec.rb
@@ -1,55 +1,55 @@
require 'spec_helper'

describe Score, :get_rivals do
describe Score, :get_rivals do
before :each do
@created = 0
@now = Time.now.utc
Time.stub!(:now).and_return(@now)
end

it "should return an empty array if the player doesn't exist" do
@leaderboard = FactoryGirl.create(:leaderboard)
create_daily_scores(6)
scores = Score.get_rivals(@leaderboard, FactoryGirl.build(:player), LeaderboardScope::Daily).to_a
scores.length.should == 0
end

it "should return 3 players with better scores for high to low" do
@leaderboard = FactoryGirl.create(:leaderboard)
player = FactoryGirl.build(:player)
player.stub!(:unique).and_return('unique_2')
player.stub!(:unique).and_return('unique_1')
create_daily_scores(6)
scores = Score.get_rivals(@leaderboard, player, LeaderboardScope::Daily).to_a
scores.length.should == 3
scores[0][:points].should == 5
scores[1][:points].should == 4
scores[2][:points].should == 3
scores.length.should == 3
scores[0][:points].should == 2
scores[1][:points].should == 3
scores[2][:points].should == 4
end

it "should return available players with better scores for high to low" do
@leaderboard = FactoryGirl.create(:leaderboard)
player = FactoryGirl.build(:player)
player.stub!(:unique).and_return('unique_3')
create_weekly_scores(6)
scores = Score.get_rivals(@leaderboard, player, LeaderboardScope::Weekly).to_a
scores.length.should == 2
scores[0][:points].should == 5
scores[1][:points].should == 4
scores[0][:points].should == 4
scores[1][:points].should == 5
end

it "should scores for low to high" do
@leaderboard = FactoryGirl.create(:leaderboard, {:type => LeaderboardType::LowToHigh})
player = FactoryGirl.build(:player)
player.stub!(:unique).and_return('unique_3')
player.stub!(:unique).and_return('unique_4')
create_overall_scores(6)
scores = Score.get_rivals(@leaderboard, player, LeaderboardScope::Overall).to_a
scores.length.should == 3
scores[0][:points].should == 0
scores[1][:points].should == 1
scores[2][:points].should == 2
scores[0][:points].should == 3
scores[1][:points].should == 2
scores[2][:points].should == 1
end


private
def create_yesterday_scores(count, stamp = nil)
create_scores(count, :daily, stamp || @leaderboard.yesterday_stamp)
Expand All @@ -68,7 +68,7 @@ def create_scores(count, scope_name, stamp = nil)
score_data = FactoryGirl.build(:score_data, {:points => @created, :data => "data#{@created}", :dated => @now - 100 * @created})
score_data.stamp = stamp unless stamp.nil?
params = {:leaderboard_id => @leaderboard.id, :username => "player_#{@created}", :unique => "unique_#{@created}", scope_name => score_data}
Score.new(params).save
Score.new(params).save
@created += 1
end
end
Expand Down

0 comments on commit a6a026c

Please sign in to comment.