# the forever bag

Thread in 'Research & Development' started by rain, 29 Apr 2017.

1. ### rain

A weird little randomizer I came up with recently. I haven't tested it much in-game. Its droughts aren't as bad as TAP's (it's somewhere between bag and 2bag), but the chance of doubles is higher (but not as bad as full random). From the file:

Pieces are taken from a set bag (such as JILTSOZ) in order, repeating, to fill a window of a fixed size (I use 4, but any number > 1 works; higher numbers behave more like full random, but still with shorter droughts). Each time a piece is needed, it is chosen randomly from the window, and then replaced with the next piece in the bag order. The order of the bag is notably important when the window size is smaller than the bag -- this limits what the first piece can be (only JILT, with my parameters).

Code:
'''
the Forever Bag

Pieces are taken from a set bag (such as JILTSOZ) in order, repeating, to fill a window of a fixed size (I use 4, but any number > 1 works; higher numbers behave more like full random, but still with shorter droughts). Each time a piece is needed, it is chosen randomly from the window, and then replaced with the next piece in the bag order. The order of the bag is notably important when the window size is smaller than the bag -- this limits what the first piece can be (only JILT, with my parameters).

Worst droughts: full random > nes > tap > 2bag > foreverbag > bag > flatbag
Chance of doubles: full random > 2bag > foreverbag > nes > bag > tap > flatbag
Bagginess: flatbag > bag > tap > foreverbag > 2bag > nes > full random

flatbag = JILTSOZ dealt in order, repeating forever
2bag = one bag of two sets of JILTSOZ (14 piece bag)
bagginess = percent of 7-piece windows which have all 7 pieces
'''
import random

class ForeverBag:
def __init__(self, bag, windowsize):
self.bag = list(bag)
self.size = windowsize
self.window = []
self.i = 0

for i in range(self.size):
self.window.append(self.bag[self.i])
self.i = (self.i + 1) % len(self.bag)

def next(self):
r = random.randint(0, self.size - 1)
p = self.window[r]
self.window[r] = self.bag[self.i]
self.i = (self.i + 1) % len(self.bag)
return p

if __name__ == '__main__':
fb = ForeverBag('jiltsoz', 4)
for i in range(10):
s = ''
for i in range(40):
s += fb.next()
print s


2. ### colour_thief

I think this is 'asymmetric' in the sense where JI is more common than IJ and weird stuff like that.

3. ### rain

Ah so it is. If you shuffle the bag each time it is exhausted, it removes that bias (which I believe is determined by the order of the bag) -- the result looks pretty close to 2bag, but presumably without seams.