sudoku.py

Created by anaali

Created on May 09, 2023

6.41 KB

𝗦𝘂𝗱𝗼𝗸𝘂


Python Game 🎮 v1.01 for Numworks, all models.

By Ilana R. & Vincent ROBERT avril 2023.

Un projet libre réalisé dans la cadre de l'enseignement de spécialité NSI.

Learn more about Sudoku on: nsi.xyz/sudoku (FR)

Changelog

Convert v1.0 - 30/04/2023:
- Initial version


from random import choice,randint, randrange
from math import*
from kandinsky import fill_rect as rect, draw_string as txt 
from ion import *

# Sudoku 1.0 NumWorks, 27.04.2023
# Par Ilana R. & Vincent ROBERT
# https://nsi.xyz/sudoku   

def reset():
  return [[0 for i in range(9)] for j in range(9)]

def ligne(x):
  return [i for i in range(1,10) if i in board[x]]

def colonne(y):
  return [board[i][y] for i in range(9) if board[i][y] != 0]

def bloc(x, y):
  nums = []
  for i in range(x//3*3, x//3*3+3):
    for j in range(y//3*3, y//3*3+3):
      if board[i][j] != 0:
        nums.append(board[i][j])
  return nums

def possible(x, y):
  return [i for i in range(1,10) if i not in ligne(x)+colonne(y)+bloc(x,y)]
  
def check():
  c=0
  for i in range (9):
    for j in range (9):
      if board[i][j]!=0:
        c+=1
  return c==81
  
def genere_board():
  global board
  board = reset()
  x = y = essai = 0
  while x!=9:
    essai += 1
    if essai ==42: 
      x = essai =0
      board = reset()
    y = 0
    while y!=9:
      if possible(x,y)==[]:
        board[x] = [0 for i in range(9)]
        y = 8
        x = x-1
      else:
        board[x][y] = choice(possible(x,y))
      y +=1
    x +=1
  return board
  
def couleur(x,y,p=0):
  if (x//3 + y//3) %2 == 1:
    return (180-42*p,140-35*p,225)
  else:
    return (255,200-30*p,125-85*p)
    
def grille():
   for x in range(9):
    for y in range(9):
      rect(2+x*(22), 2+y*(22), 20, 20, couleur(x,y,0))

def dessine_nb(x,y,nb,mode):
  txt(str(nb),x*22+7,y*22+3,"black",couleur(x,y,mode))
   
def is_valid(x,y,nb):
  global vie
  if board[x][y]==0:
    if nb == solution[x][y]:
      dessine_nb(x,y,nb,1)
      board[x][y]=nb
    else:
      vie-=1
      perdre_vie()
      
def suppr(nb):
  for i in range(nb):
    x, y = randint(0,8), randint(0,8)
    while board[x][y] == 0:
      x, y = randint(0,8), randint(0,8)
    board[x][y] = 0
    
def aide(x,y):
  rect(200,155 ,200,20,(255,)*3)
  nbs = possible(x, y)  
  if board[x][y]==0:
    for i in range(len(nbs)):
      txt(str(nbs[i]), 265 + i * 20- len(nbs) *10, 155)
      if nbs[i]!=nbs[-1]:
        txt(",", 275+ i * 20 - len(nbs) *10, 155)
  else:
    txt("Full", 240,155)

def coeur (x,y):
  col=(255,80 ,0)
  rect(x+3,y+0,3,3, col)
  rect(x+15,y+0,3,3,col)
  rect(x+0,y+3,9,3,col)
  rect(x+12,y+3,9,3,col)
  rect(x+0,y+6,21,3,col)
  rect(x+3,y+9,15,3,col)
  rect(x+6,y+12,9,3,col)
  rect(x+9,y+15,3,3,col)
  
def perdre_vie():
    rect(272 - vie *25, 5, 21, 21, (255,) * 3)
    
def affichage_nb():
  for x in range (9):
    for y in range (9):
      if board[x][y] != 0 :
        dessine_nb(x,y,board[x][y],0)
        
def surbrillance(x, y, mode):
  for i in range(9):
    rect(2+i*(22), 2+y*(22), 20, 20, couleur(i, y, mode))
    rect(2+x*(22), 2+i*(22), 20, 20, couleur(x, i, mode))
    if board[i][y] != 0:
      dessine_nb(i, y, board[i][y], mode)
    if board[x][i] != 0:
      dessine_nb(x, i, board[x][i], mode)
  for i in range(x//3*3, x//3*3+3):
    for j in range(y//3*3, y//3*3+3):
      rect(2+i*(22), 2+j*(22), 20, 20, couleur(i, j, mode))
      if board[i][j] != 0:
        dessine_nb(i, j, board[i][j], mode)
        
def draw_level(s=0):
  txt("Find", 237,35,(42+106*s,42+71*s,42+180*s))
  txt("< "*s+ "  "*(s==0) + str(lvl)+ " >"*s + "  "*(s==0), 225, 50,(42,)*3)

def draw_help(s=0):
  txt("Help", 237,80,(42+106*s,42+71*s,42+180*s))
  txt("< "*s+"  "*(s==0)+str(s_help)+ " >"*s + "  "*(s==0), 222,100,(42,)*3)
      
def wait(buttons=(0,1,2,3,4,52,30,31,32,36,37,38,42,43,44)):
  while True:
    for i in buttons:
      if keydown(i):
        while keydown(i): True 
        return i
#init
vie = 3    
rect(0, 200, 320, 22, (148, 113, 222))
txt( " chargement en cours... ", 50, 202, (242,)*3, (148, 113,222))
genere_board()
grille()
txt( "Code by nsi.xyz/sudoku", 50, 202, (242,)*3, (148, 113,222))
coeur(222,5), coeur(247,5), coeur(272,5)
lvl,s_help=32,"Off"
draw_level(1)
draw_help(0)

options = [32, 42, 52, 62]
diff = None
pos = 0

def select_diff():
  txt(str(options[pos]), 246, 50,(42,)*3)
  
while diff is None:
  key_pressed= wait()
  if key_pressed == 3: # fleche droite
    pos = (pos + 1) % len(options)
    select_diff()
  elif key_pressed == 0: # fleche gauche
    pos = (pos - 1) % len(options)
    select_diff()
  elif key_pressed in (4,52): # touche OK caclu+ordi
    lvl= options[pos]
    break
  
draw_level(0)
draw_help(1)
options = ['Off', 'On ']
help = None
pos = 0

def select_help():
  txt(options[pos], 243, 100,(42,)*3)

while help is None:
  key_pressed = wait()
  if key_pressed == 3: # fleche droite
    pos = (pos + 1) % len(options)
    select_help()
  elif key_pressed == 0: # fleche gauche
    pos = (pos - 1) % len(options)
    select_help()
  elif key_pressed in (4,52): # touche OK caclu+ordi
    s_help = options[pos]
    break

draw_help(0)

if s_help=="On ":
  txt("Valid",230, 125,(42,)*3)
  txt("numbers",225, 140,(42,)*3)
 
solution = [row.copy() for row in board]
suppr(lvl)  
affichage_nb()
draw_level(0)
pos = [4,4]
pmax = (9,9)

def deplacement():
  x, y = pos_old
  surbrillance(x,y,0)
  x, y = pos 
  surbrillance(x,y,1)
  rect(2+x*(20+2), 2+y*(20+2), 20, 20,couleur(x,y,2))
  if board[x][y]!=0:
    dessine_nb(x,y,board[x][y],2)
    
while True:
  if vie==0:
    txt("Perdu!",230,5,(42,)*3,(255,)*3)
    break
  if check()==True :
    txt("  Gagné!  ",210,5,(42,)*3,(255,)*3)
    break
  key_pressed = wait()
  pos_old = list(pos) 
  if key_pressed == 1:  # fleche haut
    pos[1] = (pos[1]-1) % pmax[1]
    if  s_help=="On ":
      aide(pos[0],pos[1])
  elif key_pressed == 2: # fleche bas
    pos[1] = (pos[1]+1) % pmax[1]
    if  s_help=="On ":
      aide(pos[0],pos[1])
  elif key_pressed == 3: #fleche droite
     pos[0] = (pos[0]+1) % pmax[0]
     if  s_help=="On ":
       aide(pos[0],pos[1])
  elif key_pressed == 0: # fleche gauche
    pos[0] = (pos[0]-1) % pmax[0]
    if  s_help=="On ":
      aide(pos[0],pos[1])
  elif  key_pressed == 42: #1
    is_valid(pos[0],pos[1],1)
  elif  key_pressed == 43: #2
    is_valid(pos[0],pos[1],2)
  elif  key_pressed == 44: #3
    is_valid(pos[0],pos[1],3)
  elif  key_pressed == 36: #4
    is_valid(pos[0],pos[1],4)
  elif  key_pressed == 37: #5
    is_valid(pos[0],pos[1],5)
  elif  key_pressed == 38: #6
    is_valid(pos[0],pos[1],6)
  elif key_pressed == 30: #7
    is_valid(pos[0],pos[1],7)
  elif  key_pressed == 31: #8
    is_valid(pos[0],pos[1],8)
  elif  key_pressed == 32: #9
    is_valid(pos[0],pos[1],9)
  if key_pressed not in (42, 43 ,44 ,36 ,37 ,38 ,30 ,31, 32) :    
    deplacement()

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.