def generate_children(p1, p2, x, y):
    child = []
    region = p2[x:y]

    #print "parent 1",p1
    #print "parent 2",p2
    #print x,y,region
    p = 0
    for i in region:
        i1 = t_rot.rotate(i[:], 1)
        i2 = t_rot.rotate(i[:], 2)
        if i in p1:
            p1.remove(i)
        elif i1 in p1:
            p1.remove(i1)
        elif i2 in p1:
            p1.remove(i2)

    for i in range(0, x):
        child.append(p1[i])
        p += 1

    for i in range(0, len(region)):
        child.append(region[i])

    if len(child) < len(p2):
        for i in range(p, len(p1)):
            child.append(p1[i])

    #print "child",child

    return child
Exemple #2
0
 def group_pieces(self):
     color = self.color[:]
     for i in color:
         if i.count('0') == 2:
             self.full_corner.append(i)
         elif i.count('0') == 1:
             self.full_sides.append(i)
         else:
             self.full_inner.append(i)
             self.full_inner.append(t_rot.rotate(i,1)) #considers all possible
             self.full_inner.append(t_rot.rotate(i,2)) #combination of inner pieces
Exemple #3
0
    def back_prop(self,i,parent,current_layer):

        r_corner = self.full_corner[:]
        r_inner  = self.full_inner[:]
        r_sides  = self.full_sides[:]

        temp_parent = parent

    ## The process continuosly finds the parent of the current node and compare the
    ## position of the each node, based on which they are deleted from the corners
    ## sidies and inner  list at the end of which we get the remaining corner, sides and
    ## inner at each node

        if len(parent.value) == 0:
            return r_corner,r_inner,r_sides
        for j in range(i,-1,-1):

                t1 = temp_parent.value
                if len(t1) == 0:
                    continue
                t2 = t_rot.rotate(t1,1)
                t3 = t_rot.rotate(t1,2)


                if t1.count('0')==2:
                    if t1 in r_corner:
                        r_corner.remove(t1)
                    elif t2 in r_corner:
                        r_corner.remove(t2)
                    elif t3 in r_corner:
                        r_corner.remove(t3)

                elif t1.count('0')==1:
                    if t1 in r_sides:
                        r_sides.remove(t1)
                    elif t2 in r_sides:
                        r_sides.remove(t2)
                    elif t3 in r_sides:
                        r_sides.remove(t3)

                else :
                    r_inner.remove(t1)
                    r_inner.remove(t2)
                    r_inner.remove(t3)

                temp_parent = temp_parent.parent

        return r_corner,r_inner,r_sides
Exemple #4
0
    def populate_children(self,parent,i,root,count):
    ## Each node is compared with the respective postion in the layer
        layers = self.layers
        current_layer = int(math.sqrt(i))

        r_corner,r_inner,r_sides = self.back_prop(i,parent,current_layer)

    ## For the first corner
        if i == 0:
            while (len(r_corner)>2):
                j = r_corner[0]
                child = Node()
                child.parent     = parent

                if j[0] != '0':
                    child.value = t_rot.rotate(j[:],2)
                elif j[1] != '0':
                    child.value = t_rot.rotate(j[:],1)
                else:
                    child.value  = j[:]

                r_corner.remove(j)
                parent.children+=(child,)

    #For the leftmost corner
        elif i == (layers-1)*(layers-1):
            while(len(r_corner)>0):
                j = r_corner[0]

                pos_m = 0
                found = 0
    #Ensuring that there is atleast one inner pieces that can be placed after this corner
                for m in r_inner:
                    if  m[1] == j[0] or \
                        m[1] == j[1] or \
                        m[1] == j[2] :
                        #found = 1
                        for n in r_sides:
                            if m[0] == n [0] or \
                                m[0] == n [1] or \
                                m[0] == n [2] :
                                found =1
                                break
                    if found == 1:
                        break

                if found!=1:
                    r_corner.remove(j)
                    continue


                child = Node()
                child.parent     = parent

                if j[0] != '0':
                    child.value = t_rot.rotate(j[:],1)
                elif j[2] != '0':
                    child.value = t_rot.rotate(j[:],2)
                else:
                    child.value  = j[:]

                r_corner.remove(j)

                ok = 1
                for ch in parent.children:
                    if ch.value == child.value:
                        del child
                        ok = 0
                        break
                if ok  == 1:
                    parent.children+=(child,)


    ## The final piece
        elif i == (layers)*(layers)-1:   #laste piece

            while(len(r_corner)>0):
                j = r_corner[0]

                child = Node()
                child.parent     = parent

                if j[2] != '0':
                    child.value = t_rot.rotate(j[:],1)
                elif j[0] != '0':
                    child.value = t_rot.rotate(j[:],2)
                else:
                    child.value  = j[:]

                r_corner.remove(j)


                ok = 1
                for ch in parent.children:
                    if ch.value == child.value:
                        del child
                        ok = 0
                        break
                if ok  == 1:
                    parent.children+=(child,)

    ## left side pieces
        elif i == current_layer*current_layer:
            while (len(r_sides)>0):

                j = r_sides[0]
                child = Node()
                child.parent     = parent

                if j[2] == '0':
                    child.value = t_rot.rotate(j[:],1)
                elif j[1] == '0':
                    child.value = t_rot.rotate(j[:],2)
                else:
                    child.value  = j[:]

                r_sides.remove(j)

                ok = 1
                for ch in parent.children:
                    if ch.value == child.value:
                        del child
                        ok = 0
                        break
                if ok  == 1:
                    parent.children+=(child,)


    ## The final layer
        elif current_layer == layers-1:

            ## if the finat layer is evem the bottom pieces are at the even posistions and
            ## vice versa
            #if i  == 43:
            #    print r_sides
            #    print r_inner
            #    print r_corner
            #    print parent.value,parent.parent.value
            if (current_layer%2==0 and i%2==0) or \
                (current_layer%2!=0 and i%2!=0):
                while (len(r_sides))>0:
                    j =r_sides[0]

                    if j[1] == '0':
                        value = t_rot.rotate(j[:],1)
                    elif j[0] == '0':
                        value = t_rot.rotate(j[:],2)
                    else:
                        value  = j[:]

                    if value[0]!=parent.value[0]:
                        r_sides.remove(j)
                        continue

                    child = Node()
                    child.parent     = parent

                    child.value = value
                    r_sides.remove(j)


                    ok = 1
                    for ch in parent.children:
                        if ch.value == child.value:
                            del child
                            ok = 0
                            break

                    if ok  == 1:
                        parent.children+=(child,)


            else:   # for inner in the final layer

                t_puzzle = []
                p_puzzle = []
                temp_parent = parent
                for _ in range(0,i):
                    t_puzzle.append(temp_parent.value)
                    temp_parent = temp_parent.parent

                p_puzzle = [t_puzzle[j] for j in range(len(t_puzzle)-1,-1,-1)]

                while (len(r_inner))>0:
                    j = r_inner[0]

                    if j[1]!=parent.value[1]:
                        r_inner.remove(j)
                        continue
                    elif(j[2]!=p_puzzle[len(p_puzzle)-current_layer*2][2]):
                        r_inner.remove(j)
                        continue

                    child = Node()
                    child.value      = j[:]
                    child.parent     = parent
                    r_inner.remove(j)


                    ok = 1
                    for ch in parent.children:
                        if ch.value == child.value:
                            del child
                            ok = 0
                            break

                    if ok  == 1:
                        parent.children+=(child,)



    ## For right edges of the puzzle
        elif i == current_layer*current_layer+2*current_layer:
            while (len(r_sides))>0:
                j = r_sides[0]
                value = j
                if j[0] == '0':
                    value = t_rot.rotate(j[:],1)
                elif j[2] == '0':
                    value = t_rot.rotate(j[:],2)
                else:
                    value  = j[:]

                if value[0]!=parent.value[0]:
                    r_sides.remove(j)
                    continue

                child = Node()
                child.parent     = parent
                child.value = value
                r_sides.remove(j)


                ok = 1
                for ch in parent.children:
                    if ch.value == child.value:
                        del child
                        ok = 0
                        break

                if ok  == 1:
                    parent.children+=(child,)


    ## For other inner pieces
        else:
            t_puzzle = []
            p_puzzle = []
            temp_parent = parent
            for _ in range(0,i):
                t_puzzle.append(temp_parent.value)
                temp_parent = temp_parent.parent

            p_puzzle = [t_puzzle[j] for j in range(len(t_puzzle)-1,-1,-1)]
            pos_j = 0

    ## Here the each selected piece are compared with the remaining pieces to ensure that there is
    ## atleast one piece to place after the current piece
            while len(r_inner)>0:
                j = r_inner[0]

                if (current_layer%2==0):
                    if i%2 != 0:    ### inverted layers at even postion when the current layer is odd and vice versa
                        if (j[1]!=parent.value[1]): ## comapring the first edge witht the piece on the left
                            r_inner.remove(j)
                            continue
                        elif(j[2]!=p_puzzle[len(p_puzzle)-current_layer*2][2]): ## comparing the bottom edge with the piece on the top
                            r_inner.remove(j)
                            continue


                            pos_n = 0
                            found = 0
                            for n in r_inner:
                                pos_n+=1
                                if pos_n==pos_j:
                                    continue
                                else:
                                    if n[0] == j [0]:
                                        found = 1
                                        break
                            if found != 1:
                                r_inner.remove(j)
                                continue

                            temp = []
                            if i == current_layer*current_layer+2*current_layer - 1:
                                found = 0

                                for s  in r_sides:
                                    if s[0]=='0':
                                        temp = t_rot.rotate(s[:],1)
                                    elif s[2]=='0':
                                        temp = t_rot.rotate(s[:],2)
                                    else:
                                        temp = s[:]
                                    if j[0] == temp[0]:
                                        found = 1
                                        break

                            if found != 1:
                                r_inner.remove(j)
                                continue
                    else: ### other inner pieces
                        if (j[0]!=parent.value[0]):
                            r_inner.remove(j)
                            continue


                        found = 0
                        pos_m=0
                        for m in r_inner:
                            pos_m += 1
                            if pos_m==pos_j:
                                continue
                            else:
                                if (m[1]==j[1]):
                                    pos_n = 0
                                    for n in r_inner:
                                        pos_n+=1
                                        if pos_n==pos_m or pos_n==pos_j:
                                            continue
                                        else:
                                            if n[2] == j [2]:
                                                found = 1
                                                break
                            if found == 1:
                                break
                        if found != 1:
                            r_inner.remove(j)
                            continue


                elif (current_layer%2!=0):
                        if i%2 == 0:
                            if (j[1]!=parent.value[1]):
                                r_inner.remove(j)
                                continue
                            elif(j[2]!=p_puzzle[len(p_puzzle)-current_layer*2][2]):
                                r_inner.remove(j)
                                continue


                                pos_n = 0
                                found = 0
                                for n in r_inner:
                                    pos_n+=1
                                    if pos_n==pos_j:
                                        continue
                                    else:
                                        if n[0] == j [0]:
                                            found = 1
                                            break
                                if found != 1:
                                    r_inner.remove(j)
                                    continue

                                temp = []
                                if i == current_layer*current_layer+2*current_layer - 1:
                                    found = 0

                                    for s  in r_sides:
                                        if s[0]=='0':
                                            temp = t_rot.rotate(s[:],1)
                                        elif s[2]=='0':
                                            temp = t_rot.rotate(s[:],2)
                                        else:
                                            temp = s[:]
                                        if j[0] == temp[0]:
                                            found = 1
                                            break

                                if found != 1:
                                    r_inner.remove(j)
                                    continue
                        else:
                            if (j[0]!=parent.value[0]):
                                r_inner.remove(j)
                                continue


                            found = 0
                            pos_m=0
                            for m in r_inner:
                                pos_m += 1
                                if pos_m==pos_j:
                                    continue
                                else:
                                    if (m[1]==j[1]):
                                        pos_n = 0
                                        for n in r_inner:
                                            pos_n+=1
                                            if pos_n==pos_m or pos_n==pos_j:
                                                continue
                                            else:
                                                if n[2] == j [2]:
                                                    found = 1
                                                    break
                                if found == 1:
                                    break
                            if found != 1:
                                r_inner.remove(j)
                                continue


                child = Node()
                child.value      = j[:]
                child.parent     = parent
                r_inner.remove(j)

                ok = 1
                for ch in parent.children:
                    if ch.value == child.value:
                        del child
                        ok = 0
                        break
                if ok  == 1:
                    parent.children+=(child,)


    ## Only doing the simulation when the parent has children
        #if i == 43:
        #    print "numbe of new nodes",len(parent.children),parent.value,len(parent.parent.children),parent.parent.parent.value,parent.parent.parent.parent.value
        #    for ch in parent.parent.children:
        #        print "kutikal",ch.value

        if len(parent.children)==0:
            parent.score = -99999
            count += 1

        if i == layers * layers:
            #o = random.randint(0,len(parent.children)-1)
            t_puzzle = []
            p_puzzle = []
            temp_parent = parent

            for _ in range(0,i):
                t_puzzle.append(temp_parent.value)
                temp_parent = temp_parent.parent

    ## Generating the puzzle at current postion
            p_puzzle = [t_puzzle[j] for j in range(len(t_puzzle)-1,-1,-1)]
            if p_puzzle[i-1][1] != '0':
                p_puzzle[i-1] = t_rot.rotate(p_puzzle[i-1][:],2)

            elif p_puzzle[i-1][2] != '0':
                p_puzzle[i-1] = t_rot.rotate(p_puzzle[i-1][:],1)
            print p_puzzle
            print count
            self.solutions.append(p_puzzle)
            self.count.append(count)
            count = 0

            temp = parent.parent
            temp.children.remove(parent)
            del parent
            i -= 1
            parent = temp
            while (len(parent.children)==0):
                temp = parent.parent
                temp.children.remove(parent)
                del parent
                i -= 1
                parent = temp
            if parent.parent == 'NaN':
                exit()
            #pd.draw_puzzle(p_puzzle,layers)
            #exit()
    ## calculating the scores

    ## when there is no children return with high penalty and delete the parent
        return parent,i,count
def swap_mutation(corner, sides, inner, color, layers):
    n_corner = []
    n_sides = []
    n_inner = []

    for i in range(0, len(corner)):

        if (random.uniform(0, 1) > 0.8):
            x = i
            y = random.randint(0, len(corner) - 1)
            while (x == y):
                y = random.randint(0, len(corner) - 1)

            t = corner[x]
            corner[x] = corner[y]
            corner[y] = t

        if (random.uniform(0, 1) > 0.8):
            if (random.uniform(0, 1) > 0.5):
                corner[i] = t_rot.rotate(corner[i], (1))
            else:
                corner[i] = t_rot.rotate(corner[i], (2))

    for i in range(0, len(corner)):
        place = corner[i]

        if i == 0:
            if place[0] != '0':
                place = t_rot.rotate(place, 2)
            elif place[1] != '0':
                place = t_rot.rotate(place, 1)

        elif i == 1:
            if place[2] != '0':
                place = t_rot.rotate(place, 2)
            elif place[0] != '0':
                place = t_rot.rotate(place, 1)

        else:
            if place[1] != '0':
                place = t_rot.rotate(place, 2)
            elif place[2] != '0':
                place = t_rot.rotate(place, 1)

        n_corner.append(place)

    for i in range(0, len(sides)):

        if (random.uniform(0, 1) > 0.6):

            x = i
            y = random.randint(0, len(sides) - 1)
            while (x == y):
                y = random.randint(0, len(sides) - 1)

            t = sides[x]
            sides[x] = sides[y]
            sides[y] = t

        if (random.uniform(0, 1) > 0.6):
            if (random.uniform(0, 1) > 0.5):
                sides[i] = t_rot.rotate(sides[i], (1))
            else:
                sides[i] = t_rot.rotate(sides[i], (2))

    for i in range(0, len(sides)):

        place = sides[i]

        s1 = (layers - 2)
        s2 = s1 * 2
        s3 = s2 * 2

        if i < (s1):
            if place[1] == '0':
                place = t_rot.rotate(place, 2)
            elif place[2] == '0':
                place = t_rot.rotate(place, 1)

        elif i < s2:
            if place[0] == '0':
                place = t_rot.rotate(place, 2)
            elif place[1] == '0':
                place = t_rot.rotate(place, 1)

        else:
            if place[2] == '0':
                place = t_rot.rotate(place, 2)
            elif place[0] == '0':
                place = t_rot.rotate(place, 1)

        n_sides.append(place)

    for i in range(0, len(inner)):

        if (random.uniform(0, 1) > 0.4):

            x = i
            y = random.randint(0, len(inner) - 1)
            while (x == y):
                y = random.randint(0, len(inner) - 1)

            t = inner[x]
            inner[x] = inner[y]
            inner[y] = t

        if (random.uniform(0, 1) > 0.4):
            if (random.uniform(0, 1) > 0.5):
                inner[i] = t_rot.rotate(inner[i], (1))
            else:
                inner[i] = t_rot.rotate(inner[i], (2))

    for i in range(0, len(inner)):
        place = inner[i]

        n_inner.append(place)

    return n_corner, n_sides, n_inner
    def populate_children(self, parent, i, root):
        ## Each node is compared with the respective postion in the layer
        layers = self.layers
        current_layer = int(math.sqrt(i))

        r_corner, r_inner, r_sides = self.back_prop(i, parent, current_layer)

        ## For the first corner
        if i == 0:
            while (len(r_corner) > 2):
                j = r_corner[0]
                child = Node()
                child.parent = parent

                if j[0] != '0':
                    child.value = t_rot.rotate(j[:], 2)
                elif j[1] != '0':
                    child.value = t_rot.rotate(j[:], 1)
                else:
                    child.value = j[:]

                r_corner.remove(j)
                parent.children += (child, )

    #For the leftmost corner
        elif i == (layers - 1) * (layers - 1):
            while (len(r_corner) > 0):
                j = r_corner[0]

                pos_m = 0
                found = 0
                #Ensuring that there is atleast one inner pieces that can be placed after this corner
                for m in r_inner:
                    if  m[1] == j[0] or \
                        m[1] == j[1] or \
                        m[1] == j[2] :
                        #found = 1
                        for n in r_sides:
                            if m[0] == n [0] or \
                                m[0] == n [1] or \
                                m[0] == n [2] :
                                found = 1
                                break
                    if found == 1:
                        break

                if found != 1:
                    r_corner.remove(j)
                    continue

                child = Node()
                child.parent = parent

                if j[0] != '0':
                    child.value = t_rot.rotate(j[:], 1)
                elif j[2] != '0':
                    child.value = t_rot.rotate(j[:], 2)
                else:
                    child.value = j[:]

                r_corner.remove(j)
                parent.children += (child, )

    ## The final piece
        elif i == (layers) * (layers) - 1:  #laste piece

            while (len(r_corner) > 0):
                j = r_corner[0]

                child = Node()
                child.parent = parent

                if j[2] != '0':
                    child.value = t_rot.rotate(j[:], 1)
                elif j[0] != '0':
                    child.value = t_rot.rotate(j[:], 2)
                else:
                    child.value = j[:]

                r_corner.remove(j)
                parent.children += (child, )
    ## left side pieces
        elif i == current_layer * current_layer:
            while (len(r_sides) > 0):

                j = r_sides[0]
                child = Node()
                child.parent = parent

                if j[2] == '0':
                    child.value = t_rot.rotate(j[:], 1)
                elif j[1] == '0':
                    child.value = t_rot.rotate(j[:], 2)
                else:
                    child.value = j[:]

                r_sides.remove(j)
                parent.children += (child, )

    ## The final layer
        elif current_layer == layers - 1:

            ## if the finat layer is evem the bottom pieces are at the even posistions and
            ## vice versa
            if (current_layer%2==0 and i%2==0) or \
                (current_layer%2!=0 and i%2!=0):

                while (len(r_sides)) > 0:
                    j = r_sides[0]

                    if j[1] == '0':
                        value = t_rot.rotate(j[:], 1)
                    elif j[0] == '0':
                        value = t_rot.rotate(j[:], 2)
                    else:
                        value = j[:]

                    if value[0] != parent.value[0]:
                        r_sides.remove(j)
                        continue

                    child = Node()
                    child.parent = parent

                    child.value = value
                    r_sides.remove(j)
                    parent.children += (child, )

            else:  # for inner in the final layer

                t_puzzle = []
                p_puzzle = []
                temp_parent = parent
                for _ in range(0, i):
                    t_puzzle.append(temp_parent.value)
                    temp_parent = temp_parent.parent

                p_puzzle = [
                    t_puzzle[j] for j in range(len(t_puzzle) - 1, -1, -1)
                ]

                while (len(r_inner)) > 0:
                    j = r_inner[0]

                    if j[1] != parent.value[1]:
                        r_inner.remove(j)
                        continue
                    elif (j[2] !=
                          p_puzzle[len(p_puzzle) - current_layer * 2][2]):
                        r_inner.remove(j)
                        continue

                    child = Node()
                    child.value = j[:]
                    child.parent = parent
                    r_inner.remove(j)
                    parent.children += (child, )

    ## For right edges of the puzzle
        elif i == current_layer * current_layer + 2 * current_layer:
            while (len(r_sides)) > 0:
                j = r_sides[0]
                value = j
                if j[0] == '0':
                    value = t_rot.rotate(j[:], 1)
                elif j[2] == '0':
                    value = t_rot.rotate(j[:], 2)
                else:
                    value = j[:]

                if value[0] != parent.value[0]:
                    r_sides.remove(j)
                    continue

                child = Node()
                child.parent = parent
                child.value = value
                r_sides.remove(j)
                parent.children += (child, )

    ## For other inner pieces
        else:
            t_puzzle = []
            p_puzzle = []
            temp_parent = parent
            for _ in range(0, i):
                t_puzzle.append(temp_parent.value)
                temp_parent = temp_parent.parent

            p_puzzle = [t_puzzle[j] for j in range(len(t_puzzle) - 1, -1, -1)]
            pos_j = 0

            ## Here the each selected piece are compared with the remaining pieces to ensure that there is
            ## atleast one piece to place after the current piece
            while len(r_inner) > 0:
                j = r_inner[0]

                if (current_layer % 2 == 0):
                    if i % 2 != 0:  ### inverted layers at even postion when the current layer is odd and vice versa
                        if (
                                j[1] != parent.value[1]
                        ):  ## comapring the first edge witht the piece on the left
                            r_inner.remove(j)
                            continue
                        elif (
                                j[2] !=
                                p_puzzle[len(p_puzzle) - current_layer * 2][2]
                        ):  ## comparing the bottom edge with the piece on the top
                            r_inner.remove(j)
                            continue

                            pos_n = 0
                            found = 0
                            for n in r_inner:
                                pos_n += 1
                                if pos_n == pos_j:
                                    continue
                                else:
                                    if n[0] == j[0]:
                                        found = 1
                                        break
                            if found != 1:
                                r_inner.remove(j)
                                continue

                            temp = []
                            if i == current_layer * current_layer + 2 * current_layer - 1:
                                found = 0

                                for s in r_sides:
                                    if s[0] == '0':
                                        temp = t_rot.rotate(s[:], 1)
                                    elif s[2] == '0':
                                        temp = t_rot.rotate(s[:], 2)
                                    else:
                                        temp = s[:]
                                    if j[0] == temp[0]:
                                        found = 1
                                        break

                            if found != 1:
                                r_inner.remove(j)
                                continue
                    else:  ### other inner pieces
                        if (j[0] != parent.value[0]):
                            r_inner.remove(j)
                            continue

                        found = 0
                        pos_m = 0
                        for m in r_inner:
                            pos_m += 1
                            if pos_m == pos_j:
                                continue
                            else:
                                if (m[1] == j[1]):
                                    pos_n = 0
                                    for n in r_inner:
                                        pos_n += 1
                                        if pos_n == pos_m or pos_n == pos_j:
                                            continue
                                        else:
                                            if n[2] == j[2]:
                                                found = 1
                                                break
                            if found == 1:
                                break
                        if found != 1:
                            r_inner.remove(j)
                            continue

                elif (current_layer % 2 != 0):
                    if i % 2 == 0:
                        if (j[1] != parent.value[1]):
                            r_inner.remove(j)
                            continue
                        elif (j[2] !=
                              p_puzzle[len(p_puzzle) - current_layer * 2][2]):
                            r_inner.remove(j)
                            continue

                            pos_n = 0
                            found = 0
                            for n in r_inner:
                                pos_n += 1
                                if pos_n == pos_j:
                                    continue
                                else:
                                    if n[0] == j[0]:
                                        found = 1
                                        break
                            if found != 1:
                                r_inner.remove(j)
                                continue

                            temp = []
                            if i == current_layer * current_layer + 2 * current_layer - 1:
                                found = 0

                                for s in r_sides:
                                    if s[0] == '0':
                                        temp = t_rot.rotate(s[:], 1)
                                    elif s[2] == '0':
                                        temp = t_rot.rotate(s[:], 2)
                                    else:
                                        temp = s[:]
                                    if j[0] == temp[0]:
                                        found = 1
                                        break

                            if found != 1:
                                r_inner.remove(j)
                                continue
                    else:
                        if (j[0] != parent.value[0]):
                            r_inner.remove(j)
                            continue

                        found = 0
                        pos_m = 0
                        for m in r_inner:
                            pos_m += 1
                            if pos_m == pos_j:
                                continue
                            else:
                                if (m[1] == j[1]):
                                    pos_n = 0
                                    for n in r_inner:
                                        pos_n += 1
                                        if pos_n == pos_m or pos_n == pos_j:
                                            continue
                                        else:
                                            if n[2] == j[2]:
                                                found = 1
                                                break
                            if found == 1:
                                break
                        if found != 1:
                            r_inner.remove(j)
                            continue

                child = Node()
                child.value = j[:]
                child.parent = parent
                r_inner.remove(j)
                parent.children += (child, )

    ## Only doing the simulation when the parent has children
        if len(parent.children) > 0:

            o = random.randint(0, len(parent.children) - 1)
            t_puzzle = []
            p_puzzle = []
            temp_parent = parent.children[o]
            for _ in range(0, i + 1):
                t_puzzle.append(temp_parent.value)
                temp_parent = temp_parent.parent

    ## Generating the puzzle at current postion
            p_puzzle = [t_puzzle[j] for j in range(len(t_puzzle) - 1, -1, -1)]

            ## calculating the scores
            v_score = 0
            v_score, flag = self.simulation(parent.children[o], i, p_puzzle)
            parent.children[o].n += 1

            v_score /= parent.n
            parent.children[o].score   = v_score + \
                                        math.sqrt(2)*math.sqrt(2*math.log(root.n)/parent.n)
            c = parent.children[o]
            k = i + 1

        else:

            ## when there is no children return with high penalty and delete the parent
            parent.n += 1

            v_score = -9999
            parent.score   = v_score + \
                                        math.sqrt(2)*math.sqrt(2*math.log(root.n)/parent.n)
            c = parent
            k = i
            return parent

    ## update the scores and n till the root nodes
        for _ in range(0, k):
            c = c.parent
            c.n += 1

            if c.parent != 'NaN':
                if len(parent.children) > 0:
                    c.score += parent.children[0].score
                else:
                    c.score += parent.score

        return parent
def puzzle_generate(corners, sides, inner, layers, c_puzzle):
    puzzle = [0 for i in range(0, layers * layers)]
    l = 0
    l1 = len(c_puzzle)
    #print l1,c_puzzle
    #print "inside"
    for j in range(0, layers):
        for k in range(0, 2 * j + 1):
            if l < l1:
                puzzle[l] = c_puzzle[l]
                l += 1
                continue
            if j == 0:
                puzzle[l] = random.choice(corners)
                corners.remove(puzzle[l])
                l += 1

            elif (j == layers - 1):
                if (k == 0):
                    found = 0
                    c = 0
                    puzzle[l] = corners[c]

                    while (found < 1 and c < len(corners)):
                        temp = puzzle[l][:]
                        if puzzle[l][0] != '0':
                            temp = t_rot.rotate(puzzle[l], 1)

                        elif puzzle[l][2] != '0':
                            temp = t_rot.rotate(puzzle[l], 2)

                        for n in inner:
                            if n[1] != temp[1] or n[2] != puzzle[(j - 1) *
                                                                 (j - 1)][2]:
                                continue
                            for s in sides:
                                temp_s = s[:]

                                if temp_s[0] == '0':
                                    temp_s = t_rot.rotate(temp_s, 2)
                                elif temp_s[1] == '0':
                                    temp_s = t_rot.rotate(temp_s, 1)

                                if n[0] == temp_s[0]:
                                    found = 1
                                    break
                            if found == 1:
                                break

                        if found == 1:
                            break
                        c += 1

                    if found != 1:
                        puzzle[l] = random.choice(corners)

                    corners.remove(puzzle[l])
                    if puzzle[l][0] != '0':
                        puzzle[l] = t_rot.rotate(puzzle[l], 1)
                    elif puzzle[l][2] != '0':
                        puzzle[l] = t_rot.rotate(puzzle[l], 2)
                    l += 1

                elif (k == j * 2):
                    puzzle[l] = random.choice(corners)
                    corners.remove(puzzle[l])
                    if puzzle[l][2] != '0':
                        puzzle[l] = t_rot.rotate(puzzle[l], 1)
                    elif puzzle[l][1] != '0':
                        puzzle[l] = t_rot.rotate(puzzle[l], 2)

                    l += 1

                else:
                    if (k % 2 != 0):
                        found = 0
                        #print "here"
                        #    print len(puzzle) , i
                        #print l,i
                        #print "inner",inner
                        for inr in inner:
                            if inr[1] == puzzle[l-1][1] and \
                                inr[2] == puzzle[l-int(math.sqrt(l))*2][2]:
                                found = 1
                                puzzle[l] = inr
                                break
                        #print "found",found
                        #print found,inr,puzzle[k-1][1],l-int(math.sqrt(l))*2,l
                        if found != 1:
                            puzzle[l] = random.choice(inner)

                        inner.remove(puzzle[l])
                        inner.remove(t_rot.rotate(puzzle[l], 1))
                        inner.remove(t_rot.rotate(puzzle[l], 2))
                        l += 1

                    else:
                        found = 0
                        for sds in sides:
                            if sds[0] == puzzle[l-1][0] or \
                            sds[0] == puzzle[l-1][1] or \
                            sds[0] == puzzle[l-1][2]:
                                found = 1
                                puzzle[l] = sds
                                break
                        #print "found sides",found
                        if found != 1:
                            puzzle[l] = random.choice(sides)

                        sides.remove(puzzle[l])
                        if puzzle[l][0] == '0':
                            puzzle[l] = t_rot.rotate(puzzle[l], 2)
                        elif puzzle[l][1] == '0':
                            puzzle[l] = t_rot.rotate(puzzle[l], 1)
                        l += 1
            else:
                if (k == 0):

                    found = 0
                    for s in sides:
                        temp_s = s[:]

                        if s[2] == '0':
                            temp_s = t_rot.rotate(s, 1)

                        elif s[1] == '0':
                            temp_s = t_rot.rotate(s, 2)

                            for inr in inner:
                                if inr[1] == temp_s[1] and inr[2] == puzzle[
                                    (j - 1) * (j - 1)][2]:
                                    found = 1
                                    break

                            if found == 1:
                                puzzle[l] = temp_s
                                sides.remove(s)
                                break

                    if found != 1:
                        puzzle[l] = random.choice(sides)
                        sides.remove(puzzle[l])

                    if puzzle[l][1] == '0':
                        puzzle[l] = t_rot.rotate(puzzle[l], 2)
                    elif puzzle[l][2] == '0':
                        puzzle[l] = t_rot.rotate(puzzle[l], 1)
                    l += 1

                elif (k == j * 2):
                    found = 0
                    for sds in sides:
                        t_sds = sds
                        if sds[0] == '0':
                            sds = t_rot.rotate(sds, 1)

                        elif sds[2] == '0':
                            sds = t_rot.rotate(sds, 2)

                        if sds[0] == puzzle[l - 1][0]:
                            found = 1
                            puzzle[l] = sds
                            sides.remove(t_sds)
                            break
                    #print "found sides",found
                    if found != 1:
                        puzzle[l] = random.choice(sides)
                        sides.remove(puzzle[l])

                    if puzzle[l][2] == '0':
                        puzzle[l] = t_rot.rotate(puzzle[l], 2)
                    elif puzzle[l][0] == '0':
                        puzzle[l] = t_rot.rotate(puzzle[l], 1)
                    l += 1
                else:
                    found = 0
                    pos_inr = -1

                    for inr in inner:
                        pos_inr += 1
                        if (inr[1] == puzzle[l-1][1] and \
                        inr[2] == puzzle[l-int(math.sqrt(l))*2][2] and \
                        k%2!=0):

                            pos_t_inr = -1
                            for t_inr in inner:
                                pos_t_inr += 1

                                if pos_t_inr == pos_inr:
                                    continue
                                else:
                                    if t_inr[0] == inr[0]:
                                        found = 1
                                        break

                            if found == 1:
                                puzzle[l] = inr
                                break

                        elif (inr[0] == puzzle[l - 1][0] and k % 2 == 0):

                            pos_t_inr = -1
                            for t_inr in inner:
                                pos_t_inr += 1

                                if pos_t_inr == pos_inr:
                                    continue
                                else:
                                    if t_inr[1] == inr[1]:
                                        found = 1
                                        break

                            if found == 1:
                                puzzle[l] = inr
                                break

                    if found != 1:
                        puzzle[l] = random.choice(inner)

                    inner.remove(puzzle[l])
                    inner.remove(t_rot.rotate(puzzle[l], 1))
                    inner.remove(t_rot.rotate(puzzle[l], 2))
                    l += 1
    return puzzle
def init_individuals():
    postion = []

    pos = 0
    c_0_2 = []
    c_0_1 = []
    c_0_0 = []
    for i in color:
        if i.count('0') == 2:
            c_0_2.append(i)
        elif i.count('0') == 1:
            c_0_1.append(i)
        else:
            c_0_0.append(i)

    corners = []
    sides   = []
    inner   = []
#filling corners
    for i in range(0,3):
        place = random.choice(c_0_2)
        c_0_2.remove(place)

        if i == 0:
            if place[0] != '0':
                place = t_rot.rotate(place,2)
            elif place[1] != '0':
                place = t_rot.rotate(place,1)

        elif i == 1:
            if place[2] != '0':
                place = t_rot.rotate(place,2)
            elif place[0] != '0':
                place = t_rot.rotate(place,1)

        else:
            if place[1] != '0':
                place = t_rot.rotate(place,2)
            elif place[2] != '0':
                place = t_rot.rotate(place,1)
        corners.append(place)


    s1=(layers-2)
    s2=s1*2
    s3=s2*2

    for i in range(0,len(c_0_1)):
        place = random.choice(c_0_1)
        c_0_1.remove(place)

        if i<(s1):
            if place[1] == '0':
                place = t_rot.rotate(place,2)
            elif place[2] == '0':
                place = t_rot.rotate(place,1)

        elif i<s2:
            if place[0] == '0':
                place = t_rot.rotate(place,2)
            elif place[1] == '0':
                place = t_rot.rotate(place,1)


        else:
            if place[2] == '0':
                place = t_rot.rotate(place,2)
            elif place[0] == '0':
                place = t_rot.rotate(place,1)

        sides.append(place)

    for i in range(0,len(c_0_0)):
        place = random.choice(c_0_0)
        c_0_0.remove(place)
        if(random.uniform(0,1)>0.6):
            if(random.uniform(0,1)>0.5):
                place=t_rot.rotate(place,1)
            else:
                place=t_rot.rotate(place,2)
        inner.append(place)

    return corners,sides,inner