# If we have up to k rounds, which probability should we 
# use to ensure that the adversary can't force us to split
# the blocks that the working listening stations think are good.
# We abstract that problem into the following:
# There are up to k rounds. The adversary chooses one of these at random.
# called that advchoice.
# If we end after round advchoice then the adversary wins that round.
# The adversary is assumed to know our probability p,


import random
import numpy as np 

print("Remember to use python3")

# given that we have n more rounds at a maximum, try various p values to find
# the best one.
def findp(n):
  p = 0.5
  x = p**n
  while x < (1-p):
    p+= 0.005 
    x = p ** n
  return(p)

numtrials = 500
maxrounds = 100
p = 0.8
out = []
while(p < 1):
  p+= 0.005
  i = 0
  numwins_rand = 0 # when using random
  numwins_first = 0 # when choosing first round
  numwins_last = 0 # when choosing last round
  while( i < numtrials):
    i+= 1
    advchoice = random.randint(1,maxrounds)
    flag = True
    j = 1
    while(flag):
      x = random.random()
      if (x >= p) and (j == 1):
        numwins_first+= 1
        print("p is: " + str(p) + " numwins_first: "+ str(numwins_first))
        flag = False
      if (j == maxrounds-1):
        numwins_last+=1
        print("p is: " + str(p) + " numwins_last: "+ str(numwins_last))
        flag = False
      if (x >= p): 
        flag = False
        if j == advchoice:
          numwins_rand+= 1
          print("p is: " + str(p) + " numwins_rand: "+ str(numwins_rand))
      else:
        j+= 1
  out.append([p, numwins_rand/numtrials, numwins_first/numtrials, numwins_last/numtrials])


# Now we try our variable approach
numwins_rand = 0 # when using random
numwins_first = 0 # when choosing first round
numwins_last = 0 # when choosing last round
i = 0
while( i < numtrials):
  i+= 1
  advchoice = random.randint(1,maxrounds)
  flag = True
  j = 1
  while(flag):
    p = findp(maxrounds-j)
    # print("j is: ", str(j), " p is: ", str(p))
    x = random.random()
    if (x >= p) and (j == 1):
      numwins_first+= 1
      flag = False
    if (j == maxrounds-1):
      numwins_last+=1
      flag = False
    if (x >= p): 
      flag = False
      if j == advchoice:
        numwins_rand+= 1
    else:
      j+= 1

out.append([p, numwins_rand/numtrials, numwins_first/numtrials, numwins_last/numtrials])


print("Probabilities and adversary win fractions: ")
for e in out:
  print(str(round(e[0],6)) + (" random: ") + str(round(e[1],6)) + (" first: ") + str(round(e[2],6)) + (" last: ") + str(round(e[3],6)) + (" max: ") + str(round(max(e[1:]),6)))

