예제 #1
0
def generate_shakashaka(height, width, verbose=False):
    generated = generate_problem(lambda problem: solve_shakashaka(height, width, problem),
                                 builder_pattern=ArrayBuilder2D(height, width, [None, -1, 0, 1, 2, 3, 4],
                                                                default=None, disallow_adjacent=True),
                                 clue_penalty=lambda problem: count_non_default_values(problem, default=None, weight=6),
                                 verbose=verbose)
    return generated
예제 #2
0
파일: nurikabe.py 프로젝트: bay-puz/cspuz
def generate_nurikabe(height,
                      width,
                      min_clue=None,
                      max_clue=10,
                      verbose=False):
    disallow_adjacent = []
    for dy in range(-2, 3):
        for dx in range(-2, 3):
            if (dy, dx) != (0, 0):
                disallow_adjacent.append((dy, dx))
    generated = generate_problem(
        lambda problem: solve_nurikabe(
            height, width, problem, unknown_low=min_clue),
        builder_pattern=ArrayBuilder2D(height,
                                       width, [-1, 0] +
                                       list(range(min_clue or 1, max_clue)),
                                       default=0,
                                       disallow_adjacent=True,
                                       symmetry=False),
        clue_penalty=lambda problem: count_non_default_values(
            problem, default=0, weight=5),
        verbose=verbose)
    if generated is None:
        return None
    else:
        return resolve_unknown(height, width, generated, unknown_low=min_clue)
예제 #3
0
파일: simplegako.py 프로젝트: bay-puz/cspuz
def generate_simplegako(height, width, verbose=True, disallow_adjacent=False, symmetry=False, hard=False):
    pattern = range(max(height, width) + 1) if hard else range(height + width - 1)

    def pretest(problem):
        if not hard:
            return True

        for y in range(height):
            for x in range(width):
                if problem[y][x] > 0:
                    for i in range(1, width - x):
                        if problem[y][x+i] == problem[y][x]:
                            return False
                    for i in range(1, height - y):
                        if problem[y+i][x] == problem[y][x]:
                            return False

        mean = (height + width) // 2
        count_big = 0
        for y in range(height):
            for x in range(width):
                if problem[y][x] > 2:
                    count_big += 1
        return (count_big < mean)

    generated = generate_problem(lambda problem: solve_simplegako(height, width, problem),
                                builder_pattern=ArrayBuilder2D(height, width, pattern, default=0,
                                disallow_adjacent=disallow_adjacent, symmetry=symmetry),
                                clue_penalty=lambda problem: count_non_default_values(problem, default=0, weight=5),
                                pretest=pretest, verbose=verbose)
    return generated
예제 #4
0
def generate_yinyang(height,
                     width,
                     disallow_adjacent=False,
                     no_clue_on_circumference=False,
                     verbose=False):
    def pretest(problem):
        for y in range(height):
            if problem[y][0] != 0 or problem[y][-1] != 0:
                return False
        for x in range(width):
            if problem[0][x] != 0 or problem[-1][x] != 0:
                return False
        return True

    generated = generate_problem(
        lambda problem: solve_yinyang(height, width, problem),
        builder_pattern=ArrayBuilder2D(height,
                                       width,
                                       range(0, 3),
                                       default=0,
                                       disallow_adjacent=disallow_adjacent),
        clue_penalty=lambda problem: count_non_default_values(
            problem, default=0, weight=5),
        pretest=pretest if no_clue_on_circumference else None,
        verbose=verbose)
    return generated
예제 #5
0
def generate_slitherlink(height, width, symmetry=False, verbose=False):
    def no_neighboring_zero(problem):
        for y in range(height):
            for x in range(width):
                if problem[y][x] == 0:
                    for dy in range(-1, 2):
                        for dx in range(-1, 2):
                            y2 = y + dy
                            x2 = x + dx
                            if (dy, dx) != (
                                    0, 0
                            ) and 0 <= y2 < height and 0 <= x2 < width and problem[
                                    y2][x2] == 0:
                                return False
        return True

    generated = generate_problem(
        lambda problem: solve_slitherlink(height, width, problem),
        builder_pattern=ArrayBuilder2D(height,
                                       width,
                                       range(-1, 4),
                                       default=-1,
                                       symmetry=symmetry,
                                       disallow_adjacent=True),
        clue_penalty=lambda problem: count_non_default_values(
            problem, default=-1, weight=5),
        pretest=no_neighboring_zero,
        verbose=verbose)
    return generated
예제 #6
0
def generate_simpleloop(height, width, verbose):
    pivot = (random.randint(0, height - 1), random.randint(0, width - 1))

    def pretest(problem):
        parity = [0, 0]
        for y in range(height):
            for x in range(width):
                if problem[y][x] == 1:
                    continue
                a = (y + x) % 2 * 2 - 1
                if (y, x) != pivot:
                    parity[0] += a
                parity[1] += a
        return parity[0] == 0 or parity[1] == 0

    generated = generate_problem(
        lambda problem: solve_simpleloop(height, width, problem, pivot),
        builder_pattern=ArrayBuilder2D(height,
                                       width, [0, 1],
                                       default=0,
                                       disallow_adjacent=True),
        clue_penalty=lambda problem: count_non_default_values(
            problem, default=0, weight=10),
        pretest=pretest,
        verbose=verbose)
    if generated is None:
        return None
    num_pass = 0
    for y in range(height):
        for x in range(width):
            if (y, x) != pivot and generated[y][x] == 0:
                num_pass += 1
    y, x = pivot
    generated[y][x] = 1 - num_pass % 2
    return generated
예제 #7
0
def generate_doppelblock(n, verbose=False):
    max_sum = (n - 2) * (n - 1) // 2
    generated = generate_problem(lambda problem: solve_doppelblock(n, problem[0], problem[1]),
                                 builder_pattern=ArrayBuilder2D(2, n, [-1] + list(range(0, max_sum + 1)), default=-1),
                                 clue_penalty=lambda problem: count_non_default_values(problem, default=-1, weight=10),
                                 verbose=verbose)
    return generated
예제 #8
0
파일: nurimisaki.py 프로젝트: bay-puz/cspuz
def generate_fillomino(height, width, verbose=False):
    generated = generate_problem(
        lambda problem: solve_nurimisaki(height, width, problem),
        builder_pattern=ArrayBuilder2D(height, width, [-1, 0], default=-1),
        clue_penalty=lambda problem: count_non_default_values(
            problem, default=-1, weight=7),
        verbose=verbose)
    return generated
예제 #9
0
파일: masyu.py 프로젝트: bay-puz/cspuz
def generate_masyu(height, width, symmetry=False, verbose=False):
    generated = generate_problem(
        lambda problem: solve_masyu(height, width, problem),
        builder_pattern=ArrayBuilder2D(height,
                                       width, [0, 1, 2],
                                       default=0,
                                       symmetry=symmetry),
        clue_penalty=lambda problem: count_non_default_values(
            problem, default=0, weight=10),
        verbose=verbose)
    return generated
예제 #10
0
파일: firefly.py 프로젝트: bay-puz/cspuz
def generate_firefly(height, width, min_clue=0, max_clue=5, verbose=False):
    cand = ['..']
    for d in ['^', 'v', '<', '>']:
        cand.append(d + '?')
        for i in range(min_clue, max_clue + 1):
            cand.append(d + str(i))
    generated = generate_problem(
        lambda problem: solve_firefly(height, width, problem),
        builder_pattern=ArrayBuilder2D(height, width, cand, default='..'),
        clue_penalty=lambda problem: count_non_default_values(
            problem, default='..', weight=10),
        verbose=verbose)
    return generated
예제 #11
0
def generate_fillomino(height,
                       width,
                       checkered=False,
                       disallow_adjacent=False,
                       symmetry=False,
                       verbose=False):
    generated = generate_problem(
        lambda problem: solve_fillomino(
            height, width, problem, checkered=checkered),
        builder_pattern=ArrayBuilder2D(height,
                                       width,
                                       range(0, 9),
                                       default=0,
                                       disallow_adjacent=disallow_adjacent,
                                       symmetry=symmetry),
        clue_penalty=lambda problem: count_non_default_values(
            problem, default=0, weight=5),
        verbose=verbose)
    return generated
예제 #12
0
파일: sudoku.py 프로젝트: bay-puz/cspuz
def generate_sudoku(n, max_clue=None, symmetry=False, verbose=False):
    size = n * n

    def pretest(problem):
        if max_clue is None:
            return True
        else:
            return count_non_default_values(problem, default=0,
                                            weight=1) <= max_clue

    generated = generate_problem(
        lambda problem: solve_sudoku(problem, n=n),
        builder_pattern=ArrayBuilder2D(size,
                                       size,
                                       range(0, size + 1),
                                       default=0,
                                       symmetry=symmetry),
        pretest=pretest,
        clue_penalty=lambda problem: count_non_default_values(
            problem, default=0, weight=5),
        verbose=verbose)
    return generated
예제 #13
0
파일: koutano.py 프로젝트: bay-puz/cspuz
def generate_koutano(height, width, hard=False, symmetry=False, verbose=False):
    pattern = list(range(1, height + width - 3))
    if not hard:
        pattern += [0, height + width - 2]

    def pretest(problem):
        if not hard:
            return True

        for y in range(height):
            count_hint = 0
            for x in range(width):
                count_hint += 1 if problem[y][x] > -1 else 0
            if count_hint > 2:
                return False
        for x in range(width):
            count_hint = 0
            for y in range(height):
                count_hint += 1 if problem[y][x] > -1 else 0
            if count_hint > 2:
                return False
        return True

    generated = generate_problem(
        lambda problem: solve_koutano(height, width, problem),
        builder_pattern=ArrayBuilder2D(height,
                                       width,
                                       pattern,
                                       default=-1,
                                       symmetry=symmetry,
                                       disallow_adjacent=hard),
        clue_penalty=lambda problem: count_non_default_values(
            problem, default=-1, weight=2),
        pretest=pretest,
        verbose=verbose)
    return generated
예제 #14
0
def generate_akari(height, width, no_easy=False, verbose=False):
    def pretest(problem):
        visited = [[False for _ in range(width)] for _ in range(height)]

        def visit(y, x):
            if not (0 <= y < height and 0 <= x < width and problem[y][x] == -2 and not visited[y][x]):
                return
            visited[y][x] = True
            visit(y - 1, x)
            visit(y + 1, x)
            visit(y, x - 1)
            visit(y, x + 1)
        n_component = 0
        for y in range(height):
            for x in range(width):
                if problem[y][x] == -2 and not visited[y][x]:
                    n_component += 1
                    visit(y, x)
        if n_component != 1:
            return False
        if not no_easy:
            return True
        for y in range(height):
            for x in range(width):
                if problem[y][x] >= 0:
                    n_adj = (1 if y > 0 and problem[y - 1][x] == -2 else 0) + (1 if x > 0 and problem[y][x - 1] == -2 else 0) + (1 if y < height - 1 and problem[y + 1][x] == -2 else 0) + (1 if x < width - 1 and problem[y][x + 1] == -2 else 0)
                    if problem[y][x] >= n_adj - 1:
                        return False
        return True

    pattern = [-2, -1, 1, 2] if no_easy else [-2, -1, 0, 1, 2, 3, 4]
    generated = generate_problem(lambda problem: solve_akari(height, width, problem),
                                 builder_pattern=ArrayBuilder2D(height, width, pattern, default=-2, symmetry=True),
                                 clue_penalty=lambda problem: count_non_default_values(problem, default=-2, weight=5),
                                 pretest=pretest, verbose=verbose)
    return generated