Atidžiai išstudijuokite šį kodą ir atraskite protingą būdą panaudoti rekursiją, kad išspręstumėte šiuos sudėtingus sudoku galvosūkius.
Sudoku yra populiarus skaičių galvosūkis, kurį sudaro 9x9 tinklelis su skaitmenimis nuo 1 iki 9. Dėlionėje yra skaičių derinys ir keletas tuščių tarpų, kuriuos reikia užpildyti.
Pildant tuščias vietas, kiekvienoje eilutėje, stulpelyje ir 3x3 antrinėje tinklelyje turi būti visi skaitmenys nuo 1 iki 9.
Paprastas Python scenarijus gali padėti išspręsti Sudoku galvosūkį. Jis gali išanalizuoti visas tuščias vietas Sudoku lentoje ir rasti galimą skaičių užpildyti kiekvieną tuščią vietą.
Kaip sukurti ir rodyti „Sudoku“ lentą
Python scenarijuje turėsite naudoti masyvų sąrašą, kad išsaugotumėte neišspręsto Sudoku galvosūkio reikšmes.
Šiame projekte naudotą kodą rasite čia „GitHub“ atpirkimas pagal MIT licenciją.
- Naujame Python scenarijuje, pavadintame sudoku.py, išsaugokite visas 9x9 tinklelio reikšmes. Kiekviena eilutė ir stulpelis žymi devynis skaičius per Sudoku galvosūkį ir žemyn. Pridėkite 0, kad nurodytumėte erdves, kurias reikia išspręsti:
lenta = [
[5, 3, 0, 0, 7, 0, 0, 0, 0],
[6, 0, 0, 1, 9, 5, 0, 0, 0],
[0, 9, 8, 0, 0, 0, 0, 6, 0],
[8, 0, 0, 0, 6, 0, 0, 0, 3],
[4, 0, 0, 8, 0, 3, 0, 0, 1],
[7, 0, 0, 0, 2, 0, 0, 0, 6],
[0, 6, 0, 0, 0, 0, 2, 8, 0],
[0, 0, 0, 4, 1, 9, 0, 0, 5],
[0, 0, 0, 0, 8, 0, 0, 7, 9]
] - Naujoje funkcijoje, pavadintoje print_board, naudokite for kilpą Norėdami apdoroti kiekvieną tinklelio eilutę:
defprint_board(lenta):
dėl eilė in diapazonas(9): - Norėdami atskirti kiekvieną eilutę į trečdalius, patikrinkite, ar eilutė dalijasi iš trijų, ir pridėkite eilutę:
jeigu % eilutė 3 == 0ir eilutė! = 0:
spausdinti ("- - - - - - - - - - - - - - ") - Kiekvienoje eilutėje peržiūrėkite kiekvieną stulpelį. Taip pat galite padalyti stulpelius į trečdalius, patikrinę, ar stulpelis dalijasi iš trijų:
dėl plk in diapazonas(9):
jeigu stulpelis % 3 == 0ir stulpelis != 0:
spausdinti (" | ", pabaiga ="") - Išspausdinkite tinklelyje saugomą skaičiaus reikšmę. Jei stulpelis yra paskutinis tos konkrečios eilutės stulpelis, pridėkite lūžio eilutę, kad ši eilutė būtų rodoma naujoje eilutėje:
jeigu stulpelis == 8:
spausdinti (lenta[eilutė][stulpelis])
Kitas:
spausdinti (str (lenta[eilutė][stulpelis]) + " ", pabaiga ="") - Iškvieskite funkciją spausdinti lentą:
print_board (lenta)
- Komandinėje eilutėje eikite į aplanką, kuriame išsaugojote python scenarijų, pavyzdžiui:
cd darbalaukis
- Naudokite python komandą, kad paleistumėte savo Sudoku scenarijų. Peržiūrėkite ekrane išspausdintą galvosūkį:
python sudoku.py
Kaip nustatyti tuščias vietas, kurias reikia išspręsti
Galite pereiti per sąrašus, kad surastumėte tarpus, sudarytus iš 0. Jie nustato, kurias erdves reikia išspręsti.
- Naujoje funkcijoje, pavadintoje find_empty(), pereikite per kiekvieną lentos eilutę ir stulpelį:
defrasti_tuščia(lenta):
dėl eilė in diapazonas(9):
dėl plk in diapazonas(9): - Jei dabartinio langelio reikšmė yra 0, grąžinkite dabartinę tuščio langelio padėtį:
jeigu lenta[eilutė][stulpelis] == 0:
grąžinti (eilutė, stulpelis) - Jei scenarijus pasiekia funkcijos pabaigą, tai reiškia, kad scenarijus negali rasti langelių, kurių reikšmė yra 0. Tokiu atveju nieko negrąžinkite:
grąžintiNė vienas
- Naujoje funkcijoje, vadinamoje solve(), naudokite paieškos funkciją, kad surastumėte pirmąją tuščią vietą lentoje:
defišspręsti(lenta):
rasti = rasti_tuščia (lenta) - Funkcija find_empty() grąžina langelio padėtį eilės formatu, pavyzdžiui, (0, 2). Išsaugokite šias reikšmes atskirai į eilė ir plk kintamieji. Kitu atveju grąžinkite teisingą, kad reikštumėte, kad nebeliko tuščių tarpų, kuriuos reikia išspręsti:
jeigune rasti:
grąžintiTiesa
Kitas:
eilutė, stulpelis = rasti
Kaip išspręsti galvosūkį kiekvienai eilutei, stulpeliui ir 3x3 tinkleliui
Dabar, kai galite nustatyti pirmąją tuščią vietą, kurią reikia išspręsti, turėsite pabandyti rasti tinkamą skaičių, kad užpildytumėte tą vietą ir išspręstumėte galvosūkį.
Naudojant rekursiją, iškvieskite savyje funkciją solve(), kad išbandytumėte visus įmanomus reikšmių derinius ir visose kitose erdvėse.
- Funkcijoje solve() suradę pirmąją tuščią vietą, pereikite per kiekvieną skaičių nuo 1 iki 9. Šie skaičiai reiškia galimus skaičius, kurie galėtų užpildyti neišspręstą erdvę:
dėl nr in diapazonas(1, 10):
- Įveskite lentą, galimą skaičių ir tuščio langelio vietą į naują funkciją. Naujoji funkcija grąžins teisingą, jei šis skaičius yra galiojantis skaičius, galintis išspręsti šią tuščią vietą. Jei jis galioja, priskirkite tą numerį lentos langeliui:
jeigu is_valid (lenta, skaičius, (eilutė, stulpelis)):
lenta[eilutė][stulpelis] = skaičius - Sukurkite funkciją is_valid() su atitinkamais parametrais:
defgaliojantis(lenta, numeris, poz.):
- Naudokite šią funkciją norėdami patikrinti, ar numerio įkėlimas į tą vietą nepažeidžia kokių nors Sudoku žaidimo taisyklių. Pirmiausia patikrinkite, ar tas skaičius jau yra langelio eilutėje arba stulpelyje:
dėl plk in diapazonas(9):
jeigu lenta[pos[0]][stulpelis] == skaičius ir poz[1] != stulpelis:
grąžintiNetiesadėl eilė in diapazonas(9):
jeigu lenta[eilutė][pozicija[1]] == Nr ir poz[0] != eilutė:
grąžintiNetiesa - Gaukite 3x3 tinklelį, kuriam priklauso langelis. Tai galite padaryti padalydami langelio vietą iš trijų:
box_row = poz[0] // 3
box_col = poz[1] // 3 - Kiekvienoje to 3x3 tinklelio eilutėje ir stulpelyje patikrinkite, ar numeris jau yra. Jei taip, grąžinkite false:
dėl eilė in diapazonas (box_row*3, box_row*3 + 3):
dėl plk in diapazonas (box_col*3, box_col*3 + 3):
jeigu lenta[eilutė][stulpelis] == nr ir (eilutė, stulpelis) != poz:
grąžintiNetiesa - Jei scenarijus pasiekia funkcijos pabaigą, tai reiškia, kad nė viena Sudoku taisyklė nepavyko. Grąžinti tiesa:
grąžintiTiesa
- Funkcija is_valid() tik patikrina, ar skaičių vieta yra teisinga, tačiau tai nereiškia, kad tai yra teisingas atsakymas į bendrą sprendimą. Funkcijoje solve() dar kartą iškvieskite solve() funkciją naudodami atnaujintą lentą. Funkcija solve() gali pasiekti būseną, kai ji nebegali naudoti jokių skaičių tarpams užpildyti. Tokiu atveju visa funkcija grąžina false, iš naujo nustato tam tikrą langelį į 0 ir grįžta atgal. Funkcija solve() grąžina true tik tada, kai scenarijus gali užpildyti visus tarpus:
dėl nr in diapazonas(1, 10):
jeigu is_valid (lenta, skaičius, (eilutė, stulpelis)):
lenta[eilutė][stulpelis] = skaičius
jeigu išspręsti (lenta):
grąžintiTiesa
lenta[eilutė][stulpelis] = 0grąžintiNetiesa
- Norėdami pradėti spręsti galvosūkį, iškvieskite solve() funkciją su originalia lenta, esančia scenarijaus apačioje, paskelbę funkciją solve():
išspręsti (lenta)
- Spausdinkite galutinį rezultatą:
spausdinti ("Išspręsta:")
print_board (lenta) - Komandinėje eilutėje naudokite python komandą, kad iš naujo paleistumėte scenarijų. Peržiūrėkite išspręstą galvosūkį, atspausdintą ekrane:
python sudoku.py
Žaidimų kūrimas naudojant Python
Sudoku yra tik vienas iš daugelio žaidimų, kuriuos galite sukurti ir išspręsti naudodami Python. Galite naudoti Python kurdami įvairius kitus žaidimus, pvz., žodžių maištelį, tekstinį nuotykių žaidimą ar spalvų žaidimą.