6
\$\begingroup\$

Right now, I have the following:

  • A win_streak column on the User table.
  • This method in game.rb

I'm interpreting win_streak as follows:

  • The number if the number games in the streak
  • The value (positive or negative) specifies whether those games were wins (positive) or losses (negative)

game.rb:

def adjust_streak
  u = self.user
  case self.result
    when 'Win'
      u.win_streak > 0 ? u.win_streak += 1 : u.win_streak = 1
    when 'Loss'
      u.win_streak > 0 ? u.win_streak = -1 : u.win_streak -= 1
    end
  u.save
end

I'm looking for a cleaner, and more succinct way to do this (e.g. keep track of win/loss streaks).

\$\endgroup\$
  • \$\begingroup\$ Can there be a draw? \$\endgroup\$ – Eric Duminil Feb 23 '18 at 13:30
  • \$\begingroup\$ The way the game is set up, no, there cannot be a draw. \$\endgroup\$ – Hyrum Carlile Mar 2 '18 at 15:44
3
\$\begingroup\$
  • You can use Array#min and Array#max to calculate the win/lose streak;
  • You don't need to use self on getters;
  • And you can use user.update instead of assigning and calling .save;
  • I would also rename the win_streak column to streak;

def adjust_streak
  streak = case result
           when 'Win'  then [user.streak, 0].max + 1
           when 'Loss' then [user.streak, 0].min - 1
           end

  user.update streak: streak
end
\$\endgroup\$
  • 1
    \$\begingroup\$ This is solid. I really like the ingenuity of using Array#min and Array#max. I wouldn't have even thought of that. Very clever! Thanks! \$\endgroup\$ – Hyrum Carlile Feb 19 '18 at 19:40
  • 1
    \$\begingroup\$ Nice! [0, streak].max + 1 and [0, streak].min - 1 might be even clearer. \$\endgroup\$ – Eric Duminil Feb 23 '18 at 13:41
  • \$\begingroup\$ great idea @EricDuminil, I updated my answer :) \$\endgroup\$ – Peoplee Feb 23 '18 at 17:49
1
\$\begingroup\$

Can the result be a tie? If not, then you can store wins and losses as Boolean values.

Thus you can use reduce the method to:

def adjust_streak
  u = self.user
  self.result == 1 ? u.win_streak += 1 : u.win_streak = 0
  u.save
end

If the result is a 'Win' (1/true) then increment the win streak, otherwise if the result is a loss the win streak is 0.

The value (positive or negative) specifies whether those games were wins (positive) or losses (negative)

This can be the sum of the result column if you are saving the values as 1 and 0.

\$\endgroup\$
  • \$\begingroup\$ The problem is that I also need to know how many losses in a row the user has, if they've lost multiple games in a row. (I guess I should probably rename the win_streak column to just streak) \$\endgroup\$ – Hyrum Carlile Feb 15 '18 at 19:04
  • \$\begingroup\$ If the streak is LLWLL, what number would you want to show and why? \$\endgroup\$ – danielsmith1789 Feb 15 '18 at 19:58
  • \$\begingroup\$ -2, to indicate that the user is on a 2 game losing streak. It doesn't necessarily have to be -2 I guess. But I would have to somehow know that the user is on a 2 game losing streak. I'm not sure how I would get that info from the sum of the result column like you said. \$\endgroup\$ – Hyrum Carlile Feb 15 '18 at 21:17
1
\$\begingroup\$

I played around with a bunch of options, but kept coming back to the structure you have. So here are a couple tweaks you could apply:

Make the logic in the cases look more alike / easier to reason about:

def adjust_streak
  u = self.user
  case self.result
    when 'Win'
      u.win_streak > 0 ? u.win_streak += 1 : u.win_streak = 1
    when 'Loss'
      u.win_streak < 0 ? u.win_streak -= 1 : u.win_streak = -1
    end
  u.save
end

Could use #positive?/#negative?:

def adjust_streak
  u = self.user
  case self.result
    when 'Win'
      u.win_streak.positive? ? u.win_streak += 1 : u.win_streak = 1
    when 'Loss'
      u.win_streak.negative? ? u.win_streak -= 1 : u.win_streak = -1
    end
  u.save
end

DRY up assignment (assumes result can only be "Win" or "Loss"):

def adjust_streak
  u = self.user
  u.win_streak = case self.result
    when 'Win'
      u.win_streak.positive? ? u.win_streak + 1 : 1
    when 'Loss'
      u.win_streak.negative? ? u.win_streak - 1 : -1
    end
  u.save
end

As you mentioned in the comment on the other answer, the column name should be streak instead of win_streak.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.