Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Script to simulate a riffle shuffle (adapted to fit Magic The Gathering: Commander decks)
- import random
- # the maximum difference of stack sizes (in number of cards) when splitting the deck
- splitting_deviation_in_cards = 5
- # the probability of mistakes during the merging of the two card stacks
- # range 0 to 1 where 0 means the shuffle is perfectly executed, always taking exactly one card from each stack
- # and 1 resulting in a 50% chance to get a card from the same stack as before
- merging_randomness = 0.05
- # similar to 'merging_randomness' but only applies to the first card when merging two stacks and is either random or not
- first_card_is_always_from_left_stack = False
- # how many time the deck shall be shuffled
- number_of_shuffles = 1000
- # verbosity of the script (1 = print finished shuffle, 2 = print every iteration, 3 = print everything)
- log_level = 1
- def main():
- stack_of_cards = ["c" for x in range(0, 30)] + ["s" for x in range(0, 10)] + ["i" for x in range(0, 10)] + ["a" for x in range(0, 11)] + ["l" for x in range(0, 38)]
- print("Unshuffled deck: " + ''.join(stack_of_cards))
- for i in range(1, number_of_shuffles):
- stack_of_cards = riffleShuffle(stack_of_cards)
- if (log_level >= 2):
- print("Shuffled deck " + str(i) + " times: [" + str(landScore(stack_of_cards)) + "] " + ''.join(stack_of_cards))
- stack_of_cards = riffleShuffle(stack_of_cards)
- print("Shuffled deck " + str(number_of_shuffles) + " times: [" + str(landScore(stack_of_cards)) + "] " + ''.join(stack_of_cards))
- def riffleShuffle(stack_of_cards):
- split_stack_of_cards = splitStack(stack_of_cards)
- shuffled_stack = mergeStacks(split_stack_of_cards[0], split_stack_of_cards[1])
- return (shuffled_stack)
- def splitStack(stack_of_cards):
- size_of_stack = len(stack_of_cards)
- deviation_in_cards = round(random.uniform(0, 1) * splitting_deviation_in_cards)
- deviation_is_positive = coinFlip()
- deviation_from_middle_of_stack = deviation_in_cards if deviation_is_positive else -deviation_in_cards
- middle_of_stack = round(size_of_stack / 2) + deviation_from_middle_of_stack
- left_half = [stack_of_cards[i] for i in range(0,middle_of_stack)]
- right_half = [stack_of_cards[i] for i in range(middle_of_stack,size_of_stack)]
- split_stack_of_cards = [left_half, right_half]
- if (log_level >= 3):
- print(" missed the center of the deck by " + str(deviation_from_middle_of_stack) + " cards while splitting: " + str(split_stack_of_cards))
- return split_stack_of_cards
- def mergeStacks(lhs, rhs):
- next_card_comes_from_from_lhs = True if first_card_is_always_from_left_stack else coinFlip()
- probability_that_next_card_comes_from_opposite_site = (1 - merging_randomness/2)
- merged_stack = [lhs.pop(0)] if next_card_comes_from_from_lhs else [rhs.pop(0)]
- while (len(lhs) > 0 and len(rhs) > 0):
- random_number = random.uniform(0, 1)
- if (random_number <= probability_that_next_card_comes_from_opposite_site):
- next_card_comes_from_from_lhs = not next_card_comes_from_from_lhs
- merged_stack.append(lhs.pop(0) if next_card_comes_from_from_lhs else rhs.pop(0))
- for card in lhs:
- merged_stack.append(card)
- for card in rhs:
- merged_stack.append(card)
- return merged_stack
- def landScore(stack_of_cards):
- consecutive_lands_list, consecutive_non_lands_list = landAnalysis(stack_of_cards)
- consecutive_lands_score = sum([pow(2, x-2) for x in consecutive_lands_list if x >= 2])
- consecutive_non_lands_score = sum([pow(2, x-3) for x in consecutive_non_lands_list if x >= 3])
- return consecutive_lands_score + consecutive_non_lands_score
- def landAnalysis(stack_of_cards):
- consecutive_lands_list = []
- consecutive_non_lands_list = []
- land_streak = 0
- non_land_streak = 0
- for card in stack_of_cards:
- if (card == 'l'):
- land_streak = land_streak + 1
- if (non_land_streak > 0):
- consecutive_non_lands_list.append(non_land_streak)
- non_land_streak = 0
- else:
- non_land_streak = non_land_streak + 1
- if (land_streak > 0):
- consecutive_lands_list.append(land_streak)
- land_streak = 0
- if (land_streak > 0):
- consecutive_lands_list.append(land_streak)
- if (non_land_streak > 0):
- consecutive_non_lands_list.append(non_land_streak)
- return (consecutive_lands_list, consecutive_non_lands_list)
- def coinFlip():
- return round(random.uniform(0, 1))
- main()
Advertisement
Add Comment
Please, Sign In to add comment