Last active
February 23, 2019 10:47
-
-
Save chapkovski/24fd7ef33ae1d97d78058d9b2a7fe590 to your computer and use it in GitHub Desktop.
Matching based on priorities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class GroupingWaitPage(WaitPage): | |
_allow_custom_attributes = True | |
group_by_arrival_time = True | |
def get_unique(self, wp, priority, filtering=None, matched=None): | |
seen = set() | |
# we don't need to re-use matched players | |
if matched: | |
wp = [w for w in wp if w not in matched] | |
# we need to filter the waiting players if we want to get rid of the priorities used in some other list | |
if filtering: | |
wp = [w for w in wp if w.participant.vars[priority] not in filtering] | |
uniques = [p for p in wp if | |
p.participant.vars[priority] not in seen and not seen.add(p.participant.vars[priority])] | |
return uniques | |
def get_players_for_group(self, waiting_players): | |
group_size = 3 | |
stopper = 6 # when the number of waiting players reach a certain threshold we start grouping them based on | |
# their non-first priorities. | |
# The next line just a naive break if there are no one to wait for anymore: then we match them randomly. | |
slowpokes = [p for p in self.session.get_participants() if p._index_in_pages < self._index_in_pages] | |
if len(slowpokes) == 0 and len(waiting_players) >= group_size: | |
return waiting_players[:group_size] | |
unique_1 = self.get_unique(waiting_players, 'first') | |
if len(unique_1) >= group_size: | |
return unique_1[:group_size] | |
if len(waiting_players) >= stopper: | |
# we need to find the lacking element in the second priorites to add missing one(s) to a first priority list | |
priorities_1 = [w.participant.vars['first'] for w in unique_1] | |
unique_2 = self.get_unique(waiting_players, 'second', filtering=priorities_1, matched=unique_1) | |
unique_1_2 = unique_1 + unique_2 | |
if len(unique_1_2) >= group_size: | |
return unique_1_2[:group_size] | |
priorities_2 = [w.participant.vars['second'] for w in unique_2] | |
unique_1_2_3 = unique_1_2 + self.get_unique(waiting_players, 'third', filtering=priorities_1 + priorities_2, | |
matched=unique_1_2) | |
return unique_1_2_3[:group_size] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It is built on the assumption that:
Number of priorities equals 3.
Each member in the group should ideally have a unique top priority. If something more complicated need (like
2 journalists, 1 economist
), the code needs adjustment