Skip to content

Instantly share code, notes, and snippets.

@yspreen
Last active January 15, 2017 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yspreen/4c0e89c58e82b612b95e927480611e81 to your computer and use it in GitHub Desktop.
Save yspreen/4c0e89c58e82b612b95e927480611e81 to your computer and use it in GitHub Desktop.
Logiq Tower greedy solver
from Piece import Piece
from copy import deepcopy
class Board:
def __init__(self, data):
self.data = data
def copy(self):
return Board(deepcopy(self.data))
@staticmethod
def empty(height=5):
data = {'layers': []}
for i in range(0, height):
data['layers'].append([])
for j in range(0, 13):
data['layers'][i].append('')
return Board(data)
@property
def is_full(self):
for layer in self.data['layers']:
for block in layer:
if block == '':
return False
return True
@property
def is_symmetric(self):
for layer in self.data['layers']:
filled = layer[0] != ''
for block in layer[1:]:
if filled != (block != ''):
return False
return True
def try_fit(self, piece: Piece):
board = self.copy()
i = -1
for layer in piece.data['layers']:
i += 1
for j in range(13):
if layer[j] == 1 and board.data['layers'][i][j] != '':
return False, board
if layer[j] == 1:
board.data['layers'][i][j] = piece.data['name']
return True, board
from Piece import Piece
from Board import Board
p_0 = {
'name': '0', 'color': 'b', 'symmetric': True, 'layers': [
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_1 = {
'name': '1', 'color': 'r', 'symmetric': True, 'layers': [
[1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_2 = {
'name': '2', 'color': 'g', 'symmetric': True, 'layers': [
[1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_3 = {
'name': '3', 'color': 'b', 'symmetric': True, 'layers': [
[1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
]
}
p_4 = {
'name': '4', 'color': 'r', 'symmetric': True, 'layers': [
[1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
]
}
p_I = {
'name': 'I', 'color': 'b', 'symmetric': True, 'layers': [
[0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]
]
}
p_Y = {
'name': 'Y', 'color': 'g', 'symmetric': False, 'layers': [
[0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_L = {
'name': 'L', 'color': 'r', 'symmetric': False, 'layers': [
[0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_N = {
'name': 'N', 'color': 'r', 'symmetric': False, 'layers': [
[0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_U = {
'name': 'U', 'color': 'g', 'symmetric': False, 'layers': [
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_Q = {
'name': 'Q', 'color': 'b', 'symmetric': False, 'layers': [
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_W = {
'name': 'W', 'color': 'g', 'symmetric': False, 'layers': [
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_F = {
'name': 'F', 'color': 'b', 'symmetric': False, 'layers': [
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_T = {
'name': 'T', 'color': 'r', 'symmetric': False, 'layers': [
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
p_S = {
'name': 'S', 'color': 'g', 'symmetric': True, 'layers': [
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
}
pieces = [
Piece(p_0),
Piece(p_1),
Piece(p_2),
Piece(p_3),
Piece(p_4),
Piece(p_I),
Piece(p_Y),
Piece(p_L),
Piece(p_N),
Piece(p_U),
Piece(p_Q),
Piece(p_W),
Piece(p_F),
Piece(p_T),
Piece(p_S),
]
solutions = []
counter = 0
def fill(board, pieces, height=5):
global solutions
global counter
for piece in pieces:
new_pieces = pieces.copy()
new_pieces.remove(piece)
for orientation in piece.orientations(board.is_symmetric, height=height):
# if counter % 10000 == 0:
# print(counter)
counter += 1
fits, new_board = board.try_fit(orientation)
if fits:
if new_board.is_full:
solutions.append(new_board)
print(new_board.data['layers'])
else:
fill(new_board, new_pieces, height=height)
print("Please enter tower height: ")
h = int(input())
fill(Board.empty(height=h), pieces, height=h)
from copy import deepcopy
class Piece:
empty_layer = [0 for i in range(13)]
def __init__(self, data: dict):
self.data = data
def copy(self):
return Piece(deepcopy(self.data))
def flip(self):
i = 0
for layer in self.data['layers']:
self.data['layers'][i][1:] = list(reversed(layer[1:]))
i += 1
self.data['layers'] = list(reversed(self.data['layers']))
def orientations(self, board_symmetric: bool, height=5):
o = []
if not self.data['symmetric']:
copy = self.copy()
copy.flip()
copy.data['symmetric'] = True
o.extend(copy.orientations(board_symmetric, height=height))
copy = self.copy()
while len(copy.data['layers']) < height+1:
if board_symmetric:
o.append(copy.copy())
else:
for j in range(12):
o.append(copy.copy())
k = -1
for layer in copy.data['layers']:
k += 1
layer = layer[1:]
layer.append(layer[0])
del layer[0]
copy.data['layers'][k][1:] = layer
copy.data['layers'].insert(0, Piece.empty_layer.copy())
return o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment