picross.py

Created by ilyas-r

Created on March 17, 2025

4.9 KB


from kandinsky import *
from ion import keydown
from random import choice, randint

X_OFFSET, Y_OFFSET = 100, 70
assets = {"m_f": "Grid by nsi.xyz/picross", "m_c_d": "Difficulty", "m_c_d_e": "Easy", "m_c_d_n": "Normal", "m_c_d_h": "Hard", "m_s_l": "Level", "m_s_s": "Score"}

solution = []
player_grid = []
row_hints = []
col_hints = []

cursor_x, cursor_y = 0, 0

dark_c = (42,)*3
light_c = (142,)*3
bright_c = (200,)*3
game_c = (148, 113, 222)
void_c = (255,)*3
state="IN_MENU"
ks=0

def generate_grid():
    global solution, row_hints, col_hints
    while 1:
        solution = [[0 for _ in range(5)] for _ in range(5)]
        for i in range(5):
            num_groups = randint(1, 3)
            remaining_cells = 5
            groups = []
            for _ in range(num_groups):
                max_group_size = remaining_cells - num_groups
                if max_group_size < 1:
                    continue
                group_size = randint(1, max_group_size)
                start_pos = randint(0, remaining_cells - group_size)
                groups.append((start_pos, start_pos + group_size))
                remaining_cells -= (group_size + 1)
            for start, end in groups:
                for j in range(start, end):
                    solution[i][j] = 1
        row_hints = [[len(group) for group in ''.join(map(str, row)).split('0') if group] for row in solution]
        col_hints = [[len(group) for group in ''.join(map(str, col)).split('0') if group] for col in zip(*solution)]
        if all(row_hints) and all(col_hints):
            break
    

def gui():
    rec(0, round(screen_height*0.9), screen_width, 22, game_c)
    txt(assets["m_f"], (screen_width//2 - 5*len(assets["m_f"])), round(screen_height*0.91), bright_c, game_c)

def draw_grid():
    fill_rect(0, 0, 320, 222, void_c)
    for i in range(5):
        for j in range(5):
            color = light_c if player_grid[i][j] else bright_c
            fill_rect(X_OFFSET + j * 20, Y_OFFSET + i * 20, 20-2, 20-2, color)
            
def update_grid(x, y):
    color = light_c if player_grid[y][x] else bright_c
    fill_rect(X_OFFSET + x * 20, Y_OFFSET + y * 20, 20-2, 20-2, color)
    

def draw_hints():
    i = 0
    for hint in row_hints:
        draw_string(' '.join(map(str, hint)), 20, Y_OFFSET + i * 20, dark_c)
        i += 1
    j = 0
    for hint in col_hints:
        for k in range(len(list(map(str, hint)))):
            draw_string(list(map(str, hint))[k], X_OFFSET + j * 20 + 5, 10+20*k, dark_c)
        j += 1


def extract_hints_from_grid(grid):
    hints = []
    for row in grid:
        hint = []
        count = 0
        for cell in row:
            if cell == 1:
                count += 1
            elif count > 0:
                hint.append(count)
                count = 0
        if count > 0:
            hint.append(count)
        hints.append(hint)
    return hints

def check_win(row, col, player):
    if extract_hints_from_grid(player) != row:
        return False
    transposed_grid = list(map(list, zip(*player)))
    if extract_hints_from_grid(transposed_grid) != col:
        return False
    return True


def move(e=0):
    color = light_c if player_grid[cursor_y][cursor_x] else bright_c
    fill_rect(X_OFFSET + cursor_x * 20, Y_OFFSET + cursor_y * 20, 20-2, 20-2, color if e else game_c)

def start():
    global cursor_x, cursor_y, state, player_grid, ks
    player_grid = [[0 for _ in range(5)] for _ in range(5)]
    generate_grid()
    draw_grid()
    draw_hints()
    state = "IN_GAME"
    last_key = False
    while state == "IN_GAME":
        if keydown(0) and last_key != 0:
            move(1)
            cursor_x -= 1
            cursor_x %= 5
            move()
            last_key = 0
        if keydown(3) and last_key != 3:
            move(1)
            cursor_x += 1
            cursor_x %= 5
            move()
            last_key = 3
        if keydown(1) and last_key != 1:
            move(1)
            cursor_y -= 1
            cursor_y %= 5
            move()
            last_key = 1
        if keydown(2) and last_key != 2:
            move(1)
            cursor_y += 1
            cursor_y %= 5
            move()
            last_key = 2
        if (keydown(4) or keydown(52)) and (last_key != 4 or last_key != 4):
            player_grid[cursor_y][cursor_x] = 1 - player_grid[cursor_y][cursor_x]
            update_grid(cursor_x, cursor_y)
            last_key = 4
        if not (keydown(0) or keydown(1) or keydown(2) or keydown(3) or keydown(4) or keydown(52)):
            last_key = None
        if check_win(row_hints, col_hints, player_grid):
            draw_string("Win!", 120, 200, game_c)
            state = "END"
            ks = 1
            break


def picross():
    global ks
    while not keydown(51):
        if state == "IN_MENU":
            start()
        if state == "END" and (keydown(4) or keydown(52)) and not ks:
            start()
        if not (keydown(4) or keydown(52)):
            ks = 0

picross()

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.