#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 30 22:04:48 2020

@author: baptistelafoux
"""

import domino 
import numpy as np
import numpy.lib.arraysetops as aso 

def spawn_block(x, y):

    if np.random.rand() > 0.5: 
        d1 = domino.domino(np.array([x,     y]), np.array([x + 1,     y]), np.array([0,-1]))
        d2 = domino.domino(np.array([x, y + 1]), np.array([x + 1, y + 1]), np.array([0, 1]))
    else: 
        d1 = domino.domino(np.array([x,     y]), np.array([x,     y + 1]), np.array([-1,0]))
        d2 = domino.domino(np.array([x + 1, y]), np.array([x + 1, y + 1]), np.array([ 1,0]))
    
    return [d1, d2]

def aztec_grid(order, only_new_blocks = True):

    grid_X, grid_Y = np.meshgrid(np.arange(2 * order) - (2 * order - 1)/2 , np.arange(2 * order) - (2 * order - 1)/2)
    
    center_pts = np.array([grid_X.flatten(), grid_Y.flatten()]).T
    center_pts = center_pts[np.lexsort((center_pts[:,1], center_pts[:,0]))]
    
    X = center_pts[:,0]
    Y = center_pts[:,1]
    if only_new_blocks: idx = (np.abs(X) + np.abs(Y) <= order) & (np.abs(X) + np.abs(Y) > order - 1)
    else: idx = np.abs(X) + np.abs(Y) <= order
    
    return X[idx], Y[idx]

def add_to_grid(tiles, grid): 
    
    for tile in tiles:
        grid[tile.pt1[0], tile.pt1[1]] = tile 
        grid[tile.pt2[0], tile.pt2[1]] = tile 
    
    return grid

def generate_good_block(grid):
    
    center_pts = np.array([*grid])
    center_pts = center_pts[np.lexsort((center_pts[:, 1], center_pts[:, 0]))]
    
    X = center_pts[:, 0]
    Y = center_pts[:, 1]
    
    for (x,y) in zip(X,Y):
        
        try:
            if ~grid[x, y]:
                idx = [(x,y), (x+1,y), (x,y+1), (x+1,y+1)]
                try:
                    should_create_a_block = ~np.sum(np.array(list(map(grid.get, idx))), dtype = bool)
                    if should_create_a_block:
                        grid = add_to_grid(spawn_block(x, y), grid)
                except: pass
        except: pass
                    
    
    return grid
    

def enlarge_grid_deprec(grid, order):
    center_pts = [*grid]
    
    X_aztec, Y_aztec = aztec_grid(order)
    center_pts_aztec = [tuple([x,y]) for (x,y) in zip(X_aztec, Y_aztec)]
    
    diff_array = set(center_pts_aztec) - set(center_pts)

    if order > 1:
        for x, y in list(diff_array):
            grid[x, y] = False 
    else:
        for (x,y) in zip(X_aztec, Y_aztec): 
            grid[x, y] = False 


    return grid

def enlarge_grid(grid, order):
    
    X_aztec, Y_aztec = aztec_grid(order, True)
    
    for (x,y) in zip(X_aztec, Y_aztec): 
        grid[x, y] = False 

    return grid

def move_tiles(grid, curr_order): 
    temp_grid = {}
    for coord in grid:
        if grid[coord] != False:
            
            x1, y1 = grid[coord].pt1
            x2, y2 = grid[coord].pt2
            
            grid[coord].move()
            temp_grid = add_to_grid([grid[coord]], temp_grid)
            
            grid[x1, y1] = False
            grid[x2, y2] = False
        
    for coord in temp_grid:
        grid[coord] = temp_grid[coord]
                        
        
    return grid

def destroy_bad_blocks(grid):
    center_pts = np.array([*grid])
    
    X = center_pts[:, 0]
    Y = center_pts[:, 1]
    
    for (x,y) in zip(X,Y):
        try:
            next_x, next_y = np.array([x, y]) + grid[x, y].v
        
            if (grid[next_x, next_y] != False): 
                
                if all(grid[next_x, next_y].v == - grid[x, y].v): 
                
                    grid[x,      y     ] = False 
                    grid[next_x, next_y] = False
        except: pass
                
    return grid
    
    


[((48, 17, 48, 34), 'numpy.array', 'np.array', ({(48, 26, 48, 33): '[*grid]'}, {}), '([*grid])', True, 'import numpy as np\n'), ((118, 17, 118, 34), 'numpy.array', 'np.array', ({(118, 26, 118, 33): '[*grid]'}, {}), '([*grid])', True, 'import numpy as np\n'), ((15, 7, 15, 23), 'numpy.random.rand', 'np.random.rand', ({}, {}), '()', True, 'import numpy as np\n'), ((16, 27, 16, 47), 'numpy.array', 'np.array', ({(16, 36, 16, 46): '[x, y]'}, {}), '([x, y])', True, 'import numpy as np\n'), ((16, 49, 16, 73), 'numpy.array', 'np.array', ({(16, 58, 16, 72): '[x + 1, y]'}, {}), '([x + 1, y])', True, 'import numpy as np\n'), ((16, 75, 16, 91), 'numpy.array', 'np.array', ({(16, 84, 16, 90): '[0, -1]'}, {}), '([0, -1])', True, 'import numpy as np\n'), ((17, 27, 17, 47), 'numpy.array', 'np.array', ({(17, 36, 17, 46): '[x, y + 1]'}, {}), '([x, y + 1])', True, 'import numpy as np\n'), ((17, 49, 17, 73), 'numpy.array', 'np.array', ({(17, 58, 17, 72): '[x + 1, y + 1]'}, {}), '([x + 1, y + 1])', True, 'import numpy as np\n'), ((17, 75, 17, 91), 'numpy.array', 'np.array', ({(17, 84, 17, 90): '[0, 1]'}, {}), '([0, 1])', True, 'import numpy as np\n'), ((19, 27, 19, 47), 'numpy.array', 'np.array', ({(19, 36, 19, 46): '[x, y]'}, {}), '([x, y])', True, 'import numpy as np\n'), ((19, 49, 19, 73), 'numpy.array', 'np.array', ({(19, 58, 19, 72): '[x, y + 1]'}, {}), '([x, y + 1])', True, 'import numpy as np\n'), ((19, 75, 19, 91), 'numpy.array', 'np.array', ({(19, 84, 19, 90): '[-1, 0]'}, {}), '([-1, 0])', True, 'import numpy as np\n'), ((20, 27, 20, 47), 'numpy.array', 'np.array', ({(20, 36, 20, 46): '[x + 1, y]'}, {}), '([x + 1, y])', True, 'import numpy as np\n'), ((20, 49, 20, 73), 'numpy.array', 'np.array', ({(20, 58, 20, 72): '[x + 1, y + 1]'}, {}), '([x + 1, y + 1])', True, 'import numpy as np\n'), ((20, 75, 20, 91), 'numpy.array', 'np.array', ({(20, 84, 20, 90): '[1, 0]'}, {}), '([1, 0])', True, 'import numpy as np\n'), ((26, 33, 26, 53), 'numpy.arange', 'np.arange', ({(26, 43, 26, 52): '2 * order'}, {}), '(2 * order)', True, 'import numpy as np\n'), ((26, 76, 26, 96), 'numpy.arange', 'np.arange', ({(26, 86, 26, 95): '2 * order'}, {}), '(2 * order)', True, 'import numpy as np\n'), ((29, 28, 29, 74), 'numpy.lexsort', 'np.lexsort', ({(29, 39, 29, 73): '(center_pts[:, (1)], center_pts[:, (0)])'}, {}), '((center_pts[:, (1)], center_pts[:, (0)]))', True, 'import numpy as np\n'), ((49, 28, 49, 76), 'numpy.lexsort', 'np.lexsort', ({(49, 39, 49, 75): '(center_pts[:, (1)], center_pts[:, (0)])'}, {}), '((center_pts[:, (1)], center_pts[:, (0)]))', True, 'import numpy as np\n'), ((34, 16, 34, 25), 'numpy.abs', 'np.abs', ({(34, 23, 34, 24): 'X'}, {}), '(X)', True, 'import numpy as np\n'), ((34, 28, 34, 37), 'numpy.abs', 'np.abs', ({(34, 35, 34, 36): 'Y'}, {}), '(Y)', True, 'import numpy as np\n'), ((125, 29, 125, 45), 'numpy.array', 'np.array', ({(125, 38, 125, 44): '[x, y]'}, {}), '([x, y])', True, 'import numpy as np\n'), ((33, 31, 33, 40), 'numpy.abs', 'np.abs', ({(33, 38, 33, 39): 'X'}, {}), '(X)', True, 'import numpy as np\n'), ((33, 43, 33, 52), 'numpy.abs', 'np.abs', ({(33, 50, 33, 51): 'Y'}, {}), '(Y)', True, 'import numpy as np\n'), ((33, 66, 33, 75), 'numpy.abs', 'np.abs', ({(33, 73, 33, 74): 'X'}, {}), '(X)', True, 'import numpy as np\n'), ((33, 78, 33, 87), 'numpy.abs', 'np.abs', ({(33, 85, 33, 86): 'Y'}, {}), '(Y)', True, 'import numpy as np\n')]