# MyHive.py

from SimpleGraphics import *
from random import randint as randi
from HexTools import *


def ShowBeeline(B):
    """ Displays the random walk encoded in B

    PreC: B is a Beeline String that encodes
    an escape from a honeycomb. It is assumed that that honeycomb
    is displayed in the plot window.
    """

    # The location of the bee is (x,y)
    x = 0
    y = 0
    DrawDisk(x,y,.3,FillColor=BLUE)
    for c in B:
        if c != 'z':
            # The bee is going to move to a neighbor cell...
            i = int(c)
            x,y = NeighborCenter(x,y,i)
            DrawDisk(x,y,.3,FillColor=BLUE)


def ShowBeeline2(B):
    """ Displays the random walk encoded in B

    PreC: B is a Beeline String that encodes
    an escape from a honeycomb. It is assumed that that honeycomb
    is displayed in the plot window.
    """
    # draw start position. x, y are the current position
    x = 0.0
    y = 0.0
    DrawDisk(x,y,.3,FillColor=BLUE)

    for i in range(len(B)):
        # B[i] represents where the next disk, if any, should be drawn
        if B[i] != 'z':
            x,y = NeighborCenter(x, y, int(B[i]))
            DrawDisk(x,y,.3,FillColor=BLUE)



def MakeBeeline(m,GPS):
    """ Returns a BeeLine string that encodes a completed
    random walk on a size-m honeycomb. If GPS is True then
    the GPS-rule is followed. Otherwise the non-GPS rule is
    followed.

    PreC: m is a positive integer that satisfies m>=3 and GPS
    is a Boolean.
    """

    # The honeycomb radius...
    r = m-2
    # (a,b) is the location of the bee...
    a = 0.0
    b = 0.0
    # The beeline string will be built up in B
    B = ''
    while Dist(a,b)<=r+1:
        # Compute the center of a random neighbor
        i = randi(1,6)
        aNew,bNew = NeighborCenter(a,b,i)
        if not GPS:
            # The bee goes there...
            a = aNew
            b = bNew
            B = B + str(i)
        elif Dist(aNew,bNew)>Dist(a,b):
            # The bee goes there if the new location is further away from (0,0).
            a = aNew
            b = bNew
            B = B + str(i)
        else:
            # Stay put...
            B = B + 'z'
    return B


def Dist(x,y):
    """ Returns a float that is the distance
    from (x,y) to (0,0).

    PreC: x and y are floats
    """
    return sqrt(x**2+y**2)


def AveBeeline(m,GPS,Nmax):
    """ Returns a float that estimates the average length of a Beeline string.
    The average is based on Nmax trials. If GPS is True then the GPS hopping rule
    is used. Otherwise the non-GPS hopping rule is used.

    Pre: m is a positive integer that satisfies m>=3.
    """
    r = m-2
    s = 0
    for N in range(Nmax):
        s = s + len(MakeBeeline(m,GPS))
    return float(s)/float(Nmax)


if __name__ == '__main__':
    # Set the size of the honeycomb...
    # m = 15
    # # Show a worker bee escape...
    # MakeWindow(m,bgcolor=BLACK,labels=False)
    # DrawHoneyComb(m)
    # B = MakeBeeline(m,False)
    # ShowBeeline(B)
    # # Show a Drone escape...
    # MakeWindow(m,bgcolor=BLACK,labels=False)
    # DrawHoneyComb(m)
    # B = MakeBeeline(m,True)
    # ShowBeeline(B)
    # ShowWindow()

    # Report a range of averages
    Nmax = 100
    print '     Averages with    Averages with'
    print ' m    GPS Hopping    No-GPS Hoppping'
    print '---------------------------------------'
    for m in range(10,110,10):
        r = m-1
        aveGPS = AveBeeline(r,True,Nmax)
        aveNoGPS = AveBeeline(r,False,Nmax)
        print '%3d  %8.1f          %8.1f ' % (m,aveGPS,aveNoGPS)


    print '\n(Averages based on %1d trials)\n' % Nmax