Compare commits
5 Commits
e1d06ea89b
...
0235cdff3e
| Author | SHA1 | Date | |
|---|---|---|---|
| 0235cdff3e | |||
| c99fca5d89 | |||
| 651af3bba3 | |||
| 1f3772db5b | |||
| 69ce9a0089 |
167
sudoku.py
Normal file
167
sudoku.py
Normal file
@@ -0,0 +1,167 @@
|
||||
from random import randint, shuffle # za generiranje naključnega sudokuja
|
||||
from copy import deepcopy # za kopiranje že rešenega sudokuja
|
||||
from time import time # za merjenje časa
|
||||
|
||||
|
||||
sudoku = [ # začnemo s praznim sudokujem
|
||||
[0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0],
|
||||
[0,0,0,0,0,0,0,0,0]
|
||||
]
|
||||
|
||||
|
||||
class GeneratorSudokuja:
|
||||
def veljavna(self, sudoku, stevilka, vrstica, stolpec): # funkcija, ki preveri veljavnost številke na določenem mestu, kjer sta vrstica in stolpec enaka i in j (j,i) = (x,y)
|
||||
for i in range(9):
|
||||
if stevilka == sudoku[vrstica][i] or stevilka == sudoku[i][stolpec] or stevilka == sudoku[3 * (vrstica//3) + i // 3][3 * (stolpec//3) + i % 3]:
|
||||
return False # če je številka enaka katerikoli izmed treh možnosti (v vrstici, v stolpcu ali pa v 3x3 mreži), funkcija vrne False
|
||||
return True # drugače True
|
||||
def generiraj(self, sudoku): # funkcija, ki generira sudoku
|
||||
for i in range(9):
|
||||
for j in range(9):
|
||||
if sudoku[i][j] == 0:
|
||||
stevila = list(range(1,10)) # seznam od 1 do 9, tako se nobena ne ponavlja
|
||||
shuffle(stevila) # jih premešamo npr. [5, 2, 7, 6, 1, 9, 3, 8, 4]
|
||||
for stevilka in stevila:
|
||||
if self.veljavna(sudoku, stevilka, i, j): # za vsako številko preverimo, če je na mestu [i][j] veljavna
|
||||
sudoku[i][j] = stevilka # če je, jo na mesto [i][j] vpišemo, tam ni več 0
|
||||
if self.generiraj(sudoku) == True:
|
||||
return True # če je sudoku s tisto številko zgeneriran, bo tam ostala
|
||||
sudoku[i][j] = 0 # če ne, pa program vpiše na mesto 0 in proba z drugo naključno številko
|
||||
return False # če ni nobena številka na tistem mestu veljavna, vrne False
|
||||
return True
|
||||
def odstranjevanje(self, sudoku, koliko): # funkcija, ki odstranjuje številke iz sudokuja
|
||||
st = 0
|
||||
while st < koliko: # odstranjujemo, dokler ne pride st do koliko
|
||||
i = randint(0, 8) # naključni koordinati
|
||||
j = randint(0, 8)
|
||||
if sudoku[i][j] != 0: # odstrani samo, ko ni enako 0, da program ne bi odšel recimo na enem mestu trikrat.
|
||||
sudoku[i][j] = 0
|
||||
st += 1
|
||||
|
||||
def izpisisudoku(): # funkcija za izpisovanje sudokuja
|
||||
print()
|
||||
for i, vrstica in enumerate(sudoku): # v terminal narišemo sudoku # enumerate vrne indeks vrstice(i) in vrstico.
|
||||
if i % 3 == 0 and i != 0: # ko je indeks večkratnik od 3, bo program vrinil med številke vrsto črtic.
|
||||
print("-" * 21)
|
||||
for j, stevilo in enumerate(vrstica): # j je indeks vsake številke v vrstici, ko je ta večkratnik od 3, se bo vrinila navpična črta, končana s presledkom
|
||||
if j % 3 == 0 and j != 0:
|
||||
print("|", end=" ")
|
||||
if stevilo == 0:
|
||||
print(0, end=" ") # 0 so bele
|
||||
else:
|
||||
print("\033[34m"+str(stevilo)+"\033[0m", end=" ") # če j ni večkratnik števila 3, program napiše barvno številko in konča s presledkom
|
||||
print() # ko se ena vrstica konča, gre program v novo vrstico
|
||||
print()
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
# igra
|
||||
# ----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
print("SUDOKU")
|
||||
print()
|
||||
tezavnost = input("Izberi težavnost(lahka, srednja, težka, nemogoča):")
|
||||
while tezavnost.lower() != "lahka" and tezavnost.lower() != "težka" and tezavnost.lower() != "srednja" and tezavnost.lower() != "nemogoča":
|
||||
print("Še enkrat jasno napiši.")
|
||||
tezavnost = input("Izberi težavnost(lahka, srednja, težka, nemogoča):")
|
||||
if tezavnost.lower() == "lahka": # težavnost pove, koliko številk moramo odstraniti
|
||||
odstrani = 35
|
||||
elif tezavnost.lower() == "srednja":
|
||||
odstrani = 42
|
||||
elif tezavnost.lower() == "težka":
|
||||
odstrani = 49
|
||||
elif tezavnost.lower() == "nemogoča":
|
||||
odstrani = 56
|
||||
|
||||
|
||||
generator = GeneratorSudokuja()
|
||||
generator.generiraj(sudoku) # zgeneriramo sudoku
|
||||
resensudoku = deepcopy(sudoku) # kopiramo rešen sudoku in ga damo v spremenljivko
|
||||
generator.odstranjevanje(sudoku, odstrani) # odstrani nam pove, koliko jih moramo odstraniti, odstrani = koliko
|
||||
|
||||
|
||||
izpisisudoku() # tu program prvič izpiše sudoku
|
||||
odgovori = ["Pravilno!","Odlično!","Točno tako!","Prav je!","Super!","Bravo!","Zadetek!","Natančno!","Fantastično!"] # množica odgovorov za pravilno rešitev
|
||||
pomote = 0 # štetje pomot
|
||||
namigi = 0 # štetje namigov
|
||||
start = time() # štetje časa
|
||||
while True: # s tem poskrbimo, da vedno znova (ob vsakem vnosu) program pogleda najprej, če je sudoku rešen, potem če je admin ali pa namig
|
||||
# šele po vseh teh preverbah program razdeli vnos (vnos.split(","))
|
||||
if sudoku == resensudoku:
|
||||
break # ko pride uporabnik do konca, gre program iz While zanke
|
||||
vnos = input('Vnesi številko in koordinate le-te.:')
|
||||
if vnos.upper() == "END": # easter egg
|
||||
break
|
||||
elif vnos.upper() == "ADM": # samo za admina za preverjanje kode
|
||||
e = randint(0,8)
|
||||
f = randint(0,8)
|
||||
while sudoku[f][e] != 0:
|
||||
e = randint(0,8)
|
||||
f = randint(0,8)
|
||||
sudoku[f][e] = resensudoku[f][e] # program avtomatsko reši eno prazno polje
|
||||
print()
|
||||
print("Goljufaš. To je samo za admina.")
|
||||
izpisisudoku()
|
||||
continue
|
||||
elif vnos.upper() == "NAMIG": # uporabnik lahko zaprosi za namig, če je obtičal
|
||||
namigi += 1 # program prišteje en uporabljen namig
|
||||
e = randint(0,8)
|
||||
f = randint(0,8)
|
||||
while sudoku[f][e] != 0:
|
||||
e = randint(0,8) # program generira nove koordinate, dokler ne naleti na 0
|
||||
f = randint(0,8)
|
||||
print()
|
||||
print("Na koordinatah x =",e+1,"in y =",f+1,"je število", resensudoku[f][e])
|
||||
izpisisudoku() # izpiše sudoku
|
||||
continue
|
||||
vnos = vnos.split(",") # ko vnos ni več "end" ali pa "namig", program vnos (npr. "6,1,5") razčleni v seznamu (["6", "1", "5"]).
|
||||
if len(vnos) != 3: # če se uporabnik zatipka (npr. 6,5 namesto 6,1,5), se program ne bo ustavil (line 136 index out of range), pač pa mu dal še eno priložnost
|
||||
print()
|
||||
print("Zatipkal si se. Poskusi ponovno.")
|
||||
izpisisudoku() # izpiše sudoku
|
||||
continue
|
||||
try:
|
||||
vnos_st = int(vnos[0]) # 6
|
||||
vnos_x = int(vnos[1])-1 # 0 -> ker program sudoku mrežo bere od 0-8, ne od 1-9
|
||||
vnos_y = int(vnos[2])-1 # 4 -> isto
|
||||
except ValueError: # če pride do ValueErrorja, program ne bo crashal, pač pa se bo vrnil na začetek zanke
|
||||
print()
|
||||
print('Vnesi le števila ali pa "namig".')
|
||||
izpisisudoku() # izpiše sudoku
|
||||
continue
|
||||
if vnos_st not in range(1,10) or vnos_x not in range(9) or vnos_y not in range(9): # v primeru napake pri vnosu velikosti števila
|
||||
print()
|
||||
print("Napaka. Vpiši števila med 1 in 9.")
|
||||
else:
|
||||
if sudoku[vnos_y][vnos_x] != 0: # če je uporabnik dislektičen
|
||||
print()
|
||||
print("Napaka. Številko vpiši v prazno polje.")
|
||||
else:
|
||||
sudoku[vnos_y][vnos_x] = vnos_st # vpišemo številko na prazno polje
|
||||
if resensudoku[vnos_y][vnos_x] != vnos_st: # če se ne ujema s številko v rešenem sudokuju, se številka ne vpiše (line 154)
|
||||
print()
|
||||
print("Pomota. Poskusi ponovno.")
|
||||
sudoku[vnos_y][vnos_x] = 0
|
||||
pomote += 1 # število pomot gre gor
|
||||
else:
|
||||
print()
|
||||
print(odgovori[randint(0,len(odgovori)-1)]) # potrdilo, vzeto iz množice odgovorov (line 94)
|
||||
izpisisudoku() # izpiše sudoku
|
||||
|
||||
|
||||
end = time() # ko je zanke konec, se merjenje časa ustavi
|
||||
cas = end - start
|
||||
if vnos.upper() == "END": # če uporabnik predčasno konča igro
|
||||
print("Škoda. Več sreče prihodnjič. Število namigov:", namigi, "Število pomot:", pomote)
|
||||
else: # če pride do konca
|
||||
print("Čestitke, sudoku si pravilno rešil v", int(cas//60), "min in", int(cas % 60) ,"sek. Število namigov:", namigi, "Število pomot:", pomote)
|
||||
Reference in New Issue
Block a user