import numpy as np
import matplotlib.pyplot as plt
import random

import sys
sys.path.append('../')
from CreativeQiskit import random_grid

grid = random_grid(4,4)
grid_stats,grid_data = grid.get_samples(shots=1,noisy=0.2)
print(grid_data)

def string2array (string):
    grid_list = []
    for line in string.split('\n'):
        grid_list.append( [int(char) for char in line] )
    return np.array(grid_list)

print( string2array( '1000\n0010\n0000\n0000' ) )

def random_map (size=(4,4),cell=(4,4),seeds=1,sweeps=1,axes=['x','y'],frac=1,shots=1,noisy=False):
    cell_maps = [ [] for _ in range(shots) ]
    
    # loop over all cells, and 
    for Y in range(size[1]):
        cell_lines = [ [] for _ in range(shots) ]
        for X in range(size[0]):
            grid = random_grid(cell[0],cell[1])
            
            # place the seeds
            if seeds>=1:
                for seed in range(int(seeds)):
                    coords = (random.randrange(cell[0]),random.randrange(cell[1]))
                    grid.NOT( coords )
            elif random.random()<seeds:
                coords = (random.randrange(cell[0]),random.randrange(cell[1]))
                grid.NOT( coords )
            
            # sweep over qubits in cell and apply cnots to neighbours
            for sweep in range(sweeps):
                for y in range(cell[1]):
                    # in each sweep, half the qubits act as controls to the cnots, and half as targets
                    # they then alternate roles from one sweep to the next
                    # the dividing of qubits into two groups is on in 'checkerboard pattern
                    for x in range((y+sweep)%2,cell[0],2): # sweeps
                        for (xx,yy) in [(x+1,y),(x-1,y),(x,y+1),(x,y-1)]:
                            if (xx in range(cell[0])  and (yy in range(cell[1]))):
                                axis = random.choice(axes)
                                grid.CNOT((x,y),(xx,yy),frac=frac,axis=axis)
            
            # collect the results
            _,grid_data = grid.get_samples(shots=shots,noisy=noisy)
            for sample in range(shots):
                cell_lines[sample].append( string2array(grid_data[sample]) )
        for sample in range(shots):
            cell_maps[sample].append( cell_lines[sample] )
    
    # create the final grid
    maps = []
    for cell_map in cell_maps:
        maps.append( np.block(cell_map) )
    return maps

maps = random_map(size=(7,7),cell=(4,4),seeds=0,sweeps=1,frac=0.5,shots=5,noisy=0.015)

for map_sample in maps:
    plt.imshow(map_sample,cmap='gray')
    plt.axis('off')
    plt.show()

