#!/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
    
    


[((1428, 1445), 'numpy.array', 'np.array', (['[*grid]'], {}), '([*grid])\n', (1436, 1445), True, 'import numpy as np\n'), ((3225, 3242), 'numpy.array', 'np.array', (['[*grid]'], {}), '([*grid])\n', (3233, 3242), True, 'import numpy as np\n'), ((220, 236), 'numpy.random.rand', 'np.random.rand', ([], {}), '()\n', (234, 236), True, 'import numpy as np\n'), ((272, 288), 'numpy.array', 'np.array', (['[x, y]'], {}), '([x, y])\n', (280, 288), True, 'import numpy as np\n'), ((294, 314), 'numpy.array', 'np.array', (['[x + 1, y]'], {}), '([x + 1, y])\n', (302, 314), True, 'import numpy as np\n'), ((320, 337), 'numpy.array', 'np.array', (['[0, -1]'], {}), '([0, -1])\n', (328, 337), True, 'import numpy as np\n'), ((365, 385), 'numpy.array', 'np.array', (['[x, y + 1]'], {}), '([x, y + 1])\n', (373, 385), True, 'import numpy as np\n'), ((387, 411), 'numpy.array', 'np.array', (['[x + 1, y + 1]'], {}), '([x + 1, y + 1])\n', (395, 411), True, 'import numpy as np\n'), ((413, 429), 'numpy.array', 'np.array', (['[0, 1]'], {}), '([0, 1])\n', (421, 429), True, 'import numpy as np\n'), ((469, 485), 'numpy.array', 'np.array', (['[x, y]'], {}), '([x, y])\n', (477, 485), True, 'import numpy as np\n'), ((491, 511), 'numpy.array', 'np.array', (['[x, y + 1]'], {}), '([x, y + 1])\n', (499, 511), True, 'import numpy as np\n'), ((517, 534), 'numpy.array', 'np.array', (['[-1, 0]'], {}), '([-1, 0])\n', (525, 534), True, 'import numpy as np\n'), ((562, 582), 'numpy.array', 'np.array', (['[x + 1, y]'], {}), '([x + 1, y])\n', (570, 582), True, 'import numpy as np\n'), ((584, 608), 'numpy.array', 'np.array', (['[x + 1, y + 1]'], {}), '([x + 1, y + 1])\n', (592, 608), True, 'import numpy as np\n'), ((610, 626), 'numpy.array', 'np.array', (['[1, 0]'], {}), '([1, 0])\n', (618, 626), True, 'import numpy as np\n'), ((735, 755), 'numpy.arange', 'np.arange', (['(2 * order)'], {}), '(2 * order)\n', (744, 755), True, 'import numpy as np\n'), ((778, 798), 'numpy.arange', 'np.arange', (['(2 * order)'], {}), '(2 * order)\n', (787, 798), True, 'import numpy as np\n'), ((919, 971), 'numpy.lexsort', 'np.lexsort', (['(center_pts[:, (1)], center_pts[:, (0)])'], {}), '((center_pts[:, (1)], center_pts[:, (0)]))\n', (929, 971), True, 'import numpy as np\n'), ((1474, 1526), 'numpy.lexsort', 'np.lexsort', (['(center_pts[:, (1)], center_pts[:, (0)])'], {}), '((center_pts[:, (1)], center_pts[:, (0)]))\n', (1484, 1526), True, 'import numpy as np\n'), ((1137, 1146), 'numpy.abs', 'np.abs', (['X'], {}), '(X)\n', (1143, 1146), True, 'import numpy as np\n'), ((1149, 1158), 'numpy.abs', 'np.abs', (['Y'], {}), '(Y)\n', (1155, 1158), True, 'import numpy as np\n'), ((3372, 3388), 'numpy.array', 'np.array', (['[x, y]'], {}), '([x, y])\n', (3380, 3388), True, 'import numpy as np\n'), ((1051, 1060), 'numpy.abs', 'np.abs', (['X'], {}), '(X)\n', (1057, 1060), True, 'import numpy as np\n'), ((1063, 1072), 'numpy.abs', 'np.abs', (['Y'], {}), '(Y)\n', (1069, 1072), True, 'import numpy as np\n'), ((1086, 1095), 'numpy.abs', 'np.abs', (['X'], {}), '(X)\n', (1092, 1095), True, 'import numpy as np\n'), ((1098, 1107), 'numpy.abs', 'np.abs', (['Y'], {}), '(Y)\n', (1104, 1107), True, 'import numpy as np\n')]