def test2():
    import pypng.png as png

    n, m = 30, 40

    maze = createRandomMaze(n, m)
    mazeSimple = simplifyMaze(maze)

    s = createPNGfromMazeAndPaths(maze)
    printMazePNG(s, "png2.png")
    s = createPNGfromMazeAndPaths(mazeSimple)
    printMazePNG(s, "png2simple.png")
def test6():
    n, m = 300, 400

    if True:
        mazePerfect = createRandomMaze(n, m)
        maze = deleteWalls(mazePerfect, 0.07)
        mazeSimple, per = simplifyMaze(maze)
        from src.createMazes import createRandomWeight

        mazeWeight, mask = createRandomWeight(n, m, 70)

        # Saving
        import pickle

        o = open("test.bin", "wb")
        pickle.dump(maze, o)
        pickle.dump(mazeWeight, o)

    # outdated
    # else:
    ## Loading
    # import pickle
    # o = open('test.bin', 'rb')
    ##mazePerfect = pickle.load(o)
    # maze = pickle.load(o)
    # mazeWeight = pickle.load(o)

    print per  # total unrearcheable cells

    # finding shortest path
    from src.shortestPath import shortestPath

    sol = shortestPath(maze, mazeWeight)
    s = createPNGfromMazeAndPaths(mazeSimple, [sol])
    printMazePNG(s, "test5.png")

    toPNG = [[int(255 * (1 - j)) for j in i] for i in mask]
    import pypng.png as png

    writterPNG = png.Writer(len(toPNG[0]), len(toPNG), greyscale=True, bitdepth=8)
    f = open("testing.png", "wb")
    writterPNG.write(f, toPNG)
    f.close()
def main(folder):
  initialPop      = getParameter(['initialPop',      'I'], None)
  n, m            = getParameter(['dim']                 , (60, 70)  , eval)
  wallsToDel      = getParameter(['wallsToDel',      'd'], 0.10      , float)
  mutPercent      = getParameter(['mutationPercent', 'm'], 0.10      , float)
  totalPopulation = getParameter(['totalPopulation', 't'], 50        , int)
  totalIterations = getParameter(['totalIterations', 'i'], 200       , int)
  badIndividuals  = getParameter(['badIndividuals',  'b'], 10        , int)
  chooseFunction  = getParameter(['chooseFunction',  'c'], lambda x:x, eval)
  sizeInitial     = getParameter(['sizeInitial',     's'], 15        , int)
  multiplesExec   = getParameter(['multiplesExec',   'M'], 1         , int)
  manyFinalPop    = getParameter(['manyFinalPop',    'P'], 1         , int)
  toBool = lambda s: False if s in ["False", "false", "f", "F", "0"] else bool(s)
  initPopInvulnrb = getParameter(['initPopInvulnrb', 'V'], True      , toBool)
  #chooseFunction = lambda x: (0.6/0.5)*x if x<0.6 else (x-1)*((1-0.5)/(1-0.6)) + 1

  # If the folder doesn't exisit
  if not os.path.exists(folder):
      os.makedirs(folder)
      os.makedirs( path.join(folder, folderInitialPop) )
      os.makedirs( path.join(folder, folderFinalPop) )
      open( path.join(folder, folderInitialPop, 'counter'),'wb').write('0')
      open( path.join(folder, folderFinalPop, 'counters'),'wb').write('[]')

  ######################## Maze #######################
  if os.path.exists( path.join(folder, mazeFile) ):
      o = open( path.join(folder, mazeFile), 'rb')
      n = pickle.load(o)
      m = pickle.load(o)
      wallsToDel = pickle.load(o)
      maze = pickle.load(o)
      mazeSimple = pickle.load(o)
      mazeWeight = pickle.load(o)
      inaccesibleCellsPercent = pickle.load(o)
      shortPath = savePaths.loadPath(o)
      o.close()
  else:
      maze = deleteWalls(createRandomMaze(n, m), wallsToDel)
      mazeSimple, inaccesibleCellsPercent = simplifyMaze(maze)

      mazeWeight, _ = createRandomWeight(n, m)
      shortPath = shortestPath(mazeSimple, mazeWeight)

      o = open( path.join(folder, mazeFile), 'wb')
      pickle.dump(n, o)
      pickle.dump(m, o)
      pickle.dump(wallsToDel, o)
      pickle.dump(maze, o)
      pickle.dump(mazeSimple, o)
      pickle.dump(mazeWeight, o)
      pickle.dump(inaccesibleCellsPercent, o)
      savePaths.savePath(shortPath, o)
      o.close()

  print "Starting ..."
  print "Maze dimensions:", (n, m)
  print "Walls Deleted (percentage):", wallsToDel
  print "Inaccesible cells (percentage):", inaccesibleCellsPercent
  fitnessShortPath = fitness(mazeWeight, shortPath)
  print "Shortest Path: ", fitnessShortPath
  print
  print "=== Global variables setted to: ==="
  print "Mutation (percentage):", mutPercent
  print "Total iterations:", totalIterations
  print "Number of bad individuals:", badIndividuals
  print "Initial Population Invulnerable:", initPopInvulnrb
  print "Total population:", totalPopulation
  print

  print "== Statistics =="
  print

  nameStatisticFinal = path.join(folder, "final.csv")
  if not os.path.exists(nameStatisticFinal):
      statistics_final = open(nameStatisticFinal, 'a')
      statistics_final.write("Name; ")
      statistics_final.write("% mutation; ")
      statistics_final.write("total iterations; ")
      statistics_final.write("bad Individuals; ")
      statistics_final.write("invulnerable initPop; ")
      statistics_final.write("Len Initial Population; ")
      statistics_final.write("Total Population; ")
      statistics_final.write("Best Init Path; ")
      statistics_final.write("Worst Init Path; ")
      statistics_final.write("Can be made from Init paths?; ")
      statistics_final.write("clones; ")
      statistics_final.write("mutations; ")
      statistics_final.write("Best final Path; ")
      statistics_final.write("Worst final Path; ")
      statistics_final.write("Ratio best-shortest paths; ")
      statistics_final.write("improvement from initial; ")
      statistics_final.write("Can me made from Final paths?\n")
  else:
      statistics_final = open(nameStatisticFinal, 'a')

  statistics_initial = open( path.join(folder, "initial.csv"), 'a' )

  for i in range(multiplesExec):
    ######################## initial Population #######################
    if initialPop == None:
        new = True
        o_counter = open( path.join(folder, folderInitialPop, 'counter'),'rb')
        counter = int(o_counter.read())
        o_counter.close()

        initialPopulation = [findPath(mazeSimple) for i in range(sizeInitial)]
        initialPopulation.sort(key=lambda i: fitness(mazeWeight, i))
        nameInitialPop = str(counter).zfill(5)

        o = open( path.join(folder, folderInitialPop, nameInitialPop), 'wb')
        savePaths.saveListOfPaths(initialPopulation, o)
        o.close()

        o_counter = open( path.join(folder, folderInitialPop, 'counter'),'wb')
        o_counter.write(str(counter+1))
        o_counter.close()
    else:
        new = False
        counter = int(initialPop, 10)
        nameInitialPop = str(counter).zfill(5)
        o = open( path.join(folder, folderInitialPop, nameInitialPop), 'rb')
        initialPopulation = savePaths.loadListOfPaths(o)
        o.close()
        nameNext = str(counter+1).zfill(5)
        if os.path.exists( path.join(folder, folderInitialPop, nameNext)):
            initialPop = nameNext
        else:
            initialPop = None

    ##################################################################

    ############################ statistics ############################
    def printSave(t, d, others="", final=False):
        print t, d, others
        if new:
            statistics_initial.write(str(d) + ("\n" if final else "; "))

    bestInitPop = fitness(mazeWeight, initialPopulation[0])
    ratioBestShortPathInitPop = float(bestInitPop)/fitnessShortPath
    worstInitPop = fitness(mazeWeight, initialPopulation[-1])
    canInit = canFindSolutionFromPaths(n, m, shortPath, initialPopulation)
    printSave("Initial Population",           nameInitialPop)
    printSave("  initial size population:",   len(initialPopulation))
    printSave("  best path: ",                bestInitPop)
    printSave("  worst path:",                worstInitPop)
    printSave("  ratio best-shortest paths:", ratioBestShortPathInitPop)
    printSave("  Is posible find the Shortest-Path from paths:", canInit, final=True)
    print
    ####################################################################

    ####################### final population #######################
    o_counters = open( path.join(folder, folderFinalPop, 'counters'),'rb')
    counters = eval(o_counters.read())
    o_counters.close()
    if len(counters) <= counter:
        counters.extend( [-1]*(counter-len(counters)+1) )

    def printSave(t, d, others="", final=False):
        print t, d, others
        statistics_final.write(str(d) + ("\n" if final else "; "))

    for i in range(manyFinalPop):
        finalPopulation, num_clones, num_mutated = evolutionAlgo(
                mazeSimple, mazeWeight, initialPopulation , mutPercent,
                totalPopulation, totalIterations , badIndividuals,
                initPopInvulnrb, chooseFunction)

        counters[counter] += 1

        ############################ statistics ############################
        nameFinalPop = str(counter).zfill(5)+'-'+str(counters[counter]).zfill(5)
        best = fitness(mazeWeight, finalPopulation[0])
        ratioBestShortPath = float(best)/fitnessShortPath
        can = canFindSolutionFromPaths(n, m, shortPath, finalPopulation)

        printSave("  Final Population #", nameFinalPop)
        statistics_final.write(str(mutPercent)+"; ")
        statistics_final.write(str(totalIterations)+"; ")
        statistics_final.write(str(badIndividuals)+"; ")
        statistics_final.write(str(initPopInvulnrb)+"; ")
        statistics_final.write(str(len(initialPopulation))+"; ")
        statistics_final.write(str(totalPopulation)+"; ")
        statistics_final.write(str(bestInitPop)+"; ")
        statistics_final.write(str(worstInitPop)+"; ")
        statistics_final.write(str(canInit)+"; ")
        printSave("    num of clones in the execution:", num_clones,
                  str(100*float(num_clones)/totalIterations)+"%")
        printSave("    num of mutations in the execution:", num_mutated,
                  str(100*float(num_mutated)/totalIterations)+"%")
        printSave("    best path: ", best)
        printSave("    worst path:", fitness(mazeWeight, finalPopulation[-1]))
        printSave("    ratio best-shortest paths:", ratioBestShortPath)
        printSave("    improvement:", ratioBestShortPathInitPop -
                                      ratioBestShortPath)
        printSave("    Is posible find the Shortest-Path from paths:", can, final=True)
        print

        o = open( path.join(folder, folderFinalPop, nameFinalPop), 'wb')
        savePaths.saveListOfPaths(finalPopulation, o)
        pickle.dump(num_clones, o)
        pickle.dump(num_mutated, o)
        o.close()
        ####################################################################

    # increment counters
    o_counters = open( path.join(folder, folderFinalPop, 'counters'),'wb')
    o_counters.write(str(counters))
    o_counters.close()

  statistics_initial.close()
  statistics_final.close()
def test3():
    n, m = 100, 120

    if True:
        mazePerfect = createRandomMaze(n, m)
        maze = deleteWalls(mazePerfect, 0.10)

        # maze without dead-ends
        mazeSimple = simplifyMaze(maze)

        from random import random

        mazeWeight = [[random() for j in range(m)] for i in range(n)]

        sol = findPath(maze)
        sol2 = findPath(maze)

        # Saving
        import pickle

        o = open("test.bin", "wb")
        # pickle.dump(mazePerfect, o)
        pickle.dump(maze, o)
        pickle.dump(mazeSimple, o)
        pickle.dump(mazeWeight, o)
        # this is a simple save, without using the optimized procedure
        # savePath from src.savePaths
        pickle.dump(sol, o)
        pickle.dump(sol2, o)

    else:
        # Loading
        import pickle

        o = open("test.bin", "rb")
        # mazePerfect = pickle.load(o)
        maze = pickle.load(o)
        mazeSimple = pickle.load(o)
        mazeWeight = pickle.load(o)
        sol = pickle.load(o)
        sol2 = pickle.load(o)

    # saving
    # maze clean
    # s = createPNGfromMazeAndPaths(mazePerfect)
    # printMazePNG(s, "test3-Perfect.png")

    # s = createPNGfromMazeAndPaths(maze)
    # printMazePNG(s, "test3.png")

    # s = createPNGfromMazeAndPaths(maze, [sol, sol2])
    # printMazePNG(s, "test3-paths.png")

    # s = createPNGfromMazeAndPaths(mazeSimple)
    # printMazePNG(s, "test3-simple.png")

    # solSon,k,l = crossingPaths(n, m, sol, sol2)
    # s = createPNGfromMazeAndPaths(maze, [solSon])
    # printMazePNG(s, "test3-son.png")

    # mutating
    solMut, p1, p2 = mutatePath(maze, sol)
    s = createPNGfromMazeAndPaths(maze, [sol, solMut], [[p1, p1], [p2, p2]])
    printMazePNG(s, "test3-original-and-mutated.png")
def testPNG():
    # la siguiente matriz representa los caminos, no las paredes del laberinto
    example1 = [
        u"┐    ┌──┐┌───┐     ┌──┐           ┌┐ ┌┐         ┌────┐ ┌─────┐  ",
        u"└┐   └─┐└┘   │   ┌┐│  └┐┌─┐      ┌┘└┐││ ┌┐      │┌─┐ └┐└─┐  ┌┘  ",
        u"┌┘    ┌┘     └───┘││   └┘ │      │  ││└┐│└─────┐└┘ │ ┌┘ ┌┘┌─┘   ",
        u"└─┐┌──┘┌─┐     ┌──┘│    ╶┬┘      │┌─┘└┐││ ┌──┐ │ ┌─┘┌┘  │ └┐ ┌─┐",
        u"  └┘  ┌┘ └──┐  └┐ ┌┘     │ ┌──┐ ┌┘└──┐│└┘┌┘┌─┘ └┐│  └─┐┌┘┌┐│ │ │",
        u" ┌────┘┌┐   │ ┌─┘ │     ┌┘ │┌┐│ └──┐ └┘┌┐│┌┘┌┐╷ └┘    └┘ │└┘ │ │",
        u" │   ┌─┘└─┐ │ └─┐ │┌┐   └┐ └┘││ ┌┐ │┌┐ │└┘│ │├┘      ┌──┐│┌┐ │ │",
        u"┌┘┌──┘┌┐ ┌┘┌┘  ┌┘ └┘│┌┐ ┌┘┌──┘│┌┘│ └┘│ │  │┌┘│       │┌┐│└┘│ │ │",
        u"└┐│  ┌┘└┐└┐│ ┌┐└─┐  └┘│ │ │ ┌┐└┘ └─┐ └─┘  └┘ └┐ ┌──┐ ││└┘  └─┘ │",
        u" ││  └─┐│┌┘└─┘└──┘   ┌┘ │ │ │└┐    └┐┌──┐    ┌┘┌┘ ┌┘┌┘│┌┐ ┌─┐  │",
        u" └┘┌───┘└┘┌──┐┌┐┌────┘  │ │ └┐│    ┌┘│  │    │ └┐ │ │┌┘│└┐│ └──┘",
        u"   └┐┌──┐┌┘┌─┘│││       │ │ ┌┘└┐┌┐ └┐│┌┐│    │  │ └─┘│┌┘ │└┐    ",
        u"┌┐  ││  ││ └──┘││ ┌─┐   │ │ │  └┘│  │└┘││  ┌─┘  │┌─┐┌┘│  └┐│    ",
        u"│└──┘└┐ ││┌┐   └┤ │┌┘   │┌┴─┘  ┌┐│  │┌─┘└──┘ ╷  │└┐│└─┘   └┘┌──┐",
        u"│ ┌───┘ │└┘│    │ │└┐┌┬─┼┘  ┌─┐││└──┘│      ╶┼╴ ├┐│└┐    ┌┐┌┘┌─┘",
        u"└─┘     └──┘    └─┘ └┘└─┴───┘╶┼┘└────┘       ╵  ╵└┘ └────┘└┘ └──",
    ]
    example2 = [u"┬─┬─┬───┬───┐", u"│ │ │┌┐ │┌┐ │", u"└┬┘ └┘│ └┘└─┘", u" └────┴──────"]
    example3 = [u"─┬──┬───┐", u"┌┴┐ │┌┐ │", u"│ │ └┘└─┘", u"├─┼─┐    ", u"│ ├─┘  ╶┐", u"└┬┘     │", u" └──────┴"]

    example = example1

    def pathToWalls(s):
        if s == u" ":
            return 15  # LEFT & UP & RIGHT & DOWN
        elif s == u"╴":
            return 14  #        UP & RIGHT & DOWN
        elif s == u"╵":
            return 13  # LEFT      & RIGHT & DOWN
        elif s == u"╶":
            return 11  # LEFT & UP         & DOWN
        elif s == u"╷":
            return 7  # LEFT & UP & RIGHT
        elif s == u"─":
            return 10  #        UP &         DOWN
        elif s == u"│":
            return 5  # LEFT      & RIGHT
        elif s == u"┌":
            return 3  # LEFT & UP
        elif s == u"┐":
            return 6  #        UP & RIGHT
        elif s == u"┘":
            return 12  #             RIGHT & DOWN
        elif s == u"└":
            return 9  # LEFT &            & DOWN
        elif s == u"├":
            return 1  # LEFT
        elif s == u"┬":
            return 2  #        UP
        elif s == u"┤":
            return 4  #             RIGHT
        elif s == u"┴":
            return 8  #                     DOWN
        elif s == u"┼":
            return 0  # NOTHING

    exampleWalls = map(lambda x: map(pathToWalls, x), example)
    simple = simplifyMaze(exampleWalls)
    # print '\n'.join([' '.join([str(c).rjust(2) for c in x]) for x in simple])

    import pypng.png as png

    s = createPNGfromMazeAndPaths(exampleWalls)
    printMazePNG(s, "png1.png")
    s = createPNGfromMazeAndPaths(simple)
    printMazePNG(s, "png1simple.png")