Beispiel #1
0
    def findKthNumber(self, n, k):
        """
        :type n: int
        :type k: int
        :rtype: int
        """
        
        if n>1 and k>1:
            t = Tree(1, compare=compare)
            count = 1
            tmax = 1
            for l in range(2,n+1):
                if count < k:
                    t.addNode(l)
                    tmax = t.find_max()
                    count += 1
#                    print("# added %i and now max = %i" % (l, tmax))
                else: # count > k

                    if int(str(l)[0])

                    if compare(l, tmax):
                        t.addNode(l)
                        t, tmax = t.del_max()
#                        print("# added %i and removed max. current max = %i" % (l, tmax))
                    else:
                        continue
                    
#            t.printTree()
            return t.find_max()
        else:
            if n==1 or k==1:
                return 1
Beispiel #2
0
def list2Tree(lst):
    if len(lst) == 0:
        return None
    else:
        root = Tree(lst[0])
        if len(lst) > 1:
            for i in lst[1:]:
                root.addNode(i)
        return root
Beispiel #3
0
    def solver(self, adjLists):
        solutions = []

        # Get the set of all words in the corpus. Set is more performant than list here.
        corpus = set(w.lower() for w in nltk.corpus.words.words())

        # load words into tree. Don't load anything shorter than 3 or longer than
        # current letter set plus 1(ie 4x4 board would be 16 characters w/o QU or 17 with)
        #  max because we can only visit that letter once)
        tree = Tree()
        for w in corpus:
            if len(w) < 3:
                continue
            if len(w) > (self.boardSize * self.boardSize) + 1:
                continue
            first = Node(w[0])
            subsequent = w[1:]
            parent = tree.addNode(first)
            last = None
            for c in subsequent:
                child = tree.addNode(Node(c), parent)
                parent = child
                last = child
            # mark the end of a word for later
            if last is not None:
                last.endsWord = True

        # walk the word tree with the letters on the board,
        # building up strings by adjacencies.
        visited = []
        sols = []
        #pos in self.currentLetters: # board in order

        # Not working yet.
        '''
        for idx, val in np.ndenumerate(self.currentLetters):
            #idx position
            #val letter
            self.findStrings(idx, tree.root.children[0], visited)
        '''
        # just returning something for now so I can pass them to the front end
        return ['solution1', 'solution2', 'solution3']
Beispiel #4
0
class TreeBuilder:
    '''
    Builds a tree from a given list of values
    '''
    def __init__(self):

        self.tree = Tree()
        self.values = []

    def setValues(self, newValues: List[NUM]):

        self.values = newValues
        self.tree = Tree()  # need to rebuild tree

    def build(self):

        for value in self.values:

            newNode = Node()
            newNode.setValue(value)
            self.tree.addNode(newNode)
def main(arguments):
    if len(arguments) < 3:
        print 'The argument 1 should be a filename to pickle tree contents into.' 
        print 'The argument 2 should be the directory where the images can be found.'
    else:
	imagenet_tree = Tree('Image Net Tree')
        # Add our selected parent nodes
        imagenet_tree.addNode('n00017222'); # Plant flora root node
        imagenet_tree.addNode('n13083586','n00017222'); # Vascular root
        # Add nodes which we need to build the tree for to a dictionary form node:parent
        node_dictionary = { 
		'n13134302':'n13083586', # Vascular child: Bulbous
		'n13121544':'n13083586', # Vascular child: Aquatic
	        'n13121104':'n13083586', # Vascular child: Desert
		'n13103136':'n13083586', # Vascular child: Woody plants
		'n13100677':'n13083586', # Vascular child: Vines
		'n13085113':'n13083586', # Vascular child: Weed
		'n13084184':'n13083586', # Vascular child: Succulent
		'n12205694':'n13083586', # Vascular child: Herb
		'n11552386':'n13083586', # Vascular child: Spermatophyte
		'n11545524':'n13083586', # Vascular child: Pteridophyte
		'n13100156':'n00017222', # House plant root
		'n13083023':'n00017222', # Poisonous root
        }
        for node in node_dictionary:
            print 'Processing %s' % (node)
            number_of_images = 0
            if (os.path.isdir(arguments[2]+'/'+node)):
                number_of_images = len([name for name in os.listdir(arguments[2]+'/'+node) 
                                        if os.path.isfile(arguments[2]+'/'+node+'/'+name) and name[-5:] == '.JPEG'])
            imagenet_tree.addNode(node,node_dictionary[node],number_of_images)
            print 'Images found for %s:%i' % (node,number_of_images)
            addAllNodes(imagenet_tree,node,arguments[2])
        pickled_file = open(arguments[1],'wb')
	pickle.dump(imagenet_tree,pickled_file)
Beispiel #6
0
def main(arguments):
    if len(arguments) < 3:
        print 'The argument 1 should be a filename to pickle tree contents into.'
        print 'The argument 2 should be the directory where the images can be found.'
    else:
        imagenet_tree = Tree('Image Net Tree')
        # Add our selected parent nodes
        imagenet_tree.addNode('n00017222')
        # Plant flora root node
        imagenet_tree.addNode('n13083586', 'n00017222')
        # Vascular root
        # Add nodes which we need to build the tree for to a dictionary form node:parent
        node_dictionary = {
            'n13134302': 'n13083586',  # Vascular child: Bulbous
            'n13121544': 'n13083586',  # Vascular child: Aquatic
            'n13121104': 'n13083586',  # Vascular child: Desert
            'n13103136': 'n13083586',  # Vascular child: Woody plants
            'n13100677': 'n13083586',  # Vascular child: Vines
            'n13085113': 'n13083586',  # Vascular child: Weed
            'n13084184': 'n13083586',  # Vascular child: Succulent
            'n12205694': 'n13083586',  # Vascular child: Herb
            'n11552386': 'n13083586',  # Vascular child: Spermatophyte
            'n11545524': 'n13083586',  # Vascular child: Pteridophyte
            'n13100156': 'n00017222',  # House plant root
            'n13083023': 'n00017222',  # Poisonous root
        }
        for node in node_dictionary:
            print 'Processing %s' % (node)
            number_of_images = 0
            if (os.path.isdir(arguments[2] + '/' + node)):
                number_of_images = len([
                    name for name in os.listdir(arguments[2] + '/' + node)
                    if os.path.isfile(arguments[2] + '/' + node + '/' +
                                      name) and name[-5:] == '.JPEG'
                ])
            imagenet_tree.addNode(node, node_dictionary[node],
                                  number_of_images)
            print 'Images found for %s:%i' % (node, number_of_images)
            addAllNodes(imagenet_tree, node, arguments[2])
        pickled_file = open(arguments[1], 'wb')
        pickle.dump(imagenet_tree, pickled_file)
Beispiel #7
0
import numpy as np
from tree import Tree
from lexicographical import compare

np.random.seed(1234)
lst = np.random.randint(0, 50, 10)

print(lst)

t = Tree(lst[0])
for l in lst[1:]:
    t.addNode(l)

t.printTree()

t = t.del_max()

print("head = ", t.val)
if t.right is not None:
    print("head.right = ", t.right.val)

t.printTree()

for _ in range(5):
    print("remove..")
    t = t.del_max()
    t.printTree()
Beispiel #8
0
def geraGrafo(id, id_pai, estado_inicial, estado_final, restricoes, pesos, personagens, num_ocupantes_barco, dicionario_heuristica, problema):
    def prob_1():
        root.destroy()

        ROOT = 0

        # Fazendeiro, alface, bode, lobo:
        dicionario_heuristica = {
            'A B F L|': 22,
            'A L|B F': 18,
            'A F L|B': 17,
            'L|A B F': 14,
            'A|B F L': 12,
            'B F L|A': 10,
            'A B F|L': 8,
            'B|A F L': 5,
            'B F|A L': 4,
            '|A B F L': 0
        }

        # comecamos com id(atual) = id)pai = ROOT
        id = ROOT
        id_pai = ROOT

        estado_inicial = "A B F L|"
        estado_final = "|A B F L"

        # vetor com as restricoes do problema
        restricoes = ["A,B", "L,B"]  # Vetor de restrições

        # vetor com os pesos referentes ao transporte de cada personagem
        pesos = {'F': 1, 'A': 2, 'B': 3, 'L': 4}

        # vetor de personagens
        personagens = ['F', 'A', 'B', 'L']

        # capacidade do barco
        num_ocupantes_barco = 2

        geraGrafo(id, id_pai, estado_inicial, estado_final, restricoes, pesos, personagens, num_ocupantes_barco,
                  dicionario_heuristica, 1)

    def prob_2():
        root.destroy()

        ROOT = 0

        # Cachorro Fazendeiro Gato Queijo Rato:
        dicionario_heuristica = {
            'C F G Q R|': 17,  # 0
            'G Q|C F R': 8,  # 1
            'C R|F G Q': 10,  # 2
            'C Q|F G R': 17,  # 3
            'F G Q|C R': 7,  # 4
            'C F G Q|R': 18,  # 5, 10
            'F G Q R|C': 12,  # 6
            'C F R|G Q': 9,  # 7
            'C F G R|Q': 19,  # 8
            'C F Q R|G': 19,  # 9, 11
            'Q|C F G R': 12,  # 12, 15, 19, 28, 30, 34
            'G|C F Q R': 10,  # 13, 16, 20, 25, 31
            '|C F G Q R': 0,  # 14, 23
            'C|F G Q R': 13,  # 17, 22, 26, 29, 32, 35
            'R|C F G Q': 13,  # 18, 21, 24, 27, 33
            'F G R|C Q': 8  # 36, 37, 38, 39, 40, 41, 42, 43....
        }

        # comecamos com id(atual) = id)pai = ROOT
        id = ROOT

        id_pai = ROOT

        estado_inicial = "C F G Q R|"
        estado_final = "|C F G Q R"

        # vetor com as restricoes do problema
        restricoes = ["C,G", "G,R", "R,Q"]  # Vetor de restrições

        # vetor com os pesos referentes ao transporte de cada personagem
        pesos = {'F': 1, 'Q': 2, 'R': 3, 'G': 4, 'C': 5}

        # vetor de personagens
        personagens = ['F', 'C', 'G', 'R', 'Q']

        # capacidade do barco
        num_ocupantes_barco = 3

        geraGrafo(id, id_pai, estado_inicial, estado_final, restricoes, pesos, personagens, num_ocupantes_barco,
                  dicionario_heuristica, 2)

    # criando objeto arvore
    arvore = Tree()

    # adicionando no raiz
    arvore.addNode(estado_inicial, 0)

    # Gerando os conjuntos de restricoes
    global restr_sep
    restr_sep = [x.split(',') for x in restricoes]

    def valida_margem(margem):

        # Se o fazendeiro está na margem, nao tem problema
        if not ('F' in margem):
            combinacoes = list(itertools.combinations(margem, 2))

            for i in combinacoes:  # passando por todas as combinacoes, 2 a 2, dos elementos da margem
                for j in restr_sep:  # passando pelas restricoes
                    if (set(i) == set(
                            j)):  # comparando se as combinacoes batem com alguma das restricoes -> movimento invalido

                        return False
        return True

    # verifica se um no ja existe
    def ja_existe(msg, id_pai_atual):

        # separa a msg no |(que se refere ao rio). Assim, ficamos com os vetores referentes as margens esquerda e direita
        msg_arr = msg.split('|')
        msg_arr_esq = msg_arr[0].split()  # elementos presentes na margem esquerda
        msg_arr_dir = msg_arr[1].split()  # elementos presentes na margem direita

        # iterando sobre os nos presentes na arvore para verificar se existe um no que tenha como dado o mesmo valor presente em msg
        for i in arvore.getAllNodes():
            dado_no = i.getData().split('|')  # divide a mensagem em margem direita e esquerda por meio do sinal |
            dado_no_esq = dado_no[0].split()  # elementos referentes a margem esquerda
            dado_no_dir = dado_no[1].split()  # elementos referentes a margem esquerda
            if ((sorted(dado_no_esq) == sorted(msg_arr_esq)) or (sorted(dado_no_dir) == sorted(
                    msg_arr_dir))):  # trabalha com os elementos ordenados JA que, para o problema, A B seja igual a B A
                if (i.getId() <= ((id_pai_atual) - 1)) or (
                        i.getId() == 0):  # testa se o id do no igual é o inicial ou se esta pelo menos 1 valor atras do atual
                    return True

        return False  # o no ainda nao existe, ou sua criacao nao resulta em um loop

    def calcula_custo(estado_pai, estado_filho):
        custo = 0
        quem_viajou = []
        margens_pai = estado_pai.split('|')
        margem_dir_pai = margens_pai[0].split()
        margem_esq_pai = margens_pai[1].split()
        margens_filho = estado_filho.split('|')
        margem_dir_filho = margens_filho[0].split()
        margem_esq_filho = margens_filho[1].split()
        if ('F' in margem_dir_pai):
            quem_viajou = list(set(margem_dir_pai) - set(margem_dir_pai).intersection(set(margem_dir_filho)))
        else:
            quem_viajou = list(set(margem_esq_pai) - set(margem_esq_pai).intersection(set(margem_esq_filho)))

        for ator in personagens:
            custo = custo + (ator in quem_viajou) * pesos[ator]

        return custo

    arestas = []

    custos_arestas = dict()
    custo_transicao = 0
    # enquanto o id do no atual nao ultrapassar o numero de nos da arvore(caso em que a geracao da arvore deve encerrar, pois o ultimo no foi atingido e nao gerou nenhum filho)
    while (id_pai < len(arvore.getAllNodes())):
        num_gerados = 0  # ainda nao gerou nenhum filho

        # recupera o no atual
        no = arvore.getNode(id_pai)
        # recupera a informacao presente no nó, referente à modelagem das margens esquerda e direita
        margens = no.getData().split('|')
        margem_esq = margens[0].split()
        margem_dir = margens[1].split()

        # se o fazendeiro esta na margem esquerda, o barco saira dela
        if ('F' in margem_esq):

            for k in range(num_ocupantes_barco):
                # gera as combinacoes, 1 a 1 e 2 a 2, dos elementos da margem esquerda para que ocupem o barco, nao excedendo sua capacidade
                combinacoes = list(itertools.combinations(margem_esq, k + 1))

                for barco in combinacoes:
                    # se o fazendeiro esta no barco, a configuracao do barco eh valida, ja que soh o fazendeiro pode guia-lo
                    if ('F' in barco):
                        # a margem esquerda apos a saida dos ocupantes do barco
                        margem_esq_resultante = list(set(margem_esq) - set(barco))

                        # testa se a configuracao da margem, caso os ocupantes do barco zarpem, continua valida segundo as restricoes do problema
                        if (valida_margem(margem_esq_resultante)):

                            # constroi a mensagem referente ao estado do no, na forma: margem_esquerda|margem_direita
                            if (len(margem_esq_resultante)):
                                margem_esq_resultante = sorted(margem_esq_resultante)
                                msg = margem_esq_resultante[0]

                                for i in range(1, len(margem_esq_resultante)):
                                    msg = msg + ' ' + margem_esq_resultante[i]
                            else:
                                msg = ''

                            msg = msg + '|'
                            margem_dir_resultante = list(set(margem_dir).union(
                                set(barco)))  # a margem direita apos a chegada dos ocupantes do barco

                            if (len(margem_dir_resultante)):
                                margem_dir_resultante = sorted(margem_dir_resultante)
                                msg = msg + margem_dir_resultante[0]

                                for i in range(1, len(margem_dir_resultante)):
                                    msg = msg + ' ' + margem_dir_resultante[i]
                            else:
                                msg = msg + ''

                            if (not ja_existe(msg, id_pai)):  # se o no ainda nao existe
                                id = id + 1
                                aresta = (arvore.getNode(id_pai).getData(), msg)
                                arestas.append(aresta)

                                custo_transicao = calcula_custo(arvore.getNode(id_pai).getData(), msg)
                                custos_arestas[aresta] = custo_transicao

                                arvore.addNode(msg, id, custo_transicao, id_pai)  # cria um novo no

        else:
            # se o fazendeiro esta na margem esquerda, o barco saira dela
            if ('F' in margem_dir):

                for k in range(num_ocupantes_barco):
                    # gera as combinacoes, 1 a 1 e 2 a 2, dos elementos da margem esquerda para que ocupem o barco, nao excedendo sua capacidade
                    combinacoes = list(itertools.combinations(margem_dir, k + 1))

                    for barco in combinacoes:
                        # se o fazendeiro esta no barco, a configuracao do barco eh valida, ja que soh o fazendeiro pode guia-lo
                        if ('F' in barco):
                            # a margem direita apos a saida dos ocupantes do barco
                            margem_dir_resultante = list(set(margem_dir) - set(barco))
                            # testa se a configuracao da margem, caso os ocupantes do barco zarpem, continua valida segundo as restricoes do problema
                            if (valida_margem(margem_dir_resultante)):
                                # a margem esquerda apos a chegada dos ocupantes do barco
                                margem_esq_resultante = list(set(margem_esq).union(set(barco)))

                                # constroi a mensagem referente ao estado do no, na forma: margem_esquerda|margem_direita
                                if (len(margem_esq_resultante)):
                                    margem_esq_resultante = sorted(margem_esq_resultante)
                                    msg = margem_esq_resultante[0]

                                    for i in range(1, len(margem_esq_resultante)):
                                        msg = msg + ' ' + margem_esq_resultante[i]
                                else:
                                    msg = ''

                                msg = msg + '|'

                                if (len(margem_dir_resultante)):
                                    margem_dir_resultante = sorted(margem_dir_resultante)
                                    msg = msg + margem_dir_resultante[0]

                                    for i in range(1, len(margem_dir_resultante)):
                                        msg = msg + ' ' + margem_dir_resultante[i]
                                else:
                                    msg = msg + ''

                                if (not ja_existe(msg, id_pai)):  # se o no ainda nao existe
                                    id = id + 1

                                    aresta = (arvore.getNode(id_pai).getData(), msg)
                                    arestas.append(aresta)

                                    custo_transicao = calcula_custo(arvore.getNode(id_pai).getData(), msg)
                                    custos_arestas[aresta] = custo_transicao

                                    arvore.addNode(msg, id, custo_transicao, id_pai)  # cria um novo no

        # vai para o proximo no
        id_pai = id_pai + 1

    def converteDicToList(dicionario):
        num_nos = len(arvore.getAllNodes())
        lista = np.zeros(num_nos)
        for no in arvore.getAllNodes():
            for chave in dicionario:
                if chave == no.getData():
                    lista[no.getId()] = dicionario[chave]
                    break
        return lista

    for i in arvore.getAllNodes():
        print(i.getData())

    # exibe o grafo gerado
    '''f = open("grafo.txt","w+")
    print("\n\nPrintando grafo")
    for i in arvore.getAllNodes():
        f.write("-----\n")
        print("-----")
        f.write("[" + str(i.getId()) + "]\n")
        print("[", i.getId(),"]")
        if(not i.getParent() is None):
            f.write("Meu papai eh: " + str(i.getParent()) + "\n")
            print("Meu papai eh: " + str(i.getParent()))
        else:
            f.write("Nao tenho papai :(\n")
            print("Nao tenho papai :(")
        f.write("Minha informacao eh: " + str(i.getData()) + "\n")
        print("Minha informacao eh: ", i.getData())
        f.write("Meus filhinhos sao: " + str(i.getChildren()) + "\n")
        print("Meus filhinhos sao: ", i.getChildren())
        f.write("Os peso pra ir nos meus filhinhos são: " + str(i.getPesosParaOsFilhos()) + "\n\n")
        print("Os peso pra ir nos meus filhinhos são: ", i.getPesosParaOsFilhos())

    f.close()'''

    caminho_busca_largura = arvore.buscaLargura(arvore)

    vet_dist_estado_final = converteDicToList(dicionario_heuristica)

    caminho_busca_a_estrela = arvore.busca_A_estrela(arvore, vet_dist_estado_final)

    # Parte de exibição **********************************************

    nos = [v.getData() for v in arvore.getAllNodes()]

    exibeGrafo(nos, arestas, custos_arestas, personagens, estado_inicial, estado_final, caminho_busca_largura)

    # exibir em janela
    root = Tk()

    root.geometry("1000x620+0+0")
    if(problema == 1):
        root.title("IA - Travessia do rio: Fazendeiro, Lobo, Bode e Alface")
    else:
        if (problema == 2):
            root.title("IA - Travessia do rio: Fazendeiro, Cachorro, Gato, Rato e Queijo")

    # Frame superior ********************************
    FImgs = Frame(root, width=700, height=500, bd=1, relief=SUNKEN)
    FImgs.grid(row=0, padx=10, pady=15)

    imgEntrada = PhotoImage(file="grafo.png")
    labelImgEntrada = Label(FImgs, image=imgEntrada)
    labelImgEntrada.pack(side=LEFT, padx=15, pady=15)

    FLegenda = Frame(root, width=700, height=60, bd=1, relief=SUNKEN)
    FLegenda.grid(row=1)

    canvas = Canvas(FLegenda, width=50, height=50)
    canvas.pack(side=LEFT)

    greenCircle = canvas.create_oval(10, 10, 40, 40, fill="green")

    Label(FLegenda, text="Caminho resultante").pack(side=LEFT)

    canvas = Canvas(FLegenda, width=50, height=50)
    canvas.pack(side=LEFT, padx=10)

    purpleCircle = canvas.create_oval(10, 10, 40, 40, fill="purple")

    Label(FLegenda, text="Estado inicial").pack(side=LEFT)

    canvas = Canvas(FLegenda, width=50, height=50)
    canvas.pack(side=LEFT, padx=10)

    yellowCircle = canvas.create_oval(10, 10, 40, 40, fill="yellow")

    Label(FLegenda, text="Estado final").pack(side=LEFT)

    canvas = Canvas(FLegenda, width=50, height=50)
    canvas.pack(side=LEFT, padx=10)

    blueCircle = canvas.create_oval(10, 10, 40, 40, fill="blue")

    Label(FLegenda, text="Estado do grafo").pack(side=LEFT)

    FResultadoBuscaLargura = Frame(root, width=300, height=500, bd=1, relief=SUNKEN)
    FResultadoBuscaLargura.grid(row=0, column=1)

    Label(FResultadoBuscaLargura, text='Resultado Busca em Largura', justify=CENTER).grid(row=0, pady=10, sticky=W)

    i = 1
    for estado in caminho_busca_largura:
        Label(FResultadoBuscaLargura, text=estado, justify=CENTER).grid(row=i, pady=10)
        i += 1

    FResultadoBuscaAEstrela = Frame(root, width=300, height=500, bd=1, relief=SUNKEN)
    FResultadoBuscaAEstrela.grid(row=0, column=2, padx=15)

    Label(FResultadoBuscaAEstrela, text='Resultado Busca A*', justify=CENTER).grid(row=0, pady=10, sticky=W)

    if(problema == 1):
        botao = Button(root, text="Ir para o problema 2", command=prob_2, width=25, height=3)
        botao.grid(row=1, column=1, columnspan=2)
    else:
        if (problema == 2):
            botao = Button(root, text="Ir para o problema 1", command=prob_1, width=25, height=3)
            botao.grid(row=1, column=1, columnspan=2)

    i = 1
    for no in caminho_busca_a_estrela:
        Label(FResultadoBuscaAEstrela, text=no.getData(), justify=CENTER).grid(row=i, pady=10)
        i += 1

    root.mainloop()
Beispiel #9
0
class TicTacToe(object):
    def __init__(self):
        self.tree = None
        self.xplayer = False  #True if human player
        self.oplayer = False  #True if human player
        self.gameover = False
        self.xturn = True  #False if oturn
        self.template = StateTemplate([0, 1, 2, 3, 4, 5, 6, 7, 8])
        self.startState = [-1, -1, -1, -1, -1, -1, -1, -1, -1]

    def setupTree(self):
        '''Set up the full tree which shows all of the game states'''
        self.tree = Tree()
        self.tree.root.data = GameState(self.startState)
        node = self.tree.root
        while node is not None:
            if -1 in node.data.state:
                nodestate = deepcopy(node.data.state)
                index = nodestate.index(-1)
                node.data.state[index] = -2
                node = self.tree.addNode(node)
                #node = self.tree.findNode(nodeid)
                if len([k for k in nodestate if k == -1 or k == -2]) % 2:
                    #if len(node.id) % 2 == 0:
                    nodestate[index] = 'X'
                else:
                    nodestate[index] = 'O'

                for i in range(len(nodestate)):
                    if nodestate[i] == -2:
                        nodestate[i] = -1
                node.data = GameState(nodestate)
                #node.depth = len(node.id)-1 #depth is 0-based
            else:
                node = node.parent

        self.tree.prune(self.tree.root,
                        filters())  #prune the tree with the filters

    def checkEndGame(self):
        '''Return true if the current node has no children'''
        if len(self.tree.root.children) == 0:
            return True
        return False

    def humanFirstTurn(self):
        return int(raw_input("Enter an 'X' at location: (0-8) "))

    def humanTurn(self, symbol):
        '''Gets called when it is a humans turn.  symbol is either "X" or "O"'''
        i = int(raw_input("Enter an '" + symbol + "' at location: (0-8) "))
        data = self.tree.root.data.copy()
        if not data.setData(symbol, i):
            print("Cannot place '" + symbol + "' there.  Try again")
            self.humanTurn(symbol)
        else:
            node = self.tree.find(data)
            self.tree.setRoot(node.id)

    #def aiTurn(self, symbol, index):
    #    '''The ai at this point has chosen the best path as given by the index'''
    #    data = self.tree.root.data.copy() #get a copy of root GameState
    #    #data.setData(symbol, index)
    #    node = self.tree.find(data)
    #    self.tree.setRoot(node.id)

    def makeMoveAI(self, index):
        node = self.tree.root.children[index]
        self.tree.setRoot(node.id)
Beispiel #10
0
from tree import Tree

#Tree tests complete

t = Tree(3)
print(t)
a = t.addNode(0, 4)
b = t.addNode(0, 5)
c = t.addNode(a, 6)
d = t.addNode(a, 7)
e = t.addNode(d, 8)
print(t)
print("Path to e:")
p = t.pathToNode(e)
for i in p:
    print("\t", t.getData(i))
print("Path to c")
p = t.pathToNode(c)
for i in p:
    print("\t", t.getData(i))
print("Leaves:")

l = t.leaves()
for i in l:
    print(t.getData(i))
import numpy as np
from tree import Tree

if __name__ == '__main__':
    root = None

    np.random.seed(1234)
    for i in np.random.randint(0, 100, 10):
        print(i)

        if root is None:
            root = Tree(i)
        else:
            root.addNode(i)

    print("Printing the whole tree: ")
    root.printTree()

    print("Printing the tree with level")
    root.printTreeLevel(0)

    print("Printing the tree by level")
    root.printTreeByLevel(root)

    # single node tree:
    t = Tree(0)
    t.printTreeByLevel(t)
Beispiel #12
0
def inicializa_main_cinco_itens():
    ROOT = 0

    #Cachorro Fazendeiro Gato Queijo Rato:
    dicionario_heuristica_5_itens = {
        'C F G Q R|': 17,  #0
        'G Q|C F R': 8,  #1
        'C R|F G Q': 10,  #2
        'C Q|F G R': 17,  #3
        'F G Q|C R': 7,  #4
        'C F G Q|R': 18,  #5, 10
        'F G Q R|C': 12,  #6
        'C F R|G Q': 9,  #7
        'C F G R|Q': 19,  #8
        'C F Q R|G': 19,  #9, 11
        'Q|C F G R': 12,  #12, 15, 19, 28, 30, 34
        'G|C F Q R': 10,  #13, 16, 20, 25, 31
        '|C F G Q R': 0,  #14, 23
        'C|F G Q R': 13,  #17, 22, 26, 29, 32, 35
        'R|C F G Q': 13,  #18, 21, 24, 27, 33
        'F G R|C Q': 8  #36, 37, 38, 39, 40, 41, 42, 43....
    }

    #comecamos com id(atual) = id)pai = ROOT
    id = ROOT
    id_pai = ROOT

    #criando objeto arvore
    arvore = Tree()

    #adicionando no raiz
    arvore.addNode("C F G Q R|", 0)

    #vetor com as restricoes do problema
    restricoes = ["C,G", "G,R", "R,Q"]  #Vetor de restrições

    #vetor com os pesos referentes ao transporte de cada personagem
    pesos = {'F': 1, 'Q': 2, 'R': 3, 'G': 4, 'C': 5}

    #vetor de personagens
    global personagens
    personagens = ['F', 'C', 'G', 'R', 'Q']

    #capacidade do barco
    num_ocupantes_barco = 3

    #Gerando os conjuntos de restricoes
    global restr_sep
    restr_sep = [x.split(',') for x in restricoes]

    def valida_margem(margem):

        #Se o fazendeiro está na margem, nao tem problema
        if not ('F' in margem):
            combinacoes = list(itertools.combinations(margem, 2))

            for i in combinacoes:  #passando por todas as combinacoes, 2 a 2, dos elementos da margem
                for j in restr_sep:  #passando pelas restricoes
                    if (
                            set(i) == set(j)
                    ):  #comparando se as combinacoes batem com alguma das restricoes -> movimento invalido

                        return False
        return True

    #verifica se um no ja existe
    def ja_existe(msg, id_pai_atual):

        #separa a msg no |(que se refere ao rio). Assim, ficamos com os vetores referentes as margens esquerda e direita
        msg_arr = msg.split('|')
        msg_arr_esq = msg_arr[0].split(
        )  #elementos presentes na margem esquerda
        msg_arr_dir = msg_arr[1].split(
        )  #elementos presentes na margem direita

        #iterando sobre os nos presentes na arvore para verificar se existe um no que tenha como dado o mesmo valor presente em msg
        for i in arvore.getAllNodes():
            dado_no = i.getData().split(
                '|'
            )  #divide a mensagem em margem direita e esquerda por meio do sinal |
            dado_no_esq = dado_no[0].split(
            )  #elementos referentes a margem esquerda
            dado_no_dir = dado_no[1].split(
            )  #elementos referentes a margem esquerda
            if (
                (sorted(dado_no_esq) == sorted(msg_arr_esq))
                    or (sorted(dado_no_dir) == sorted(msg_arr_dir))
            ):  #trabalha com os elementos ordenados JA que, para o problema, A B seja igual a B A
                if (i.getId() <= ((id_pai_atual) - 1)) or (
                        i.getId() == 0
                ):  #testa se o id do no igual é o inicial ou se esta pelo menos 1 valor atras do atual
                    return True

        return False  #o no ainda nao existe, ou sua criacao nao resulta em um loop

    def calcula_custo(estado_pai, estado_filho):
        custo = 0
        quem_viajou = []
        margens_pai = estado_pai.split('|')
        margem_dir_pai = margens_pai[0].split()
        margem_esq_pai = margens_pai[1].split()
        margens_filho = estado_filho.split('|')
        margem_dir_filho = margens_filho[0].split()
        margem_esq_filho = margens_filho[1].split()
        if ('F' in margem_dir_pai):
            quem_viajou = list(
                set(margem_dir_pai) -
                set(margem_dir_pai).intersection(set(margem_dir_filho)))
        else:
            quem_viajou = list(
                set(margem_esq_pai) -
                set(margem_esq_pai).intersection(set(margem_esq_filho)))

        for ator in personagens:
            custo = custo + (ator in quem_viajou) * pesos[ator]

        return custo

    arestas = []

    custos_arestas = dict()
    custo_transicao = 0
    #enquanto o id do no atual nao ultrapassar o numero de nos da arvore(caso em que a geracao da arvore deve encerrar, pois o ultimo no foi atingido e nao gerou nenhum filho)
    while (id_pai < len(arvore.getAllNodes())):
        num_gerados = 0  #ainda nao gerou nenhum filho

        #recupera o no atual
        no = arvore.getNode(id_pai)
        #recupera a informacao presente no nó, referente à modelagem das margens esquerda e direita
        margens = no.getData().split('|')
        margem_esq = margens[0].split()
        margem_dir = margens[1].split()

        #se o fazendeiro esta na margem esquerda, o barco saira dela
        if ('F' in margem_esq):

            for k in range(num_ocupantes_barco):
                #gera as combinacoes, 1 a 1 e 2 a 2, dos elementos da margem esquerda para que ocupem o barco, nao excedendo sua capacidade
                combinacoes = list(itertools.combinations(margem_esq, k + 1))

                for barco in combinacoes:
                    #se o fazendeiro esta no barco, a configuracao do barco eh valida, ja que soh o fazendeiro pode guia-lo
                    if ('F' in barco):
                        #a margem esquerda apos a saida dos ocupantes do barco
                        margem_esq_resultante = list(
                            set(margem_esq) - set(barco))

                        #testa se a configuracao da margem, caso os ocupantes do barco zarpem, continua valida segundo as restricoes do problema
                        if (valida_margem(margem_esq_resultante)):

                            #constroi a mensagem referente ao estado do no, na forma: margem_esquerda|margem_direita
                            if (len(margem_esq_resultante)):
                                margem_esq_resultante = sorted(
                                    margem_esq_resultante)
                                msg = margem_esq_resultante[0]

                                for i in range(1, len(margem_esq_resultante)):
                                    msg = msg + ' ' + margem_esq_resultante[i]
                            else:
                                msg = ''

                            msg = msg + '|'
                            margem_dir_resultante = list(
                                set(margem_dir).union(set(barco))
                            )  #a margem direita apos a chegada dos ocupantes do barco

                            if (len(margem_dir_resultante)):
                                margem_dir_resultante = sorted(
                                    margem_dir_resultante)
                                msg = msg + margem_dir_resultante[0]

                                for i in range(1, len(margem_dir_resultante)):
                                    msg = msg + ' ' + margem_dir_resultante[i]
                            else:
                                msg = msg + ''

                            if (not ja_existe(
                                    msg, id_pai)):  #se o no ainda nao existe
                                id = id + 1
                                aresta = (arvore.getNode(id_pai).getData(),
                                          msg)
                                arestas.append(aresta)

                                custo_transicao = calcula_custo(
                                    arvore.getNode(id_pai).getData(), msg)
                                custos_arestas[aresta] = custo_transicao

                                arvore.addNode(msg, id, custo_transicao,
                                               id_pai)  #cria um novo no

        else:
            # se o fazendeiro esta na margem esquerda, o barco saira dela
            if ('F' in margem_dir):

                for k in range(num_ocupantes_barco):
                    # gera as combinacoes, 1 a 1 e 2 a 2, dos elementos da margem esquerda para que ocupem o barco, nao excedendo sua capacidade
                    combinacoes = list(
                        itertools.combinations(margem_dir, k + 1))

                    for barco in combinacoes:
                        # se o fazendeiro esta no barco, a configuracao do barco eh valida, ja que soh o fazendeiro pode guia-lo
                        if ('F' in barco):
                            # a margem direita apos a saida dos ocupantes do barco
                            margem_dir_resultante = list(
                                set(margem_dir) - set(barco))
                            # testa se a configuracao da margem, caso os ocupantes do barco zarpem, continua valida segundo as restricoes do problema
                            if (valida_margem(margem_dir_resultante)):
                                # a margem esquerda apos a chegada dos ocupantes do barco
                                margem_esq_resultante = list(
                                    set(margem_esq).union(set(barco)))

                                # constroi a mensagem referente ao estado do no, na forma: margem_esquerda|margem_direita
                                if (len(margem_esq_resultante)):
                                    margem_esq_resultante = sorted(
                                        margem_esq_resultante)
                                    msg = margem_esq_resultante[0]

                                    for i in range(1,
                                                   len(margem_esq_resultante)):
                                        msg = msg + ' ' + margem_esq_resultante[
                                            i]
                                else:
                                    msg = ''

                                msg = msg + '|'

                                if (len(margem_dir_resultante)):
                                    margem_dir_resultante = sorted(
                                        margem_dir_resultante)
                                    msg = msg + margem_dir_resultante[0]

                                    for i in range(1,
                                                   len(margem_dir_resultante)):
                                        msg = msg + ' ' + margem_dir_resultante[
                                            i]
                                else:
                                    msg = msg + ''

                                if (not ja_existe(
                                        msg,
                                        id_pai)):  #se o no ainda nao existe
                                    id = id + 1

                                    aresta = (arvore.getNode(id_pai).getData(),
                                              msg)
                                    arestas.append(aresta)

                                    custo_transicao = calcula_custo(
                                        arvore.getNode(id_pai).getData(), msg)
                                    custos_arestas[aresta] = custo_transicao

                                    arvore.addNode(msg, id, custo_transicao,
                                                   id_pai)  #cria um novo no

        #vai para o proximo no
        id_pai = id_pai + 1

    def converteDicToList(dicionario):
        num_nos = len(arvore.getAllNodes())
        lista = np.zeros(num_nos)
        for no in arvore.getAllNodes():
            for chave in dicionario:
                if chave == no.getData():
                    lista[no.getId()] = dicionario[chave]
                    break
        return lista

    for i in arvore.getAllNodes():
        print(i.getData())

    #exibe o grafo gerado
    '''f = open("grafo.txt","w+")
    print("\n\nPrintando grafo")
    for i in arvore.getAllNodes():
        f.write("-----\n")
        print("-----")
        f.write("[" + str(i.getId()) + "]\n")
        print("[", i.getId(),"]")
        if(not i.getParent() is None):
            f.write("Meu papai eh: " + str(i.getParent()) + "\n")
            print("Meu papai eh: " + str(i.getParent()))
        else:
            f.write("Nao tenho papai :(\n")
            print("Nao tenho papai :(")
        f.write("Minha informacao eh: " + str(i.getData()) + "\n")
        print("Minha informacao eh: ", i.getData())
        f.write("Meus filhinhos sao: " + str(i.getChildren()) + "\n")
        print("Meus filhinhos sao: ", i.getChildren())
        f.write("Os peso pra ir nos meus filhinhos são: " + str(i.getPesosParaOsFilhos()) + "\n\n")
        print("Os peso pra ir nos meus filhinhos são: ", i.getPesosParaOsFilhos())
    
    f.close()'''

    caminho_busca_largura = arvore.buscaLargura(arvore)

    vet_dist_estado_final = converteDicToList(dicionario_heuristica_5_itens)

    caminho_busca_a_estrela = arvore.busca_A_estrela(arvore,
                                                     vet_dist_estado_final)

    #Parte de exibição **********************************************

    nos = [v.getData() for v in arvore.getAllNodes()]

    g = nx.Graph()
    g.add_nodes_from(nos)
    g.add_edges_from(arestas)

    permutacoes_personagens = list(
        itertools.permutations(personagens, len(personagens)))
    nos_finais = []
    prim = True
    for i in permutacoes_personagens:
        msg = '|'
        for aux in i:
            if (prim):
                msg = msg + aux
                prim = False
            else:
                msg = msg + ' ' + aux
        prim = True
        nos_finais.append(msg)

    caminho_sem_no_final_e_sem_no_inicial = list(
        set(caminho_busca_largura) -
        set(caminho_busca_largura).intersection(set(nos_finais)) -
        set('A B F L|'))  #caminho sem o no final

    #pinta de verde o caminho encontrado pela busca em largura, de vermelho o no final e de azul os demais nos
    node_colors = [
        'purple' if n == 'C F G Q R|' else 'yellow' if n in nos_finais else
        'green' if n in caminho_sem_no_final_e_sem_no_inicial else 'blue'
        for n in g.nodes()
    ]

    #legenda
    '''green_patch = mpatches.Patch(color='green', label='Menor caminho')
    blue_patch = mpatches.Patch(color='blue', label='Nos nao visitados')
    plt.legend(handles=[green_patch,blue_patch])'''

    pos = nx.spring_layout(g)
    nx.draw(g,
            pos=pos,
            with_labels=True,
            node_size=700,
            node_color=node_colors)
    nx.draw_networkx_edge_labels(g, pos=pos, edge_labels=custos_arestas)

    plt.savefig('grafo2.png')

    plt.show(block=False)
    plt.close()

    #exibir em janela
    root = Tk()

    root.geometry("1000x620+0+0")
    root.title("IA - Travessia do rio")

    #Frame superior ********************************
    FImgs = Frame(root, width=700, height=500, bd=1, relief=SUNKEN)
    FImgs.grid(row=0, padx=10, pady=15)
    #imagem = cv2.imread("grafo1.png")
    #imagem = cv2.resize(imagem, None, fx=1.3, fy=1.3)
    #cv2.imwrite("grafo1.png", imagem)

    imgEntrada = PhotoImage(file="grafo2.png")
    labelImgEntrada = Label(FImgs, image=imgEntrada)
    labelImgEntrada.pack(side=LEFT, padx=15, pady=15)

    FLegenda = Frame(root, width=700, height=60, bd=1, relief=SUNKEN)
    FLegenda.grid(row=1)

    canvas = Canvas(FLegenda, width=50, height=50)
    canvas.pack(side=LEFT)

    greenCircle = canvas.create_oval(10, 10, 40, 40, fill="green")

    Label(FLegenda, text="Caminho resultante").pack(side=LEFT)

    canvas = Canvas(FLegenda, width=50, height=50)
    canvas.pack(side=LEFT, padx=10)

    purpleCircle = canvas.create_oval(10, 10, 40, 40, fill="purple")

    Label(FLegenda, text="Estado inicial").pack(side=LEFT)

    canvas = Canvas(FLegenda, width=50, height=50)
    canvas.pack(side=LEFT, padx=10)

    yellowCircle = canvas.create_oval(10, 10, 40, 40, fill="yellow")

    Label(FLegenda, text="Estado final").pack(side=LEFT)

    canvas = Canvas(FLegenda, width=50, height=50)
    canvas.pack(side=LEFT, padx=10)

    blueCircle = canvas.create_oval(10, 10, 40, 40, fill="blue")

    Label(FLegenda, text="Estado do grafo").pack(side=LEFT)

    FResultadoBuscaLargura = Frame(root,
                                   width=300,
                                   height=500,
                                   bd=1,
                                   relief=SUNKEN)
    FResultadoBuscaLargura.grid(row=0, column=1)

    Label(FResultadoBuscaLargura,
          text='Resultado Busca em Largura',
          justify=CENTER).grid(row=0, pady=10, sticky=W)

    i = 1
    for estado in caminho_busca_largura:
        Label(FResultadoBuscaLargura, text=estado,
              justify=CENTER).grid(row=i, pady=10)
        i += 1

    FResultadoBuscaAEstrela = Frame(root,
                                    width=300,
                                    height=500,
                                    bd=1,
                                    relief=SUNKEN)
    FResultadoBuscaAEstrela.grid(row=0, column=2, padx=15)

    Label(FResultadoBuscaAEstrela, text='Resultado Busca A*',
          justify=CENTER).grid(row=0, pady=10, sticky=W)

    i = 1
    for no in caminho_busca_a_estrela:
        Label(FResultadoBuscaAEstrela, text=no.getData(),
              justify=CENTER).grid(row=i, pady=10)
        i += 1

    root.mainloop()
Beispiel #13
0
      for index in indices:
         newstate = deepcopy(state)
         if (numFreeSpots % 2) == 0:
            newstate[index] = 'X'
         else:
            newstate[index] = 'O'
         newnode = tree.addNode(node, newstate)
         if newnode.depth < maxdepth:
            recurse(newnode)
           
   recurse(tree.root)

constructTree(4)
n = tree.walk(0, tree.root)
print(n)
"""
tree = Tree()
tree.addNode(tree.root, 9)
tree.addNode(tree.root, 10)
tree.addNode(tree.root, 11)
tree.addNode(tree.root.children[0], 4)
tree.addNode(tree.root.children[0], 6)
tree.addNode(tree.root.children[1], 8)
tree.addNode(tree.root.children[1], 1)
tree.addNode(tree.root.children[2], 7)
tree.addNode(tree.root.children[2], 90)
tree.addNode(tree.root.children[2], 66)
tree.addNode(tree.root.children[0].children[1], 78)
tree.addNode(tree.root.children[0].children[1], 99)

#tree.walk(0, tree.root)
Beispiel #14
0
    return True


#Testa se a configuracao da margem eh valida
#Para a margem esquerda        e     Para a margem direita
#if(testa_margem_valida(margens[0]) and testa_margem_valida(margens[1])):
#pode ir para o no

#comecamos com id(atual) = id)pai = ROOT
id = ROOT
id_pai = ROOT

#criando objeto arvore
arvore = Tree()
#inserindo o no raiz
arvore.addNode("L B A F|", 0)
'''arvore.addNode("L A|F B", 1)
arvore.addNode("L A F|B", 2)
arvore.addNode("L|F A B", 3)
arvore.addNode("L B F|A", 4)
arvore.addNode("B|F A L", 5)
arvore.addNode("F B|A L", 6)
arvore.addNode("|F B A L", 7)'''


#verifica se um no ja existe
def ja_existe(msg, id_pai_atual):

    #separa a msg no |(que se refere ao rio). Assim, ficamos com os vetores referentes as margens esquerda e direita
    msg_arr = msg.split('|')
    msg_arr_esq = msg_arr[0].split()  #elementos presentes na margem esquerda
Beispiel #15
0
from node import Node
from tree import Tree
from random import randrange

if __name__ == "__main__":

   arr = [randrange(1,100) for i in range(100)]
   #[print(i) for i in arr]
   tree = Tree(verbose=False)
   [tree.addNode(i) for i in arr]
   print("tree height: ", tree.getHeight())
   tree.display()
   tree.getInOrder()
   tree.getPreOrder()
   tree.findValue(10)
Beispiel #16
0
class Parser:
    def __init__(self, tokens, verbose, printmode, program):
        # Reverses tokens so I can use pop...cleans
        # up the code significantly
        self.__tokens = tokens[::-1]
        self.cst = Tree(printmode)
        self.verbose = verbose
        self.warnings = 0
        self.errors = 0
        self.program = program
        self.parse()

    # Check if the current token is an appropriate token for the scope
    def match(self, current_token, expected_tokens):
        retval = False
        if current_token in expected_tokens:
            retval = True
        return retval

    # This handles all error messages
    # as it was getting messy inside of function
    def error(self, token, expected):
        if self.errors is 0:
            Error('Parser', f'Expected [ {expected} ] found [ {token.value} ]',
                  token.line, token.position)
            self.errors += 1

    def exit(self):
        # Fail the Parser if there were any errors
        if self.errors > 0:
            print(colored(f'Parse Failed for Program {self.program}.\n',
                          'red'))
        else:
            print(
                colored(f'Parse Completed for Program {self.program}.\n',
                        'magenta',
                        attrs=['bold']))

    def logProduction(self, fn):
        if self.verbose and self.errors is 0:
            print(colored(f'PARSER ❯ {fn}', 'magenta'))

    ''' All productions to preform "derivations" '''

    def parse(self):
        print(
            colored(f'Parsing Program {self.program}',
                    'magenta',
                    attrs=['bold']))
        self.logProduction('parse()')
        self.cst.addNode('program', 'branch')

        # This is grabbing the first token but not removing it,
        # this is so if the first '{' is left out we can say what was
        # in its place
        current_token = self.__tokens[-1]

        # The most basic program is <block>$,
        # so check for block and then $
        if self.parseBlock():
            current_token = self.__tokens.pop()
            if self.match(current_token.kind, 'T_EOP'):
                self.cst.cutOffChildren()
                # print(current_token.line)
                self.cst.addNode(current_token.value,
                                 'leaf',
                                 line=current_token.line,
                                 pos=current_token.position)

                # We finished with 0 errors, exit safely now.
                self.exit()
            else:
                self.error(current_token, '$')
        else:
            self.error(current_token, '{')

    def parseBlock(self):
        # Look at the next token but dont remove until we are sure this is a print statement
        current_token = self.__tokens[-1]
        # Match open brace of block
        if self.match(current_token.kind, 'T_LEFT_BRACE'):
            # Actually remove it now
            current_token = self.__tokens.pop()
            # New Block
            self.logProduction('parseBlock()')
            self.cst.addNode('Block', 'branch')
            self.cst.addNode(current_token.value,
                             'leaf',
                             line=current_token.line,
                             pos=current_token.position)

            # Check the contents of the block
            if self.parseStatementList():
                # There better be a right brace to close this block
                current_token = self.__tokens.pop()
                if self.match(current_token.kind, 'T_RIGHT_BRACE'):
                    self.cst.addNode(current_token.value,
                                     'leaf',
                                     line=current_token.line,
                                     pos=current_token.position)
                else:
                    self.error(current_token, '}')
                    return False
            # This is a valid block
            return True
        else:
            # No block detected, move on
            return False

    def parseStatementList(self):
        self.logProduction('parseStatementList()')
        self.cst.addNode('StatementList', 'branch')

        if self.parseStatement():
            # Move up the tree
            self.cst.cutOffChildren()
            return self.parseStatementList()
        else:
            while self.cst.current_node.name is 'StatementList':
                self.cst.cutOffChildren()
            # Epsilon
            return True

    def parseStatement(self):
        self.logProduction('parseStatement()')
        self.cst.addNode('Statement', 'branch')

        # Check all possible statements
        if self.parseBlock() or self.parsePrintStatement() or (
                self.parseAssignmentStatement() or self.parseIfStatement()
                or self.parseVarDecl() or self.parseWhileStatement()):
            self.cst.cutOffChildren()
            return True
        else:
            # Remove the Statement branch node we didnt need it
            self.cst.delCurNode()
            return False

    # All possible statements
    def parsePrintStatement(self):
        # Look at the next token but dont remove until we are sure this is a print statement
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_PRINT'):
            # Actually remove it now
            current_token = self.__tokens.pop()

            # New Print Statement
            self.logProduction('parsePrintStatement()')
            self.cst.addNode('PrintStatement', 'branch')
            self.cst.addNode(current_token.value,
                             'leaf',
                             line=current_token.line,
                             pos=current_token.position)

            current_token = self.__tokens.pop()
            # The next token better be a open paren
            if self.match(current_token.kind, 'T_LEFT_PAREN'):
                self.cst.addNode(current_token.value,
                                 'leaf',
                                 line=current_token.line,
                                 pos=current_token.position)
                # Check for expr inside parens
                if self.parseExpr():
                    self.cst.cutOffChildren()
                    # Check for closing paren
                    current_token = self.__tokens.pop()
                    if self.match(current_token.kind, 'T_RIGHT_PAREN'):
                        self.cst.addNode(current_token.value,
                                         'leaf',
                                         line=current_token.line,
                                         pos=current_token.position)
                        return True
                    else:
                        self.error(current_token, ')')
                else:
                    self.error(current_token, 'ID, Int, String, or Boolean')
            else:
                self.error(current_token, '(')
        else:
            return False

    def parseAssignmentStatement(self):
        # Look at the next token but dont remove until we are sure this is a print statement
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_DIGIT') or self.match(
                current_token.kind, 'T_QUOTE'):
            self.error(current_token, 'ID')

        if self.match(current_token.kind, 'T_ID'):
            # We are sure this is a Assignment so pop the token
            self.logProduction('parseAssignmentStatement()')
            self.cst.addNode('AssignmentStatement', 'branch')
            self.parseId()

            current_token = self.__tokens.pop()
            # Now look for the actual '='
            if self.match(current_token.kind, 'T_ASSIGN_OP'):
                self.cst.addNode(current_token.value,
                                 'leaf',
                                 line=current_token.line,
                                 pos=current_token.position)

                # Finally validate what the ID is being assigned to
                if self.parseExpr():
                    self.cst.cutOffChildren()
                    return True
                else:
                    self.error(current_token, 'ID, Int, String, or Boolean')
            else:
                self.error(current_token, '=')  # T_ASSIGN_OP
        else:
            # Not an Assignment statement or not
            # valid(didnt start with a ID)
            return False

    def parseVarDecl(self):
        # Look at the next token but dont remove until we are sure this is a print statement
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_TYPE'):
            # We are sure this is a Assignment so pop the token
            current_token = self.__tokens.pop()
            self.logProduction('parseVarDecl()')
            self.cst.addNode('VarDecleration', 'branch')
            self.parseType(current_token)

            current_token = self.__tokens[-1]
            if self.parseId():
                return True
            else:
                self.error(current_token, 'ID')
        else:
            # Not a valid decleration
            return False

    def parseWhileStatement(self):
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_WHILE'):
            current_token = self.__tokens.pop()
            self.logProduction('parseWhileStatement()')
            self.cst.addNode('WhileStatement', 'branch')

            if self.parseBooleanExpr():
                self.cst.cutOffChildren()
                if self.parseBlock():
                    self.cst.cutOffChildren()

                    return True
                else:
                    self.error(self.__tokens[-1], '{')
                    return False
            else:
                self.error(self.__tokens[-1], 'BooleanExpr')
                return False
        else:
            return False

    def parseIfStatement(self):
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_IF'):
            current_token = self.__tokens.pop()
            self.logProduction('parseIfStatement()')
            self.cst.addNode('IfStatement', 'branch')
            if self.parseBooleanExpr():
                self.cst.cutOffChildren()

                if self.parseBlock():
                    self.cst.cutOffChildren()
                    return True
                else:
                    self.error(self.__tokens[-1], 'T_LEFT_BRACE')
                    return False
            else:
                self.error(self.__tokens[-1], 'BooleanExpr')
                return False
        else:
            return False

    # Expressions
    def parseExpr(self):
        self.logProduction('parseExpr()')
        self.cst.addNode('Expr', 'branch')

        # New Expr INT, BOOL or String
        if self.parseIntExpr() or self.parseBooleanExpr(
        ) or self.parseStringExpr():
            self.cst.cutOffChildren()
            return True

        elif self.parseId():
            # New Expr ID
            return True

        else:
            return False

    def parseIntExpr(self):
        # Look at the next token but dont remove until we are sure this is a print statement
        current_token = self.__tokens[-1]
        if self.match(current_token.kind, 'T_DIGIT'):
            self.logProduction('parseIntExpr()')
            self.cst.addNode('IntExpr', 'branch')
            if self.parseDigit():
                if self.parseIntOp():
                    if self.parseExpr():
                        self.cst.cutOffChildren()
                        return True
                    else:
                        self.error(current_token, 'Expr')
                else:
                    # this is valid => a = 3
                    return True
            else:
                self.error(current_token, 'digit(0-9)')

        else:
            # Its not a IntEpr
            return False

    def parseStringExpr(self):
        # Check for quote else dis aint a string
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_QUOTE'):
            current_token = self.__tokens.pop()
            self.logProduction('parseStringExpr()')
            self.cst.addNode('StringExpr', 'branch')
            self.cst.addNode(current_token.value,
                             'leaf',
                             line=current_token.line,
                             pos=current_token.position)
            self.cst.addNode('CharList', 'branch')

            if self.parseCharList():
                current_token = self.__tokens.pop()
                if self.match(current_token.kind, 'T_QUOTE'):
                    self.cst.addNode(current_token.value,
                                     'leaf',
                                     line=current_token.line,
                                     pos=current_token.position)
                    return True
                else:
                    self.error(self.__tokens[-1], 'T_Quote')
            else:
                self.error(self.__tokens[-1], 'Charlist')
        else:
            return False

    def parseBooleanExpr(self):
        # Check for BoolOp first
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_BOOLEAN'):
            self.logProduction('parseBooleanExpr()')
            self.cst.addNode('BooleanExpr', 'branch')
            self.parseBoolVal()
            return True
        elif self.match(current_token.kind, 'T_LEFT_PAREN'):
            current_token = self.__tokens.pop()
            self.logProduction('parseBooleanExpr()')
            self.cst.addNode('BooleanExpr', 'branch')
            self.cst.addNode(current_token.value,
                             'leaf',
                             line=current_token.line,
                             pos=current_token.position)

            if self.parseExpr():
                self.cst.cutOffChildren()

                if self.parseBoolOp():

                    if self.parseExpr():
                        self.cst.cutOffChildren()

                        current_token = self.__tokens.pop()
                        if self.match(current_token.kind, 'T_RIGHT_PAREN'):
                            self.cst.addNode(current_token.value,
                                             'leaf',
                                             line=current_token.line,
                                             pos=current_token.position)

                            return True
                        else:
                            self.error(current_token, ')')
                    else:
                        self.error(current_token, 'Expr')
                else:
                    self.error(current_token, '== or !=')
            else:
                self.error(current_token, 'Expr')
        else:
            # Not a valid BoolExpr
            return False

    def parseId(self):
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_ID'):
            current_token = self.__tokens.pop()
            # We dont need to check for char as
            # the lexer already took care of that
            self.logProduction('parseId()')
            self.cst.addNode('Id', 'branch')
            self.cst.addNode(current_token.value,
                             'leaf',
                             line=current_token.line,
                             pos=current_token.position)
            # go back to parent node
            self.cst.cutOffChildren()
            return True
        else:
            return False

    def parseCharList(self):
        self.logProduction('parseCharList()')

        if self.parseChar():
            return self.parseCharList()
        else:
            # move back up tree to get back to the branch node
            while self.cst.current_node.name is 'CharList':
                self.cst.cutOffChildren()
            return True

    def parseType(self, type_token):
        self.logProduction('parseType()')
        self.cst.addNode('Type', 'branch')
        self.cst.addNode(type_token.value,
                         'leaf',
                         line=type_token.line,
                         pos=type_token.position)
        # go back to parent node
        self.cst.cutOffChildren()

    def parseChar(self):
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_CHAR'):
            current_token = self.__tokens.pop()
            self.logProduction('parseChar()')
            self.cst.addNode('char', 'branch')
            self.cst.addNode(current_token.value,
                             'leaf',
                             line=current_token.line,
                             pos=current_token.position)
            # go back to parent node
            self.cst.cutOffChildren()
            return True
        else:
            # Not a char
            return False

    def parseDigit(self):
        self.logProduction('parseDigit()')
        current_token = self.__tokens.pop()
        if self.match(current_token.kind, 'T_DIGIT'):
            self.cst.addNode('digit', 'branch')
            self.cst.addNode(current_token.value,
                             'leaf',
                             line=current_token.line,
                             pos=current_token.position)
            # go back to parent node
            self.cst.cutOffChildren()
            return True
        else:
            return False

    def parseBoolOp(self):
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_BOOL_OP'):
            current_token = self.__tokens.pop()
            self.logProduction('parseBoolOp()')
            self.cst.addNode('BoolOp', 'branch')
            self.cst.addNode(current_token.value,
                             'leaf',
                             line=current_token.line,
                             pos=current_token.position)
            self.cst.cutOffChildren()
            return True
        else:
            return False

    def parseBoolVal(self):
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_BOOLEAN'):
            current_token = self.__tokens.pop()
            self.logProduction('parseBoolVal()')
            self.cst.addNode('BoolVal', 'branch')
            self.cst.addNode(current_token.value,
                             'leaf',
                             line=current_token.line,
                             pos=current_token.position)
            self.cst.cutOffChildren()
            return True
        else:
            return False

    def parseIntOp(self):
        current_token = self.__tokens[-1]

        if self.match(current_token.kind, 'T_ADDITION_OP'):
            current_token = self.__tokens.pop()
            self.cst.addNode('IntOP', 'branch')
            self.cst.addNode(current_token.value,
                             'leaf',
                             line=current_token.line,
                             pos=current_token.position)
            self.cst.cutOffChildren()
            return True
        else:
            return False