Skip to content

Instantly share code, notes, and snippets.

@jondavidjohn
Created January 18, 2012 05:35
Show Gist options
  • Save jondavidjohn/1631187 to your computer and use it in GitHub Desktop.
Save jondavidjohn/1631187 to your computer and use it in GitHub Desktop.
List Shuffle (humanoid)
@staticmethod
def humanoid_shuffle(items, num_shuffles=6):
# how many times items can be pulled from the same list consecutively
MAX_STREAK = 10
# divide list roughly in half
num_items = len(items)
end_range = int(num_items / 2 + random.randint(0, int(.1 * num_items)))
first_half = items[:end_range] # list up to 0 - end_range
second_half = items[end_range:] # list after end_range - len(items)
split_lists = (first_half, second_half)
mixed = []
streak = current_item_index = 0
# while both lists still contain items
while first_half and second_half:
# calc the percentage of remaining total items
remaining = (1 - float(len(mixed)) / num_items)
# if we happen to generate a random value less than the remaining percentage
# which will be continually be decreasing (along with the probability)
# or
# if MAX_STREAK is exceeded
if random.random() < remaining or streak > MAX_STREAK:
# switch which list is being used to pull items from
current_list_index = 1 ^ current_list_index
# reset streak counter
streak = 0
# pop the selected list onto the new (shuffled) list
mixed.append(split_lists[current_list_index].pop())
# increment streak of how many consecutive times a list has remained selected
streak += 1
# add any remaining items
mixed.extend(first_half)
mixed.extend(second_half)
num_shuffles -= 1
# if we still have shuffles to do
if num_shuffles:
# rinse and repeat
mixed = Simulator.humanoid_shuffle(mixed, num_shuffles)
# finally return fully shuffled list
return mixed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment