-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GamePicker now picks the same game each day for each set of players #24
Conversation
TODO: Write tests
@@ -26,6 +26,8 @@ defmodule GamePicker do | |||
nil | |||
""" | |||
def pick_game(games_list, num_players) do | |||
:rand.seed(:exsplus, DateTime.utc_now |> DateTime.to_date |> Date.to_erl) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, this and the call to Enum.take_random
are non-deterministic...
That said, if you want to test this and allow for this to be deterministic, maybe a "game randomization" function would be in order - something that you could inject.
There's a number of ways to inject it, but what this could look like:
def pick_game(games_list, num_players, randomizer \\ GamePicker.Randomizer) do
...
|> randomizer.randomize()
end
You could then test the injected piece independently if you want.
Just a thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does Enum.take_random not use the value seeded to :rand.seed/2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at something like this:
defmodule Randomizer do
def new do
:rand.seed(:exsplus, DateTime.utc_now |> DateTime.to_date |> Date.to_erl)
end
def new(seed) do
:rand.seed(:exsplus, seed)
end
end
Is that how the randomizer would work with injection?
EDIT: this doesn't have a randomize
and I'm not sure how that would work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@daveshah I'd like to respectively disagree that this is non-deterministic. Given the same seed and the same pseudorandom algorithm, you should always get the same output. The seed is what gives the RNG its non-determinism (which we're taking away)
Try it yourself:
:rand.seed(:exsplus, {10, 17, 2016})
:rand.uniform(1000)
Should always return 993
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But, I do agree that this randomizer should be extracted and isolated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defmodule GamePicker.Randomizer do
def new do
:rand.seed(:exsplus, DateTime.utc_now |> DateTime.to_date |> Date.to_erl)
end
def new(seed) do
:rand.seed(:exsplus, seed)
end
def randomize(games_list) do
games_list
|> Enum.take_random(1)
|> List.first
end
end
@@ -26,6 +26,8 @@ defmodule GamePicker do | |||
nil | |||
""" | |||
def pick_game(games_list, num_players) do | |||
:rand.seed(:exsplus, DateTime.utc_now |> DateTime.to_date |> Date.to_erl) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha! I love this solution. It's hacky in a really elegant way.
8843865
to
641d5ae
Compare
Tests will currently fail |
games = [%Game{name: "Game1", min_players: 2, max_players: 4}, | ||
%Game{name: "Game2", min_players: 2, max_players: 4}, | ||
%Game{name: "Game3", min_players: 2, max_players: 4}] | ||
randomizer = GamePicker.Randomizer.new({2016, 10, 17}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't work because new
returns the result of the last called function. Not the Randomizer
.
Yeah, Eric had narrowed that down. I was still treating it like it was OO
|
Todo
In short, this randomizer uses the current year and day of year to as the index of the list of available games to reliably choose the same game for a given day and game list. I'm not happy with the tests, as I'm not too sure about how to set this up to be tested reliably (but I barrelled through with it anyway). Paired with @Serneum while doing this. |
TODO: Write tests
Closes #23