예제 #1
0
 def genkids(self):
     new = set()
     if len(self.cords) < 4:
         for cord in self.cords:
             for i in [[0, 1], [1, 0], [0, -1], [-1, 0]]:
                 new.add((cord[0] + i[0], cord[1] + i[1]))
         for item in self.cords:
             new.discard(item)
         if new:
             for i in new:
                 temp = []
                 for k in self.cords:
                     temp.append(k)
                 temp.append(i)
                 self.child.append(TreePoint(temp))
                 self.child[-1].genkids()
     else:
         for i in range(1, 18):
             for cord in self.cords:
                 tempcords = []
                 for k in self.cords:
                     temp = [-cord[0] + k[0], -cord[1] + k[1]]
                     if temp not in utils.generate_shape(i):
                         break
                 else:
                     self.id = i
예제 #2
0
 def setPieceId(self, shapeId, CopyT, row, col, M, pieceId):
     shape = utils.generate_shape(shapeId)
     for [y, x] in shape:
         CopyT[y + row][x + col] = 0
         M[y + row][x + col] = (shapeId, pieceId)
     pieceId += 1
     return CopyT, M, pieceId
 def check_piece_validity(target, r,
                          c):  #check for pieces that fit in the target area
     valid_pieces = []  #create list for valid pieces
     for shape_id in range(4, 20):  #check each of 16 shapes with ids 4-19
         shape = utils.generate_shape(
             shape_id
         )  #define shape from utils as a linear transformation using 4 coordinate pairs
         piece = [[y + r, x + c]
                  for [y, x] in shape]  #define piece as 4 coordinate pairs
         #check piece validity
         valid = False  #set default piece validity
         piece_neighbour_counts = [
         ]  #create list for neighbour count for each occupied square of a piece
         for j, k in piece:  #for each coordinate
             if j < 0 or j >= height or k < 0 or k >= width:  #no negative numbers otherwise will look from end of list
                 break
             else:
                 if target[j][
                         k] == 1:  #check if the coordinate square is occupied
                     piece_neighbour_counts.append(
                         neighbour_count_matrix[j][k])
                     if piece.index([j, k]) == 3:
                         valid = True
                 else:
                     break  #one of the squares is not occupied, go to next piece
         if valid:
             valid_pieces.append(
                 [piece, shape_id,
                  sum(piece_neighbour_counts)])  #store valid shape ids
     sorted(valid_pieces, key=lambda piece: piece[2])
     return valid_pieces
예제 #4
0
def check_placement(partial_sol, limit_tetris, placement):
    if limit_tetris[placement['shapeID']] == 0:
        return False
    for sq_row, sq_col in utils.generate_shape(placement['shapeID']):
        row = placement['row'] + sq_row
        col = placement['col'] + sq_col
        if partial_sol[row][col] is not None:
            return False
    return True
예제 #5
0
def canitfit(shapeid, pos):
    shape = utils.generate_shape(shapeid)
    #print(shape)
    #print(shapeid)
    for sq in shape:
        output = [100, "a", "a"]
        a = doesitfit2(shapeid, (pos[0] - sq[0], pos[1] - sq[1]))
        #print (pos[0]-sq[0],pos[1]-sq[1])
        #print("does it fit2 returns", a)
        if a != False and a < output[0]:
            output = (a, (pos[0] - sq[0], pos[1] - sq[1]), shapeid)
    return output  #Unused at the moment
예제 #6
0
def shapepos(
    shapeid, pos
):  # takes the shape id and the starting possition and returns a list of the true cordinates
    output = []
    shape = utils.generate_shape(shapeid)
    for square in shape:
        testpos = [pos[0] + square[0],
                   pos[1] + square[1]]  #getting position of the point of shape
        output.append(testpos)
        #if testpos[0] * testpos[1] < 0:
        #   return False Code that used to debug stuff but was not worth it
    return output
예제 #7
0
 def place_shape_and_update_target_matrix():
     shape_id = shape_id_with_lowest_sum_result
     offsets_of_tiles_in_shape = utils.generate_shape(shape_id)
     start_coord = first_non_0_coord
     for tile_offset in offsets_of_tiles_in_shape:
         updating_target_matrix[start_coord[0] +
                                tile_offset[0]][start_coord[1] +
                                                tile_offset[1]] = 0
         my_solution_matrix_np[start_coord[0] +
                               tile_offset[0]][start_coord[1] +
                                               tile_offset[1]] = (
                                                   shape_id,
                                                   placement_counter)
예제 #8
0
 def shape_id_with_lowest_sum(
 ):  # has no way of breaking the tie between two equal summed shapes
     lowest_sum_so_far = 9999999999
     lowest_shape_id_so_far = 0
     for shape_id in list_of_shapes_that_fit_inside_cutout_result:
         # calculate sum of shape in weight matrix
         offsets_of_tiles_in_shape = utils.generate_shape(shape_id)
         shape_sum = 0
         for tile_offset in offsets_of_tiles_in_shape:
             tile_value = value_of_tile_at_offset(first_non_0_coord,
                                                  tile_offset)
             shape_sum = shape_sum + tile_value
         if shape_sum < lowest_sum_so_far:
             lowest_sum_so_far = shape_sum
             lowest_shape_id_so_far = shape_id
     return lowest_shape_id_so_far
예제 #9
0
 def list_of_shapes_that_fit_inside_cutout():
     result = []
     shape_items = number_of_allowed_shapes.items()
     for shape_id, number_of_instances_of_shape_allowed in shape_items:
         if not (first_non_0_value >= shape_origins_values[shape_id]
                 and number_of_instances_of_shape_allowed != 0):
             continue
         offsets_of_tiles_in_shape = utils.generate_shape(shape_id)
         shape_fails_test = False
         for tile_offset in offsets_of_tiles_in_shape:
             tile_value = value_of_tile_at_offset(first_non_0_coord,
                                                  tile_offset)
             if tile_value <= 0:
                 shape_fails_test = True
                 break
         if shape_fails_test is False:
             result.append(shape_id)
     return result
예제 #10
0
    def identifyCandidateShapes(self, CopyT, height, width, row, column):
        candidateShapes = []
        for m in self.shapeIds:
            valid = True
            shape = utils.generate_shape(
                m
            )  #import from utils the generate shape which is called by generate target.
            piece = [[y + row, x + column] for [y, x] in shape]
            for [r, c] in piece:
                if r < 0 or c < 0 or r >= height or c >= width:
                    valid = False
                    break  #break terminates the current loop and resumes execution at the next statement
                if CopyT[r][c] == 0:  #using boolean conditions.
                    valid = False
                    break

            if valid == True:
                candidateShapes.append(m)
        return candidateShapes
예제 #11
0
 def set_tiles_of_shape_to_0(shape_id, start_coord):
     shape_rel_coords = utils.generate_shape(shape_id)
     for coord in shape_rel_coords:
         weight_matrix[start_coord[0] + coord[0]][start_coord[1] +
                                                  coord[1]] = 0
예제 #12
0
def Tetris(target, limit_tetris):
    tetronimos = [0] + [utils.generate_shape(x) for x in range(1, 20)]

    width = len(target[0])  # The width of the target matrix
    height = len(target)

    solution_matrix = deepcopy(target)
    total_shapes = 0
    for shape in limit_tetris:
        total_shapes += limit_tetris[shape]

    for y in range(len(solution_matrix)):
        for x in range(len(solution_matrix[y])):
            if not solution_matrix[y][x]:
                solution_matrix[y][x] = (0, 0)
    pieceID = 1

    for y in range(len(target)):
        for x in range(len(target[y])):
            if target[y][x]:
                biggest_score = 0
                best_shape = 0
                coord_scores = calc_coord_scores(target, x, y)
                if coord_scores != {}:
                    results = []
                    for shapeID in limit_tetris:
                        if limit_tetris[shapeID] > 0:
                            if total_shapes > 2500:
                                weighting = (limit_tetris[shapeID] /
                                             total_shapes)
                            else:
                                weighting = 1
                            weighting = (limit_tetris[shapeID] / total_shapes)
                            shape_score = weighting * score_fit(
                                shapeID, tetronimos, coord_scores)
                            if shape_score > biggest_score:
                                biggest_score = shape_score
                                best_shape = shapeID
                    if biggest_score > 0:
                        pieceID = place(best_shape, x, y, solution_matrix,
                                        pieceID, tetronimos, target,
                                        limit_tetris)
                        total_shapes -= 1
                    else:
                        solution_matrix[y][x] = (0, 0)
                else:
                    solution_matrix[y][x] = (0, 0)

    #places an block
    for y in range(len(target)):
        for x in range(len(target[y])):
            if target[y][x]:
                for shapeID in limit_tetris:
                    if limit_tetris[shapeID] > 0:
                        covering = 0
                        for coord_mod in tetronimos[shapeID]:
                            new_y = y + coord_mod[0]
                            new_x = x + coord_mod[1]
                            if new_y >= 0 and new_x >= 0 and new_y < height and new_x < width:
                                if target[new_y][new_x] and solution_matrix[
                                        new_y][new_x] == (0, 0):
                                    covering += 1
                                if solution_matrix[new_y][new_x] != (0, 0):
                                    covering = 0
                                    break
                            else:
                                covering = 0
                                break
                        if covering >= 3:
                            pieceID = place(shapeID, x, y, solution_matrix,
                                            pieceID, tetronimos, target,
                                            limit_tetris)
                            break

    #print('\n'.join([' '.join([str(char) for char in row]) for row in solution_matrix]))
    return solution_matrix
예제 #13
0
from copy import deepcopy
import utils

tetronimos = [0] + [utils.generate_shape(x) for x in range(1, 20)]


def calc_coord_scores(target, x, y):
    neighbors = [[-1, 0], [0, -1], [0, 1], [1, 0]]

    score = 0

    coords_to_check = [(0, 0), (0, 1), (0, 2), (0, 3), (1, -2), (1, -1),
                       (1, 0), (1, 1), (1, 2), (2, -1), (2, 0), (2, 1), (3, 0)]
    coord_scores = {}

    checked_coords = []
    for coord_mod in coords_to_check:
        score = 0
        y_mod, x_mod = coord_mod
        cur_y = y + y_mod
        cur_x = x + x_mod
        try:
            if (cur_x < 0) or (cur_y < 0):
                raise IndexError
            if target[cur_y][cur_x]:
                for neighbor in neighbors:
                    try:
                        check_y, check_x = cur_y + neighbor[
                            0], cur_x + neighbor[1]
                        if not target[check_y][check_x]:
                            score += 1
예제 #14
0
def Tetris(target, limit_tetris):

    #   create padded target by adding a buffer of threes all around

    pad_target = np.pad(target, [3, 3], mode='constant', constant_values=3)
    pad_height = len(pad_target)
    pad_width = len(pad_target[0])
    solution = [[(0, 0) for col in range(0, pad_width)]
                for row in range(0, pad_height)]
    moved_coords = []
    one_here = []  #coordinates of ones in pad

    #   find the coordinates of where there are ones in the target
    for i in range(3, pad_height - 3):
        for j in range(3, pad_width - 3):
            if pad_target[i][j] == 1:
                one_here.append([i, j])

    i = 0
    x = 0
    #   add a value of one_here (coordinate e.g. (3,4) to the shape's coordinates in order to change the shape's location
    while x < len(one_here):
        for i in limit_tetris:
            if limit_tetris[
                    i] >= 1:  #if there is that piece in limit tetris continue

                shapecoords = utils.generate_shape(i)

                good_place1 = (0 + ((one_here[x][0]))), (0 +
                                                         ((one_here[x][1])))
                l = pad_target[good_place1[0]][good_place1[1]]

                good_place2 = (shapecoords[1][0] +
                               ((one_here[x][0]))), (shapecoords[1][1] +
                                                     ((one_here[x][1])))
                #adds the coordinate of a block in a shape to where there is a one
                m = pad_target[good_place2[0]][good_place2[1]]

                if m == 1:
                    # check if that block also fits in a shape

                    good_place3 = (shapecoords[2][0] +
                                   ((one_here[x][0]))), (shapecoords[2][1] +
                                                         ((one_here[x][1])))
                    n = pad_target[good_place3[0]][good_place3[1]]

                    if n == 1:
                        good_place4 = (shapecoords[3][0] + (
                            (one_here[x][0]))), (shapecoords[3][1] +
                                                 ((one_here[x][1])))
                        o = pad_target[good_place4[0]][good_place4[1]]

                        if o == 1 and l == 1:

                            moved_coords.append(good_place1)
                            pad_target[good_place1[0]][good_place1[1]] = 2
                            #two means i've place a piece there instead of just making it empty

                            moved_coords.append(good_place2)
                            pad_target[good_place2[0]][good_place2[1]] = 2

                            moved_coords.append(good_place3)
                            pad_target[good_place3[0]][good_place3[1]] = 2

                            moved_coords.append(good_place4)
                            pad_target[good_place4[0]][good_place4[1]] = 2

                            moved_coords.append(i)
                            del one_here[
                                x]  #faster to include this function for some reason
                            limit_tetris[i] -= 1

        x += 1

    x = 0

    #optimising:
    #
    good_place1 = 0
    good_place2 = 0
    good_place3 = 0
    good_place4 = 0

    while x < len(one_here):
        for a in limit_tetris:
            if limit_tetris[a] >= 1:
                optimshapes = utils.generate_shape(a)

                good_place1 = (0 + ((one_here[x][0]))), (0 +
                                                         ((one_here[x][1])))
                l = pad_target[good_place1[0]][good_place1[1]]

                good_place2 = (optimshapes[1][0] +
                               ((one_here[x][0]))), (optimshapes[1][1] +
                                                     ((one_here[x][1])))
                m = pad_target[good_place2[0]][good_place2[1]]

                good_place3 = (optimshapes[2][0] +
                               ((one_here[x][0]))), (optimshapes[2][1] +
                                                     ((one_here[x][1])))
                n = pad_target[good_place3[0]][good_place3[1]]

                good_place4 = (optimshapes[3][0] +
                               ((one_here[x][0]))), (optimshapes[3][1] +
                                                     ((one_here[x][1])))
                o = pad_target[good_place4[0]][good_place4[1]]

                if (l == 1 and m == 1 and n == 1 and o == 1) or (
                        l == 1 and m == 0 and n == 1
                        and o == 1) or (l == 1 and m == 1 and n == 1
                                        and o == 0) or (l == 1 and m == 1
                                                        and n == 0 and o == 1):

                    moved_coords.append(good_place1)
                    pad_target[good_place1[0]][good_place1[1]] = 2
                    #two means i've place a piece there instead of just making it empty

                    moved_coords.append(good_place2)
                    pad_target[good_place2[0]][good_place2[1]] = 2

                    moved_coords.append(good_place3)
                    pad_target[good_place3[0]][good_place3[1]] = 2

                    moved_coords.append(good_place4)
                    pad_target[good_place4[0]][good_place4[1]] = 2

                    moved_coords.append(a)
                    del one_here[
                        x]  #faster to include this function for some reason
                    limit_tetris[a] -= 1

        x += 1

    x = 0

    moved_coords = [
        moved_coords[i:i + 5] for i in range(0, len(moved_coords), 5)
    ]
    #splits moved coords up into a list of lists, where moved_coords[i] is a list of 4 coordinates and a piece id value

    #   change the (0,0) in solution to place a random piece in piece_idfor j in (0, len(piece_id)):
    for i in range(0, len(moved_coords)):
        for j in range(0, 4):
            solution[moved_coords[i][j][0]][moved_coords[i][j][1]] = (
                moved_coords[i][4], i + 1)

    shrunken_solution = solution[3:-3]
    shrunken_solution = [i[3:-3] for i in shrunken_solution]

    return shrunken_solution
예제 #15
0
def Tetris(target, limit_tetris):

    ########## SETUP #########

    n = 1  #piece ID
    shapeID = 0  #shapeID
    J = deepcopy(target)  # Array for placing in weights

    #blank solution:

    M = deepcopy(target)
    for i in range(len(M)):
        for j in range(len(M[0])):
            M[i][j] = (0, 0)

    def weighting():
        for a in range(len(J)):
            for b in range(len(J[0])):
                try:
                    weight = 0
                    if J[a - 1][b] >= 1:
                        weight += 1
                    if J[a + 1][b] >= 1:
                        weight += 1
                    if J[a][b + 1] >= 1:
                        weight += 1
                    if J[a][b - 1] >= 1:
                        weight += 1

                    J[a][b] = weight

                except IndexError:
                    pass

                    ####problem is that have to do "try except" for all if statements - actually probably not?

                #need to call weighting early in code and then overwrite J with 0s in the place a piece was just placed when placed

        return J

    weighting()  #setting up J for the first time

    ##########main loop to place pieces############

    ##an approach of going piece by piece finding a spot for each one as you go
    while not all(value == 0 for value in limit_tetris.values()
                  ):  ##loops as long as there are still pieces left to place
        for key in limit_tetris:  #for each type of piece in the dictionary
            print("Key: {0}".format(key))
            if limit_tetris[
                    key] != 0:  #if there's a piece of that type left then...
                print("Wooo!!! I'm here! The key is {0}. n = {1}.".format(
                    key, n))
                print(limit_tetris)
                shape = utils.generate_shape(key)
                for i in range(len(M)):  #check each space in the grid
                    for j in range(len(M[0])):  #check each space in the grid
                        print(
                            "I'm here! The key is {0}, i = {1} and j = {2}. PieceID = {3}. ShapeID = {4}"
                            .format(key, i, j, n, shapeID))

                        ##if weight =3

                        if J[i][j] < 3:
                            break

                        if target[i][j] == 1 and limit_tetris[key] != 0:
                            print("I've got here now!")
                            try:  # To fix index error
                                if target[i + shape[1][0]][
                                        j + shape[1]
                                    [1]] == 1 and target[i + shape[2][0]][
                                        j + shape[2]
                                        [1]] == 1 and target[i + shape[3][0]][
                                            j + shape[3]
                                            [1]] == 1:  #check if the shape fits
                                    print(
                                        "Results from checking if shape fits: ({0}, {1}), ({2}, {3}), ({4}, {5}), ({6}, {7})"
                                        .format(i, j, i + shape[1][0],
                                                j + shape[1][1],
                                                i + shape[2][0],
                                                j + shape[2][1],
                                                i + shape[3][0],
                                                j + shape[3][1]))
                                    if j + shape[1][1] < 0 or j + shape[2][
                                            1] < 0 or j + shape[2][1] < 0:
                                        print("Negative index error")
                                        break

                                    ###debugging

                                    shapeID = limit_tetris[key]

                                    ###end of debugging

                                    #place shape into M:
                                    M[i][j] = (key, n)
                                    M[i + shape[1][0]][j + shape[1][1]] = (key,
                                                                           n)
                                    M[i + shape[2][0]][j + shape[2][1]] = (key,
                                                                           n)
                                    M[i + shape[3][0]][j + shape[3][1]] = (key,
                                                                           n)

                                    n += 1  #increase pieceID

                                    #remove the 1s from target:

                                    target[i][j] = 0
                                    target[i + shape[1][0]][j +
                                                            shape[1][1]] = 0
                                    target[i + shape[2][0]][j +
                                                            shape[2][1]] = 0
                                    target[i + shape[3][0]][j +
                                                            shape[3][1]] = 0

                                    #remove the piece from the limit_tetris
                                    print(limit_tetris[key])
                                    limit_tetris[key] = limit_tetris[key] - 1

                                    #replace shape in J with 0s

                                    J[i][j] = 0
                                    J[i + shape[1][0]][j + shape[1][1]] = 0
                                    J[i + shape[2][0]][j + shape[2][1]] = 0
                                    J[i + shape[3][0]][j + shape[3][1]] = 0

                                    #redo J with new weightings

                                    weighting()

                            except IndexError:
                                pass

        for i in range(len(J)):
            print(J[i])
        return M
예제 #16
0
def apply_placement(partial_sol, limit_tetris, placement, piece_id):
    for sq_row, sq_col in utils.generate_shape(placement['shapeID']):
        row = placement['row'] + sq_row
        col = placement['col'] + sq_col
        partial_sol[row][col] = (placement['shapeID'], piece_id)