Skip to content

Instantly share code, notes, and snippets.

@zhengyangchoong
Last active October 19, 2017 15:05
Show Gist options
  • Save zhengyangchoong/3bc58397402abea5b09602ffcebc3679 to your computer and use it in GitHub Desktop.
Save zhengyangchoong/3bc58397402abea5b09602ffcebc3679 to your computer and use it in GitHub Desktop.
raffle ticket simulator
from __future__ import division
import random
from scipy import stats
random.seed("asdfghjkl")
class Game:
def __init__(self,N):
self.cards = []
self.N = int(N/2)
for i in xrange(self.N):
self.cards.append(i)
self.cards.append(i)
self.failures = 0
random.shuffle(self.cards)
#print self.cards
def enter(self, x): # x is a list of two numbers
if not self.cards[x[0]] == self.cards[x[1]]:
self.failures += 1
return [self.cards[x[0]], self.cards[x[1]]]
class Player:
def __init__(self,N, logging = False):
self.N = N
self.known = {} # indices value. known but insovled
self.unknown = [i for i in xrange(self.N)] # unknown indices
self.solved = [] # solved and can be ignored
self.gameState = True
self.game = Game(N)
self.logging = logging
self.controller()
def controller(self):
while self.gameState:
self.play()
#print "game complete"
#print "failures: {}".format(self.game.failures)
def initguess(self, n1, N):
n2 = random.randint(0,N)
if n2 == n1:
return self.initguess(n1, N)
else:
return n2
def limitedguess(self,n1):
n2 = random.choice(self.unknown)
if n2 == n1:
return self.limitedguess(n1)
else:
return n2
def scanforsolved(self):
if not len(self.known.values()) == len(set(self.known.values())):
seen = {}
success = []
for i in self.known:
if self.known[i] not in seen:
seen[self.known[i]] = [i]
else:
seen[self.known[i]].append(i)
for i in seen:
if len(seen[i]) > 1: # success
success.append(seen[i])
return success
else:
return None
def play(self):
if (len(self.known)) == 0 and len(self.solved) == 0:
n1 = random.randint(0,self.N-1)
n2 = self.initguess(n1, self.N-1)
else:
n1 = random.choice(self.unknown)
n2 = self.limitedguess(n1)
#print [n1,n2]
self.check([n1,n2])
# scan through known to see if any can be solved
jigsaw = self.scanforsolved()
if not jigsaw == None:
for pair in jigsaw:
self.check(pair)
def check(self, numbers):
results = self.game.enter(numbers) #
if results[0] == results[1]:
self.solved.append(numbers[0])
self.solved.append(numbers[1])
if numbers[0] in self.known.keys():
self.known.pop(numbers[0], None)
if numbers[1] in self.known.keys():
self.known.pop(numbers[1], None)
#print "success!"
else:
self.known[numbers[0]] = results[0]
self.known[numbers[1]] = results[1]
try:
self.unknown.remove(numbers[0])
self.unknown.remove(numbers[1])
except:
pass
if self.logging:
print "Known: {}".format(self.known)
print "Unknown: {}".format(self.unknown)
print "Solved: {}".format(self.solved)
print "--"
if len(self.solved) == self.N or self.N - len(self.solved) == 2:
self.gameState = False
def main():
n_trials = 10**4
failures = []
for i in xrange(n_trials):
player = Player(18, logging = False)
failures.append(player.game.failures)
failure_distribution = {}
for i in failures:
if i not in failure_distribution:
failure_distribution[i] = 1
else:
failure_distribution[i] += 1
for i in failure_distribution:
failure_distribution[i] /= n_trials
print failure_distribution
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment