Exemplo n.º 1
0
def save_nonogram_from_url(url):
    try:
        nono_id, nono_name, d = parse_nonogram(url)
    except Exception as e:
        # print('Ссылка не туда')
        print(e)
    else:
        columns_number = d[1][0] % d[1][3] + d[1][1] % d[1][3] - d[1][2] % d[
            1][3]  # ширина
        rows_number = d[2][0] % d[2][3] + d[2][1] % d[2][3] - d[2][2] % d[2][
            3]  # высота
        colors_number = d[3][0] % d[3][3] + d[3][1] % d[3][3] - d[3][2] % d[3][
            3]

        nono_answer = np.full((rows_number, columns_number), 0)
        # print('Columns number =', columns_number)
        # print('Rows number', rows_number)
        v = colors_number + 5
        black_rows_number = d[v][0] % d[v][3] * (
            d[v][0] % d[v][3]) + d[v][1] % d[v][3] * 2 + d[v][2] % d[v][3]
        decoder = d[v + 1]

        for x in range(v + 2, v + 1 + black_rows_number + 1):
            for v in range(d[x][0] - decoder[0] - 1,
                           d[x][0] - decoder[0] + d[x][1] - decoder[1] - 1):
                nono_answer[d[x][3] - decoder[3] - 1][v] = d[x][2] - decoder[2]

        header_rows = get_header_from_array(nono_answer)
        header_columns = get_header_from_array(nono_answer.T)
        header = Header(header_rows, header_columns)
        nonogram = Nonogram(nono_id, nono_name, header, nono_answer)
        nono_db.write_nonogram_to_db(nonogram)
Exemplo n.º 2
0
 def __init__(self):
     self.nonogram = Nonogram()
     self.rows = self.nonogram.get_row_constraints()
     self.col = self.nonogram.get_column_constraints()
     self.row_length = len(self.rows)
     self.col_length = len(self.col)
     # define a state 
     self.state = State(self.rows, self.col)
     # get permutations from nonogram.py (attempt 1)
     self.col_permutations = self.hash_col_permutations()
     self.row_permutations = self.hash_row_permutations() 
     self.traversed = 0 
     self.all_created_nodes = 0 
Exemplo n.º 3
0
def test_init_overlap():
    rows = [[1, 1], [5], [5], [3], [1]]
    cols = [[2], [4], [4], [4], [2]]

    nono = Nonogram(rows, cols)
    e = nono.EMPTY
    u = nono.UNKNOWN
    f = nono.FILLED
    answer = [[u, u, u, u, u], [f, f, f, f, f], [f, f, f, f, f],
              [u, f, f, f, u], [u, u, u, u, u]]

    s = Solver(nono)
    s.initial_overlaps()

    assert nono.board == answer
Exemplo n.º 4
0
 def init_games(self):
     try:
         loaded_data = ast.literal_eval(self.window['-LOADED_DATA-'].get())
         if not isinstance(loaded_data, list):
             raise ValueError()
         self.games = []
         for id in loaded_data:
             if not isinstance(id, int):
                 raise ValueError()
             nonogram = Nonogram(self.games_queue)
             nonogram.load_from_db(id)
             self.games.append(nonogram)
     except (ValueError, SyntaxError):
         sg.popup_error('Entered data incorrect')
     self.window['-NO_OF_GAMES-'].update(str(len(self.games)))
def initialize_cells(my_image):
    width = my_image.shape[1] * cell_width
    height = my_image.shape[0] * cell_width
    nonogram = Nonogram(width, height, cell_width)
    for i in range(cell_width, height + cell_width, cell_width):
        for j in range(cell_width, width + cell_width, cell_width):
            if my_image[(i - cell_width) // cell_width,
                        (j - cell_width) // cell_width] == 0:
                color = BLACK
            else:
                color = WHITE
            cell = Cell(((j - cell_width) // cell_width,
                         (i - cell_width) // cell_width), j, i, color,
                        cell_width)
            nonogram.add_cell(cell)
    return nonogram, width, height
Exemplo n.º 6
0
def random_nonogram(row_count, col_count):
    cell_count = row_count * col_count

    # nonograms with half of the cells colored are the hardest
    colored_cell_count = np.random.binomial(cell_count, 0.5)

    fields = list(itertools.product(range(row_count), range(col_count)))

    colored_fields = random.sample(fields, k=colored_cell_count)

    nonogram = Nonogram(row_count, col_count, colored_cells=colored_fields)

    nonogram.calculate_descriptors()
    nonogram.reset_cells()

    if nonogram.solve():
        return nonogram
    else:
        return random_nonogram(row_count, col_count)
Exemplo n.º 7
0
    def __init__(self, gui_queue, filename=None, db_id=None):
        self.main_gui_queue = gui_queue

        if filename is not None or db_id is not None:
            self.game = Nonogram()
            if filename is not None:
                self.game.load_from_file(filename)
            else:
                self.game.load_from_db(db_id)
        else:
            raise ValueError("GUIGame object wasn't initialized!")

        self.game_width, self.game_height = 0, 0
        self.BOX_WIDTH, self.BOX_HEIGHT = 0, 0

        # window sizes related variables
        self.WINDOW_SIZE_X = 500  # initial width of the window
        self.WINDOW_SIZE_Y = 500  # initial height of the window

        self.stored_size = (0, 0)  # width and height of the last drawn window
        self.reload_size = True  # boolean for checking if the window needs to be redrawn due to window resizing

        self.TIP_SIZE = 150  # widht (for rows) or height (for columns) of box containing hints

        # variables storing object ids of hints/board
        self.row_hint_ids = [
        ]  # array storing IDs of drawn objects of hints for rows
        self.col_hint_ids = [
        ]  # array storing IDs of drawn objects of hints for columns

        # init display variables
        self.layout = None  # layout of current window
        self.window = None  # pointer to window object
        self.puzzle = None  # pointer to window fragment containing puzzle tiles
        self.row_hints = None  # pointer to window fragment containing hints for rows
        self.col_hints = None  # pointer to window fragment containing hints for columns

        self.queue = queue.Queue()
        self.threads_id = []
Exemplo n.º 8
0
from nonogram import Nonogram
from solver import Solver

rows = [[1, 1], [5], [5], [3], [1]]
cols = [[2], [4], [4], [4], [2]]

nono = Nonogram(rows, cols)
s = Solver(nono, False)
s.solve()

print(nono.verify())
print(nono)

rows = [[1, 2, 3], [3, 1], [4, 2], [1, 3], [1, 2, 3]]
cols = [[1, 3], [2], [3], [3, 1], [1], [1], [1, 2], [2, 2], [1, 2], [1]]

nono = Nonogram(rows, cols)
s = Solver(nono, False)
s.solve()

print(nono.verify())
print(nono)

rows = [[2, 4, 1, 1], [1, 2, 1], [2, 1, 1, 2, 1], [3, 5, 1], [1, 1, 2, 1, 1],
        [1, 2, 1, 1, 3], [1, 1, 1, 2, 3], [1, 1, 1, 1, 1, 1, 1],
        [2, 3, 2, 1, 1], [1, 2, 6], [2, 1, 1, 1, 2, 2], [2, 1, 1, 1, 1, 1],
        [1, 1, 3, 1, 1, 1], [1, 1, 1, 1, 2, 1], [1, 1, 7, 1]]
cols = [[1, 3, 7], [1, 2, 3, 2], [4, 1, 1, 1], [1, 1, 3, 1], [4, 1, 1, 1, 1],
        [1, 1, 2, 1, 3], [1, 3, 1, 2, 1], [1, 3, 2, 1, 1], [1, 4], [5, 1],
        [3, 2, 3, 2], [4, 1, 2], [5, 1], [2, 2, 2], [1, 11]]
Exemplo n.º 9
0
from nonogram import Square, Nonogram

col_num = [[2], [1, 1], [1, 2], [1, 1], [2]]
row_num = [[1], [1, 1], [1, 1], [1, 1, 1], [1]]

n = Nonogram(row_num, col_num)

n.print_nonogram()

Exemplo n.º 10
0
class GeneticAlgorithm(object):
    global file
    file = open('output.txt', 'w')
    # instance of nonogram board
    global nonogram, population, fitness, ROWS, COLUMNS, ROW_COUNT, COLUMN_COUNT, POPSIZE, MUTATIONPROB, CROSSOVERPROB
    nonogram = Nonogram()
    population = []
    fitness = []

    ROWS = nonogram.get_row_constraints()
    COLUMNS = nonogram.get_column_constraints()
    ROW_COUNT = len(ROWS)
    COLUMN_COUNT = len(COLUMNS)

    POPSIZE = 300
    MUTATIONPROB = None
    CROSSOVERPROB = 75

    # generate random population of suitable solutions for nonogram
    def generate_population(self):
        pop = []
        for i in range(0, POPSIZE):
            state = nonogram.get_random_state(ROWS, COLUMNS)
            # get solution generated based on row constraints
            pop.append(state[0])
        return pop

    # evaluate the fintness of each solution in the population
    def evaluate_fitness(self, pop):
        fit = []
        # print pop
        for sol in pop:
            fit.append(nonogram.check_all_col(sol))
        return fit

    '''1ST APPROACH'''

    # create a new population by repeating
    # selection, crossover, mutation, accepting
    def create_new_population_1(self, pairs):
        pop = []
        # create a new population by repeating
        # selection, crossover, mutation, accepting (placing new offspring in new pop)
        parents = self.selection(pairs)
        while len(pop) <= POPSIZE:
            cross = self.crossover(parents)
            offspring = self.mutation(cross)
            # place new offspring in a new population
            pop.append(offspring)

        print("PARENTS ARE\n")
        print nonogram.print_state(parents[0])
        print("\n\n")
        print nonogram.print_state(parents[1])
        print("\n\n")

        # return new generated population
        return pop

    '''2ND APPROACH'''

    # create a new population by repeating
    # selection, crossover, mutation, accepting
    def create_new_population_2(self, pairs):
        pre_pop = []
        # create a new population by repeating
        # selection, crossover, mutation, accepting (placing new offspring in new pop)

        # select best individuals based on their fitness
        chosen = self.selection_2(pairs)
        chosen = sorted(chosen, key=operator.attrgetter('fitness'))
        pre_pop.append(chosen[0].get_state())
        pre_pop.append(chosen[1].get_state())
        # the rest crossover
        cross = self.crossover_2(chosen[2:])
        pre_pop.extend(cross)

        # print pre_pop

        # mutate the whole pre_pop
        post_pop = []
        for i in range(0, len(pre_pop)):
            offspring = self.mutation(pre_pop[i])
            # place new offspring in a new population
            post_pop.append(offspring)

        # '''WRITING TO FILE'''
        # file.write("BEST 2 ARE\n")
        # file.write(nonogram.print_state(chosen[0].get_state()))
        # file.write(str(chosen[0].get_fit()))
        # file.write("\n\n")
        # file.write(nonogram.print_state(chosen[1].get_state()))
        # file.write(str(chosen[1].get_fit()))
        # file.write("\n\n")

        print("BEST 2 ARE\n")
        print nonogram.print_state(chosen[0].get_state())
        print str(chosen[0].get_fit())
        print("\n\n")
        print nonogram.print_state(chosen[1].get_state())
        print(str(chosen[1].get_fit()))
        print("\n\n")

        # return new generated population
        return post_pop

    # use roulette wheel to select best solutions from a population according to their fitness
    # the better fitness, the bigger chance to be selected
    def selection_2(self, pairs):
        sum_fit = 0
        # store fitness in an array
        fit_array = []
        for i in pairs:
            sum_fit += i.get_fit()
            fit_array.append(i.get_fit())
        # print "sum fit is", sum_fit
        fit_array.reverse()

        chosen = []
        fitness_function = []
        index = 0
        for j in fit_array:
            fit_val = j
            # print "fit val is", fit_val
            fitness_function.append(range(index, index + fit_val))
            index += fit_val
        # print fitness_function

        for k in range(0, POPSIZE):
            probability = random.randint(0, sum_fit)
            for a in range(0, len(fitness_function)):
                if probability in fitness_function[a]:
                    chosen.append(pairs[a])
        # print len(chosen)
        # print chosen
        return chosen

    # with a crossover probability cross over the parents to form 2 new offsprings
    # return a list of new offsprings
    def crossover_2(self, parents):
        index_i = 0
        index_j = 1
        # list of offsprings to return
        list = []
        while index_i < len(parents) and index_j < len(parents):
            # generate a random probability
            probability = random.randint(0, 100)
            if probability < CROSSOVERPROB:
                # generate a random crossover point
                crossover_point = random.randint(0, ROW_COUNT)
                # copy everything before this point from parent 1 and after this point from parent 2
                offspring1 = []
                offspring2 = []
                # get states of parents
                state1 = parents[index_i].get_state()
                state2 = parents[index_j].get_state()

                for i in range(0, crossover_point):
                    offspring1.append(state1[i])
                    offspring2.append(state2[i])
                for j in range(crossover_point, ROW_COUNT):
                    offspring1.append(state2[j])
                    offspring2.append(state1[j])
                list.append(offspring1)
                list.append(offspring2)
            else:
                list.append(parents[index_i].get_state())
                list.append(parents[index_j].get_state())
            index_i += 2
            index_j += 2
        return list

    '''1ST APPROACH'''

    # select 2 solutions from a population according to their fitness
    # the better fitness, the bigger chance to be selected
    def selection(self, pairs):
        sorted_pairs = sorted(pairs, key=operator.attrgetter('fitness'))
        sol1 = sorted_pairs[0]
        sol2 = sorted_pairs[1]

        # '''WRITING TO FILE'''
        # file.write("PARENTS ARE\n")
        # file.write(nonogram.print_state(sol1.get_state()))
        # file.write(str(sol1.get_fit()))
        # file.write("\n")
        # file.write(nonogram.print_state(sol2.get_state()))
        # file.write(str(sol2.get_fit()))
        # file.write("\n")

        # list of 2 chosen solutions
        chosen = [sol1.get_state(), sol2.get_state()]
        return chosen

    # with a crossover probability cross over the parents to form a new offspring
    def crossover(self, parents):
        # generate a random probability
        probability = random.randint(0, 100)
        if probability < CROSSOVERPROB:
            # generate a random crossover point
            crossover_point = random.randint(0, ROW_COUNT)

            # copy everything before this point from parent 1 and after this point from parent 2
            offspring = []
            for i in range(0, crossover_point):
                offspring.append(parents[0][i])
            for j in range(crossover_point, ROW_COUNT):
                offspring.append(parents[1][j])
        else:
            offspring = parents[0]
        return offspring

    # with a mutation probability mutate new offspring at each locus (position in chromosome)
    def mutation(self, offspring):
        # new mutated offspring
        new = []
        for i in range(0, ROW_COUNT):
            # 20% chance a row get mutated
            probability = random.randint(0, 100)
            if probability <= MUTATIONPROB:
                # print "row" + str(i) + " get mutated"
                # print offspring[i]
                rand = nonogram.get_random_row(i)
                # print "became"
                # print rand
                new.append(rand)

            else:
                new.append(offspring[i])
        return new

    # return solution if all constraints are met
    def check_goal(self, pop):
        for sol in pop:
            if nonogram.check_all_col(sol) is 0:
                return sol
        return None

    # method to pair each solution with its fitness
    def pair_up(self, pop, fitness):
        pairs = []
        for i in range(0, len(pop)):
            solution = Solution(pop[i], fitness[i])
            pairs.append(solution)
        return pairs

    # main method
    def __init__(self):
        if len(sys.argv) == 1:
            print "Choose an approach: greedy or proper"
            print "'python genetic.py greedy' or 'python genetic.py proper'"
            return

        if str(sys.argv[1]) == "greedy":
            global MUTATIONPROB
            MUTATIONPROB = 30

        elif str(sys.argv[1]) == "proper":
            global MUTATIONPROB
            MUTATIONPROB = 5

        start = time.time()

        global population, fitness
        # STEP 1: generate random population
        population = self.generate_population()

        # loop to return the best solution in current population
        flag = None
        counter = 0
        while flag is None:
            counter += 1
            string = "Generation " + str(counter) + "\n"
            # file.write(string)
            # STEP 2: evaluate fitness of each sol in population
            fitness = self.evaluate_fitness(population)

            # pair each solution with its fitness
            pairs = self.pair_up(population, fitness)

            # STEP 3: create a new population

            if str(sys.argv[1]) == "greedy":
                population = self.create_new_population_1(pairs)
            elif str(sys.argv[1]) == "proper":
                population = self.create_new_population_2(pairs)

            # STEP 4: check if the end condition is satisfied
            flag = self.check_goal(population)
        end = time.time()
        runtime = end - start
        '''WRITING TO FILE'''
        # file.write("SOLUTION IS \n")
        # file.write(nonogram.print_state(flag))
        # file.write("\n")
        # file.write("\nRUNTIME IS")
        # file.write(str(runtime))
        print "RUNTIME IS %s" % runtime
        print "Number of generations: %s" % counter
        print(nonogram.print_state(flag))
Exemplo n.º 11
0

if __name__ == '__main__':
    #file_name = "lost.txt"
    file_name = "beach.txt"
    #file_name = "artist.txt" # faster with match_forwards than match backwards. NFA is of course the fastest
    #file_name = "balance.txt"
    #file_name = "warship.txt"
    #file_name = "bear.txt"

    # the webpbn puzzles are super hard
    #file_name = "webpbn-01611-For  merilinnuke" +'.txt'

    file_name = 'puzzles/' + file_name
    runs_row, runs_col, solution = decode(file_name)
    puzzle = Nonogram(runs_row, runs_col)

    find_solution = True
    make_guess = True
    # set solution
    if solution and not find_solution:  # the webpbn files have solutions
        print("setting solution ...")
        grid_sol = decode_solution(solution, len(runs_row), len(runs_col))
        puzzle.set_grid(grid_sol)

    ##solve game
    if find_solution:
        start_time = time.time()
        grid = solve_fast(puzzle, make_guess=make_guess)
        #grid = solve(puzzle)
        end_time = time.time()
Exemplo n.º 12
0
    five_strip1 = [(
        1,
        2,
    ) + 6 * (1, ), (2, ) + 6 * (1, ) + (2, ), (1, ), (2, 1, 1, 2, 1, 2, 1),
                   (1, 1, 1, 2, 1, 1, 1)]
    three_strip = [(1, ), (18, ), (1, 1)]
    five_strip2 = [(1, 2, 1, 2, 1, 1, 2), (1, 1, 1, 2, 1, 1, 1), (1, ),
                   (2, 1, 1, 2, 1, 2, 1), (1, 1, 1, 2, 1, 1, 1)]
    two_strip = [(1, 2, 1, 2, 1, 1, 2), (1, 1, 1, 2, 1, 1, 1)]
    #r_row = five_strip1 + three_strip + five_strip2 + three_strip + two_strip
    #r_col = [(3,2,3,2,1),(1,1,2,1,1,2,1)] + [(1,)*7 for _ in range(15)] + [(2,1,3,1,3)]
    ## small but constraint propagation alone won't solve
    #r_row = [(4,),(4,),(1,),(1,1),(1,)] # not possible to solve with this solver
    #r_col = [(1,),(2,1),(2,1),(2,1),(1,1)] # not possible to solve with this solver

    puzzle = Nonogram(r_row, r_col)

    ## set solution
    #puzzle.set_grid(solution)

    ## solve game
    start_time = time.time()
    grid = solve(puzzle)
    puzzle.set_grid(grid)
    end_time = time.time()

    puzzle.show_grid(show_instructions=True, to_file=False, symbols="x#.?")

    print(puzzle.is_complete(), "{:.2f}%%".format(puzzle.progress * 100))
    print("time taken: {:.5f}s".format(end_time - start_time))
    print("solved with {} guesses".format(puzzle.guesses))
Exemplo n.º 13
0
from config import NUM_COLS, NUM_ROWS, pickle_unsolved_file_path
from nonogram import Nonogram
import pickle

csv_path = '../data/hanjie.csv'

save = True  # True -> save to file, False -> load file

# saves the Nonograms in csv_path to a pickled list of unsolved Nonograms
with open(csv_path) as csvfile:
    readCSV = csv.reader(csvfile, delimiter=',')
    filtered = [
        {
            'title': row[2],
            'number': int(row[3]),
            'solution': row[4],
            'rows': row[6],
            'cols': row[7]
        } for i, row in enumerate(readCSV)
        if i > 0 and int(row[0]) == NUM_COLS and int(row[1]) == NUM_ROWS
    ]
    nonograms = [
        Nonogram(d['rows'], d['cols'], d['title'], d['number'], d['solution'])
        for d in filtered
    ]
    for nono in nonograms:
        print(nono)

with open('../' + pickle_unsolved_file_path, 'wb') as f:
    pickle.dump(nonograms, f)
Exemplo n.º 14
0
import tkinter as tk
from tkinter import messagebox, Button
from nonogram import Nonogram
from image import Img
import numpy as np

# #####  DEFINE GRID HERE  ###### #
ROWS = 10
COLS = 10
# Visual size of grid box
GRID_SIZE = 40

# Initialize
nonogram = Nonogram()
img = Img()
tiles = [[0 for _ in range(COLS)] for _ in range(ROWS)]


def create_grid(event=None):
    w = grid.winfo_width()  # Get current width of canvas
    h = grid.winfo_height()  # Get current height of canvas
    grid.delete('grid_line')  # Will only remove the grid_line

    # Creates all vertical lines at intevals of 100
    for i in range(0, w, GRID_SIZE):
        grid.create_line([(i, 0), (i, h)], tag='grid_line')

    # Creates all horizontal lines at intevals of 100
    for i in range(0, h, GRID_SIZE):
        grid.create_line([(0, i), (w, i)], tag='grid_line')
Exemplo n.º 15
0
    def event_handler(self):
        event, values = self.window.read(timeout=100)

        # handle queue from other GUI windows
        while len(self.queue) > 0:
            self.read_queue(self.queue[-1])
            self.queue.pop(-1)

        if event in (None, ):
            return False

        if event in '-INIT_GAMES-':
            try:
                loaded_data = ast.literal_eval(
                    self.window['-LOADED_DATA-'].get())
                if not isinstance(loaded_data, list):
                    raise ValueError()
                self.games = []
                for id in loaded_data:
                    if not isinstance(id, int):
                        raise ValueError()
                    nonogram = Nonogram()
                    nonogram.load_from_db(id)
                    self.games.append(nonogram)
            except (ValueError, SyntaxError):
                sg.popup_error('Entered data incorrect')

        if not self.game_gui_opened and event in ('...file', '-FILE_LOAD-'):
            self.game_gui = GUIGame(self.queue, 'test.txt')
            self.game_gui.set_layout()
            self.game_gui_opened = True

        if not self.game_gui_opened and event in ('...database', '-DB_LOAD-'):
            popup_text = sg.popup_get_text('Choose puzzle ID (1-9800)',
                                           'Load puzzle from database')
            if popup_text:
                puzzle_id = int(popup_text)
                if 0 < puzzle_id < 9801:
                    self.game_gui = GUIGame(self.queue, db_id=puzzle_id)
                    self.game_gui.set_layout()
                    self.game_gui_opened = True

                    self.game_gui.reload()
                    self.game_gui.redraw_hints(self.game_gui.game.rows,
                                               self.game_gui.game.cols)
                    self.game_gui.redraw()

        if not self.database_gui_opened and event == 'Browse database':
            self.database_gui = GUIDatabase(self.queue)
            self.database_gui.set_layout()
            self.database_gui_opened = True

        if self.game_gui_opened and not self.game_gui.event_handler():
            self.game_gui = None
            self.game_gui_opened = False

        if self.database_gui_opened and not self.database_gui.event_handler():
            self.database_gui = None
            self.database_gui_opened = False

        return True