Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from PIL import Image
- import os
- class PuzzlePiece:
- # Save side strings and center image pixels as part of class
- def __init__(self, sides, center, image):
- self.sides = sides
- self.center = center
- self.image = image
- # top, right, bottom, left
- self.matched = [0, 0, 0, 0]
- self.position =[-1,-1]
- self.match_attemps_left = 5
- # Check that RBG are all less than half lit
- def is_black(pixel):
- return pixel[0] < 128 and pixel[1] < 128 and pixel[2] < 128
- # Return _ for none S for Square T for Triangle C for Circle and D for Diamond
- def get_shape_letter(subimage):
- pixel_access = subimage.load()
- if (not is_black(pixel_access[7,7])):
- # White center so nothing
- return '_'
- elif (not is_black(pixel_access[5,1])):
- # White just left of top center so diamond
- return 'D'
- elif (not is_black(pixel_access[0,14]) and not is_black(pixel_access[1,7])):
- # White bottom left and left center so triangle
- return 'T'
- elif (is_black(pixel_access[1,7]) and not is_black(pixel_access[0,0])):
- # Black left center White left top so Circle
- return 'C'
- else:
- # Only square remains
- return 'S'
- def get_sides(image):
- top_row = ((35,0,50,15),(57,0,72,15),(79,0,94,15),(101,0,116,15),(123,0,138,15))
- right_row = ((164,35,179,50),(164,57,179,72),(164,79,179,94),(164,101,179,116),(164,123,179,138))
- bottom_row = ((123,164,138,179),(101,164,116,179),(79,164,94,179),(57,164,72,179),(35,164,50,179))
- left_row = ((0,123,15,138),(0,101,15,116),(0,79,15,94),(0,57,15,72),(0,35,15,50))
- perimeter = (top_row, right_row, bottom_row, left_row)
- img_array = []
- for row in perimeter:
- img_str = ''
- for box in row:
- img_str += get_shape_letter(image.crop(box))
- img_array.append(img_str)
- return img_array
- def create_pieces_in_dir(directory_name):
- filenames = os.listdir(directory_name)
- pieces = []
- for filename in filenames:
- puzzle_image = Image.open(directory_name + "\\" + filename)
- pieces.append(PuzzlePiece(get_sides(puzzle_image), puzzle_image.crop((26,26,153,153)), puzzle_image))
- return pieces
- def find_an_adjacent_piece(piece, unplaced_pieces):
- searched = 0
- offset = 128
- if (piece.matched[0] < 3 and not piece.sides[0] == "_____"):
- for x in unplaced_pieces:
- searched += 1
- # Search for a piece above
- if (x.sides[2] == piece.sides[0]):
- x.position[0] = piece.position[0]
- x.position[1] = piece.position[1] - (offset * 2)
- piece.matched[0] += 1
- x.matched[2] += 1
- return x
- # Search upper right
- if (x.sides[1] == piece.sides[0]):
- x.position[0] = piece.position[0] + offset
- x.position[1] = piece.position[1] - (offset)
- piece.matched[0] += 1
- x.matched[1] += 1
- return x
- # Search upper left
- if (x.sides[3] == piece.sides[0]):
- x.position[0] = piece.position[0] - offset
- x.position[1] = piece.position[1] - (offset)
- piece.matched[0] += 1
- x.matched[3] += 1
- return x
- if (piece.matched[1] < 3 and not piece.sides[1] == "_____"):
- for x in unplaced_pieces:
- searched += 1
- # Search for a piece to the right
- if (x.sides[3] == piece.sides[1]):
- x.position[0] = piece.position[0] + (offset * 2)
- x.position[1] = piece.position[1]
- piece.matched[1] += 1
- x.matched[3] += 1
- return x
- # Search upper right
- if (x.sides[2] == piece.sides[1]):
- x.position[0] = piece.position[0] + (offset)
- x.position[1] = piece.position[1] - offset
- piece.matched[1] += 1
- x.matched[2] += 1
- return x
- # Search lower right
- if (x.sides[0] == piece.sides[1]):
- x.position[0] = piece.position[0] + (offset)
- x.position[1] = piece.position[1] + offset
- piece.matched[1] += 1
- x.matched[0] += 1
- return x
- if (piece.matched[2] < 3 and not piece.sides[2] == "_____"):
- for x in unplaced_pieces:
- searched += 1
- # Search for a piece below
- if (x.sides[0] == piece.sides[2]):
- x.position[0] = piece.position[0]
- x.position[1] = piece.position[1] + (offset * 2)
- piece.matched[2] += 1
- x.matched[0] += 1
- return x
- # Search lower right
- if (x.sides[1] == piece.sides[2]):
- x.position[0] = piece.position[0] - offset
- x.position[1] = piece.position[1] + (offset)
- piece.matched[2] += 1
- x.matched[1] += 1
- return x
- # Search lower left
- if (x.sides[3] == piece.sides[2]):
- x.position[0] = piece.position[0] + offset
- x.position[1] = piece.position[1] + (offset)
- piece.matched[2] += 1
- x.matched[3] += 1
- return x
- if (piece.matched[3] < 3 and not piece.sides[3] == "_____"):
- for x in unplaced_pieces:
- searched += 1
- # Search for a piece to the left
- if (x.sides[1] == piece.sides[3]):
- x.position[0] = piece.position[0] - (offset * 2)
- x.position[1] = piece.position[1]
- piece.matched[3] += 1
- x.matched[1] += 1
- return x
- # Search for a piece to the upper left
- if (x.sides[2] == piece.sides[3]):
- x.position[0] = piece.position[0] - (offset)
- x.position[1] = piece.position[1] - offset
- piece.matched[3] += 1
- x.matched[1] += 1
- return x
- # Search for a piece to the lower left
- if (x.sides[0] == piece.sides[3]):
- x.position[0] = piece.position[0] - (offset)
- x.position[1] = piece.position[1] + offset
- piece.matched[3] += 1
- x.matched[1] += 1
- return x
- print("No matches found after :" + str(searched) + " searches")
- return None
- all_pieces = create_pieces_in_dir("ARG")
- unplaced = all_pieces.copy()
- placed_unfinished = []
- new_image = Image.new("RGB", (20000,20000), (255,255,255))
- # Need to see multiple images here to get process started
- for piece in all_pieces:
- if (piece.sides[0] == "CDTDC"):
- print("Found first seed")
- #Should be double zero piece lets use it as center
- piece.position = [10000, 10000]
- box = (piece.position[0], piece.position[1])
- new_image.paste(piece.center, box)
- unplaced.remove(piece)
- placed_unfinished.append(piece)
- elif (piece.sides[0] == "DTCTS"):
- print("Found second seed")
- piece.position = [10000 - 128, 10000]
- box = (piece.position[0], piece.position[1])
- new_image.paste(piece.center, box)
- unplaced.remove(piece)
- placed_unfinished.append(piece)
- print ("Starting search current seeds: " + str(len(placed_unfinished)))
- total_adjacency_attempts = 0
- while len(placed_unfinished) > 0:
- total_adjacency_attempts += 1
- piece = placed_unfinished[0]
- print("Finding adjacent for " + piece.sides[0] + piece.sides[1] + piece.sides[2] + piece.sides[3])
- adjacent = find_an_adjacent_piece(piece, unplaced)
- if adjacent != None:
- unplaced.remove(adjacent)
- placed_unfinished.append(adjacent)
- box = (adjacent.position[0], adjacent.position[1])
- new_image.paste(adjacent.center, box)
- print("Placed " + adjacent.sides[0] + adjacent.sides[1] + adjacent.sides[2] + adjacent.sides[3])
- else:
- print("None found for " + piece.sides[0] + piece.sides[1] + piece.sides[2] + piece.sides[3] + " attempts left: " + str(piece.match_attemps_left))
- placed_unfinished.remove(piece)
- piece.match_attemps_left = piece.match_attemps_left - 1
- if (piece.match_attemps_left > 0) :
- placed_unfinished.append(piece)
- print("Total adjacency attempts: "+ str(total_adjacency_attempts))
- new_image.save("Assembled.jpg")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement