# Agent based model of lexicon convergence
import random

alphabet = ['p','t','k','b','d','g','i','a','u','o','s','n']

def initialize(numAgents, lexSize, wordLen, minConnections):
    agents = [initAgent(lexSize, wordLen) for i in range(numAgents)]
    network = initNetwork(agents, minConnections)
    return agents, network

def initAgent(lexSize, wordLen):
    agent = {}
    for meaning in range(lexSize):
        agent[meaning] = {}
        agent[meaning][randomWord(wordLen)] = 1
    return agent

def randomWord(wordLen):
    word = ''
    while wordLen > 0:
        wordLen -= 1
        word += random.choice(alphabet)
    return word

def initNetwork(agents, minConnections):
    network = {}
    for srcAgent in range(len(agents)):
        numDests = random.randint(minConnections, len(agents)-1)
        dests = random.sample(range(len(agents)), numDests)
        network[srcAgent] = dests
    return network

def pickone(cdict):
    tot = sum(cdict.values())
    n = random.randint(1,tot)
    for k in cdict:
        n -= cdict[k]
        if n <= 0: return k 

def updateAgents(agents, network):
    for (srcIndex, srcAgent) in enumerate(agents):
        # pick destination agent
        destAgentIndex = random.choice(network[srcIndex])
        destAgent = agents[destAgentIndex]
        # pick meaning and word that srcAgent says
        meaning = random.choice(srcAgent.keys())
        word = pickone(srcAgent[meaning])

        print '%s -> %s: "%s = %s"' % (srcIndex, destAgentIndex, meaning, word)
        # update destAgent's lexicon
        if word not in destAgent[meaning]:
            destAgent[meaning][word] = 0
        destAgent[meaning][word] += 1
    print '\n'

def runSimulation(agents, network, timesteps):
    while timesteps > 0:
        timesteps -= 1
        updateAgents(agents, network)















        
