def test_init_domain_two_blocks(self): """ Test that init domain generates correct domains """ correct_domain = [ '0000111101', '0001111001', '0001111010', '0011110001', '0011110010', '0011110100', '0111100001', '0111100010', '0111100100', '0111101000', '1111000001', '1111000010', '1111000100', '1111001000', '1111010000' ] domain = sorted(NonogramState.init_domain(10, [4, 1])) self.assertEqual(len(correct_domain), len(domain)) for i, element in enumerate(domain): self.assertEqual(element, correct_domain[i])
def set_solution(self, solution): """ Receives a solution from search and sets the node """ self.nonogram_state = NonogramState( solution.state, None, solution.domains, solution.solution_length )
def level_loaded(self, nonogram): """ Called whenever a level is loaded, adjust Widget size """ self.nonogram_state = NonogramState(nonogram, None) self.compute_tile_size()
class NonogramGUI(QtGui.QFrame): """ Implement QFrame, which is a subclass of QWidget """ status_message = pyqtSignal(str) def __init__(self, parent): QtGui.QFrame.__init__(self, parent) self.dx = self.dy = 1 self.widget_width_px = self.widget_height_px = 600 self.nonogram_state = None self.set_nonogram(True) self.delay = 50 self.mode = C.search_mode.A_STAR self.thread = SearchWorker(self) self.init_ui() def init_ui(self): """ Initialize the UI """ self.setFocusPolicy(QtCore.Qt.StrongFocus) size = QtCore.QSize(self.widget_width_px, self.widget_height_px) self.setMinimumSize(size) self.parent().adjustSize() def level_loaded(self, nonogram): """ Called whenever a level is loaded, adjust Widget size """ self.nonogram_state = NonogramState(nonogram, None) self.compute_tile_size() def compute_tile_size(self): """ Computes tile size based on widget size and nonogram """ self.dx = self.dy = 1 x, y = self.nonogram_state.state.x, self.nonogram_state.state.y self.dx *= (self.widget_width_px / float(x)) self.dy *= (self.widget_height_px / float(y)) def start_search(self): """ Start the search in the worker thread """ self.status_message.emit(str('Search started')) search = NonogramBfs(self.nonogram_state.state, self) self.thread.search(search) def set_solution(self, solution): """ Receives a solution from search and sets the node """ self.nonogram_state = NonogramState( solution.state, None, solution.domains, solution.solution_length ) def paint(self, state): """ Receives a node and tells Qt to update the graphics """ self.nonogram_state = state self.update() def paintEvent(self, _): # pylint: disable=invalid-name """ Called by the Qt event loop when the widget should be updated """ painter = QtGui.QPainter(self) self.draw_nonogram(painter) def resizeEvent(self, e): # pylint: disable=invalid-name """ Handles widget resize and scales Nonogram """ self.widget_width_px = e.size().width() self.widget_height_px = e.size().height() self.compute_tile_size() def draw_nonogram(self, painter): """ Draws a Nonogram, WHITE should be treated as an error. """ colors = { C.colors.GREY: QtGui.QColor(130, 130, 130), # Unset C.colors.PINK: QtGui.QColor(255, 255, 150), # Drawn C.colors.YELLOW: QtGui.QColor(255, 0, 150), # Space C.colors.WHITE: QtGui.QColor(255, 255, 255) # No domains } for y, row in enumerate(self.nonogram_state.representation()): for x, element in enumerate(row): painter.setBrush(colors[int(element)]) painter.drawRect(x*self.dx, y*self.dy, self.dx - 1, self.dy - 1) def set_nonogram(self, default=False): """ Load level with a QFileDialog """ folder = res.nonograms.__path__[0] if default: path = folder + '/nono-heart-1.txt' else: path = QtGui.QFileDialog.getOpenFileName( self.window(), "Nonogram Selector", folder, "Text files (*.txt)" ) if not path: return nonogram_file = open(path, 'r') contents = [line.strip() for line in nonogram_file.read().splitlines()] self.level_loaded(Nonogram(contents)) filename = path.split('/')[-1] title = 'Module 3 - Nonogram - {}'.format(filename) self.parent().setWindowTitle(title) self.status_message.emit(str('Loaded: {}'.format(filename))) self.update() def set_delay(self, delay): """ Change delay """ self.delay = delay self.status_message.emit('Delay: ' + str(delay))