-1

I am working on a code that looks at choice game in a mutliple round game. There are four choice (A,B,C,D) options and four payoff pools (pool_1, pool_2, pool_3 and pool_4). Every round there is one choice to be selected. Each choice is asssigned to one pool (A - pool_1 etc).

I want to randomly shuffle the pools once 5 in 6 choices have been the same (e.g. AAABAA or BCBBBB -> e.g. change pool_1 to any other BUT pool_1). Also there should be an automatic shuffle once every 20 rounds to make sure that even if no choice is selected 5 in 6 times, that the pools stil change.

For now I have coded it the way that after 5 streaks (5 choices in a row) the pools change. I just do not manage to have the pools change after any 5 in 6 choices (having been identical) together with a change every 20 rounds and also sometimes the same pool gets randomly selected straight again, which I do not want.

if (streak % 5) == 0 : pools = [pool_1, pool_2, pool_3, pool_4] random.shuffle(pools)

work1 = pools[0]
work2 = pools[1]
work3 = pools[2]
work4 = pools[3]

Any help is appreaciated -thank you!

Lenikago
  • 1
  • 1

1 Answers1

0

Streak tracking

For determining if five of the last six choices are the same, you could use a deque to keep track of the last N choices. You'd want to limit the size to 6. Whenever a choice is made, append the choice to your deque.

from collections import deque
from collections import Counter

last_three_choices = deque('', maxlen=3)  # using 3 for brevity
last_three_choices.append('A')            # User picked A. History is now A
last_three_choices.append('B')            # User picked B. History is now AB
last_three_choices.append('C')            # User picked C. History is now ABC
last_three_choices.append('A')            # User picked A. History is now BCA
last_three_choices.append('C')            # User picked C. History is now CAC

After appending the choice, make a Counter based on your deque to determine how many times each choice has been made. Filter that to only contain keys whose value is 5 or more (there should be at most one!) and if there are any, that's a choice that has been made five times in the last six trials.

two_out_of_three = deque('CAC')                           # Restoring state from above
streakyness = Counter(two_out_of_three)                   # This will be {'C':2, 'A':1}
streaked = {k:v for (k,v) in streakyness.items() if v>=2} # This will just be {'C':2}

Then you can use Python's treatment of empty dictionaries as False to extract the offending choice and perform a shuffle if there's been a streak:

if streaked:                             
  repeated_choice = next(iter(streaked)) # Retrieve the key
  do_shuffle_thing(repeated_choice)      # Invoke your shuffling procedure

Antagonistic shuffling

For not-completely-random shuffling in which a particular element (the one that was streaked) is guaranteed to not have a particular final location (its original location), assuming you're really only dealing with a small number of choices, you could basically use a bogosort with a very relaxed 'order' criterion:

pool_to_move = pools[repeated_choice]
while pools[repeated_choice] == pool_to_move:
  random.shuffle(pools)

With each pass, you have a 1 in 6 chance of getting a bad shuffle that requires reshuffling, so after N iterations you only have a 6^N chance of needing to keep going. Theoretically it could go on forever, but unless your RNG is biased to hate games that exploding dice, it should terminate quickly.

You may note I assumed that pool is a dictionary with choices as keys, rather than a list like you've got. But no worry: shuffling dictionary keys is a doable thing.

Community
  • 1
  • 1
Bryant
  • 622
  • 4
  • 18