Skip to content

Instantly share code, notes, and snippets.

@Zwork101
Created October 8, 2018 18:42
Show Gist options
  • Save Zwork101/200505f786f0abeeebe0655ae4cf881f to your computer and use it in GitHub Desktop.
Save Zwork101/200505f786f0abeeebe0655ae4cf881f to your computer and use it in GitHub Desktop.
Issues with puzzle solver
import random
class Piece:
def __init__(self, width: int, height: int, color: int=None):
self.width = width
self.height = height
self.color = color if color else random.randint(0x0000FF, 0xFFF00)
def __repr__(self):
return "<Piece({w}, {h}, {c})>".format(w=self.width, h=self.height, c=self.color)
NORMAL_SET = [
*[Piece(21, 18) for _ in range(2)],
*[Piece(21, 14) for _ in range(2)],
Piece(28, 7),
Piece(28, 6),
Piece(12, 14),
Piece(14, 4),
Piece(10, 7),
Piece(32, 11),
Piece(32, 10),
Piece(17, 14)
]
from enum import Enum
from typing import List, Tuple, Union
from pieces import Piece, NORMAL_SET
import pygame
def to_rgb(number: int):
real_num = hex(number)[2:]
real_num = "0" * (6 - len(real_num)) + real_num
return tuple(int(real_num[i:i+2], 16) for i in (0, 2 ,4))
def _debug_contains(grid):
sum = []
for element in grid:
for thing in element:
if thing not in sum and thing is not None:
sum.append(thing)
return sum
class Direction(Enum):
WIDTH_FIRST = 1
HEIGHT_FIRST = 2
class Board:
def __init__(self, size: Tuple[int]=None):
self.size = size if size else (56, 56)
self.grid = [[None for _ in range(self.size[0])] for _ in range(self.size[1])]
pygame.init()
self.screen = pygame.display.set_mode((self.size[0] * 10, self.size[1] * 10))
def place(self, grid: List[List[Union[Piece, None]]], block: Piece, direction: Direction):
for y, yaxis in enumerate(grid):
for x, place in enumerate(yaxis):
if place is None:
if direction == Direction.WIDTH_FIRST:
left, down = block.width, block.height
else:
left, down = block.height, block.width
if x + left > self.size[0] or any(yaxis[x:x + left]):
return False
if y + down > self.size[1] or any(axis[x] for axis in grid[y:y + down]):
return False
for placey in grid[y:y + down]:
for i in range(x, x + left):
placey[i] = block
return True
def start_branch(self, grid: List[List[Union[Piece, None]]], remaining: List[Piece]=NORMAL_SET):
for block in remaining:
if remaining is NORMAL_SET:
grid = [[None for _ in range(self.size[0])] for _ in range(self.size[1])]
for direction in (Direction.WIDTH_FIRST, Direction.HEIGHT_FIRST):
cp_grid = grid.copy()
check = self.place(cp_grid, block, direction)
if check:
print("Success! Placed {b} at {d}".format(b=block, d=direction))
self.display_grid(cp_grid)
if not remaining:
print("Finished grid! {g}".format(g=cp_grid))
return cp_grid
remaining_clone = remaining.copy()
remaining_clone.remove(block)
result = self.start_branch(cp_grid, remaining_clone)
if result:
return result
print("Fail! Couldn't place {b} at {d}, in {c} | {s}"
.format(b=block, d=direction, c=len(remaining), s=_debug_contains(cp_grid)))
def display_grid(self, grid: List[List[Union[Piece, None]]]):
for y, yaxis in enumerate(grid):
for x, place in enumerate(yaxis):
pygame.draw.rect(self.screen, to_rgb(place.color) if place else to_rgb(0x00000F),
pygame.Rect(x * 10, y * 10, (x * 10) + 10, ((y * 10) + 10)))
for line_y in range(0, self.size[1] * 10, 10):
pygame.draw.line(self.screen, (0, 0, 0), (0, line_y), (self.size[0] * 10, line_y))
for line_x in range(0, self.size[0] * 10, 10):
pygame.draw.line(self.screen, (0, 0, 0), (line_x, 0), (line_x, self.size[1] * 10))
pygame.display.flip()
self.screen.fill((255, 255, 255))
if __name__ == "__main__":
b = Board()
print(b.start_branch(b.grid))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment