2669fbd62908cf7787bd6ac81bad624c

The rule at work here is that users can be awarded badges for a streak of 10, 20, and 30. But the user can't be awarded multiple badges for the same streak. I'm tracking consec wins in the user model.

For example, if the user hits a 10-streak, the user is awarded a 10-streak badge. If the user is on a 20-streak, he/she receives a 20-streak badge. If the user is on a 30-game win streak, the user is awarded a 30-streak badge. The user shouldn't be awarded three 10-streak badges -- only one 10-streak, one 20-streak, and one 30-streak.

Further, if the user reaches a 40-win streak, then the user should be awarded a 10-streak badge. If the user hits 50, then he/she should be awarded a 20-streak badge. If the user hits 60, the user should be award a 30-streak badge. If the user hits 70, the user should be awarded a 10-streak. I think you get the pattern here. A 30-streak trophy is the max a user can get. But the user can be on an infinite winning streak.

def check_win_streak(streak)
    badge = 10
    while badge < BADGE::MAX_STREAK_BADGE_SIZE do # MAX_STREAK_BADGE_SIZE = 30

       if streak < badge then
         break
       end

       if (streak % badge == 0) then
         award_streak_badge(badge)
       end

       badge += 10
    end
  end

Refactorings

No refactoring yet !

D41d8cd98f00b204e9800998ecf8427e

Joshua Morgan

June 7, 2010, June 07, 2010 13:57, permalink

No rating. Login to rate!

This dosn't match your code but seems to match your description

def check_win_streak(streak)
    while streak > 0 do
        [10, 20, 30].each {|badge| award_streak_badge(badge) if streak >= badge}
        
        streak -= 30
    end
end
7855792dbc5f3b4c365344314e2b1ad6

arvanasse

June 7, 2010, June 07, 2010 14:20, permalink

1 rating. Login to rate!

Assuming that you call #check_win_streak after every win it would be more readable (and easier to maintain) if you use a case statement.

Your solutions work but only as long as the streak rules continue to be based on convenient factors of 10.

# Assuming something like this
class Badge
  BRONZE_BADGE 10
  SILVER_BADGE 20
  GOLD_BADGE 30
  MAX_STREAK_BADGE_SIZE 30
end

def check_win_streak(streak)
  case streak % BADGE::MAX_STREAK_BADGE_SIZE
    when BRONZE_BADGE
      award_streak_badge BADGE::BRONZE_BADGE
    when SILVER_BADGE
      award_streak_badge BADGE::SILVER_BADGE
    when 0
      award_streak_badge(BADGE::GOLD_BADGE) if streak >= BADGE::MAX_STREAK_BADGE_SIZE
  end
end
D41d8cd98f00b204e9800998ecf8427e

Joshu

June 7, 2010, June 07, 2010 14:33, permalink

1 rating. Login to rate!

If you calling it after every win this should do what you want. Its important that the badge numbers are in descending order.

def check_win_streak(streak)
    [30, 20, 10].each do |badge|
        if (streak % badge == 0 and streak / badge >= 1) then
            award_streak_badge(badge)
            break
        end
    end
end
2669fbd62908cf7787bd6ac81bad624c

keruilin.myopenid.com

June 8, 2010, June 08, 2010 04:19, permalink

No rating. Login to rate!

Joshu, yours is closest I've come across yet. Only issue is that when I run a test code for a 40-win streak, it awards a 20-streak trophy, when it should only award a 10-streak trophy.

D41d8cd98f00b204e9800998ecf8427e

Joshua Morgan

June 8, 2010, June 08, 2010 12:39, permalink

1 rating. Login to rate!

Your right - I forgot to mod by badges in the negative case. This seems to work now.

def check_win_streak(streak)
    [30, 20, 10].each do |badge|
        if (streak % badge == 0 and streak / badge >= 1) then
            award_streak_badge(badge)
            break
        else 
            streak %= badge
        end
    end   
    
    nil
end
E8f0d6e9bc8bca695b3c5bdf75cdcc03

Martin Plöger

June 8, 2010, June 08, 2010 16:55, permalink

3 ratings. Login to rate!

Hope, I understood what you meant (text not code):
10 => 10
20 => 20
30 => 30
40 => 10
50 => 20
...
Everything else (not a multiple of ten and <= zero) => 0

def check_win_streak streak
  return if streak % 10 != 0 || streak <= 0
  award_streak_badge [10, 20, 30][streak / 10 % 3 - 1]
end

Your refactoring





Format Copy from initial code

or Cancel