Skip to content

Commit e5a3be3

Browse files
authored
Add files via upload
1 parent b0e44c6 commit e5a3be3

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed

GAMES/sudoku_game.py

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import random # imports random to pick random numbers and shuffle cells
2+
import sys # calls sys.exit() so program can end whenver user quits
3+
# function to print the board
4+
def print_board(board):
5+
'''
6+
displays 9*9 board in a formatted grid
7+
with lines separating 3*3 subgrids basically 2d list board 9*9
8+
'''
9+
for i in range(9):
10+
if i % 3 == 0 and i != 0:
11+
print("- - - - - - - - - - - - - - -")
12+
'''
13+
every time i is a multiple of 3 it print horizontal seperator
14+
this is row index or used for maing row
15+
'''
16+
for j in range(9):
17+
'''
18+
every time j is multiple of 3, we print vertical bars without
19+
for coloumns
20+
'''
21+
if j % 3 == 0 and j != 0:
22+
print("|", end=" ")
23+
print(board[i][j] if board[i][j] != 0 else ".", end=" ")
24+
# prints cells value if nonzero otherwise . to make empty cell
25+
# on the same line end=" "
26+
print() # for moving to next line
27+
28+
# function to find an empty cell in board
29+
def find_empty(board):# searches the grid
30+
for i in range(9):
31+
for j in range(9):
32+
# used for scanning every row i and every col j to look for 0(indicates empty)
33+
if board[i][j] == 0:
34+
return (i, j) # returns row and col as soon as it finds empty
35+
return None
36+
37+
# function to check if placing num at pos is valid
38+
def is_valid(board, num, pos):# check if you can place a number at row or col
39+
row, col = pos
40+
if any(board[row][i] == num for i in range(9) if i != col): #scaNS row for duplicates
41+
return False
42+
if any(board[i][col] == num for i in range(9) if i != row): # scans entire col for duplicates
43+
return False
44+
box_row = (row // 3) * 3
45+
box_col = (col // 3) * 3
46+
for i in range(box_row, box_row + 3):
47+
for j in range(box_col, box_col + 3):
48+
if board[i][j] == num and (i, j) != pos:
49+
return False # if num appears somewhere else move illegal
50+
return True # if not true
51+
52+
# Backtracking solver
53+
def solve_board(board):
54+
# here function find empty and is valid is used
55+
# to fill the board , it tries all numbers from 1 to 9 at each empty cell and proceeds only if valid
56+
empty = find_empty(board)
57+
if not empty:
58+
return True
59+
row, col = empty
60+
for num in range(1, 10):
61+
if is_valid(board, num, (row, col)):
62+
board[row][col] = num
63+
if solve_board(board):
64+
return True
65+
board[row][col] = 0
66+
return False
67+
68+
def count_solutions(board):
69+
# counts all possible ways to create or complete the solutuion
70+
# no empty you found sol and returns 1
71+
# and finds total num of solution and stores in count
72+
empty = find_empty(board)
73+
if not empty:
74+
return 1
75+
row, col = empty
76+
count = 0
77+
for num in range(1, 10):
78+
if is_valid(board, num, (row, col)):
79+
board[row][col] = num
80+
count += count_solutions(board)
81+
board[row][col] = 0
82+
return count
83+
84+
def create_board(removals=30):
85+
# creates an empty board
86+
# num cell is used to choose difficulty
87+
# here removal check that only 1 unique sol remains using count_solutions
88+
board = [[0]*9 for _ in range(9)]
89+
solve_board(board)
90+
removed = 0
91+
while removed < removals:
92+
r = random.randrange(9)
93+
c = random.randrange(9)
94+
if board[r][c] != 0:
95+
temp = board[r][c]
96+
board[r][c] = 0
97+
copy = [row[:] for row in board]
98+
if count_solutions(copy) != 1:
99+
board[r][c] = temp
100+
else:
101+
removed += 1
102+
return board
103+
104+
def is_complete(board):
105+
return all(cell != 0 for row in board for cell in row)
106+
# returns if every cell in grid is non zero
107+
108+
def get_input(prompt):
109+
while True:
110+
inp = input(prompt)
111+
if inp.lower() == 'q': # q to exit the program
112+
sys.exit("Goodbye!")
113+
if inp.isdigit() and 1 <= int(inp) <= 9:
114+
return int(inp) - 1
115+
print("Invalid input. Enter 1-9 or 'q'.")
116+
117+
def player_turn(board):
118+
print("\n your move:")
119+
print_board(board)
120+
while True:
121+
row = get_input("Enter row (1-9) or 'q' to quit: ")
122+
col = get_input("Enter column (1-9) or 'q' to quit: ")
123+
if board[row][col] == 0:
124+
break
125+
print("choose another, cell already filled")
126+
while True:
127+
num = get_input("Enter number (1-9) or 'q' to quit: ") + 1
128+
if is_valid(board, num, (row, col)):
129+
board[row][col] = num
130+
break
131+
print("invalid try again")
132+
133+
def computer_turn(board):
134+
print("\nComputer's move:")
135+
print_board(board)
136+
empties = [(i, j) for i in range(9) for j in range(9) if board[i][j] == 0]
137+
random.shuffle(empties)
138+
for row, col in empties:
139+
for num in range(1, 10):
140+
if is_valid(board, num, (row, col)):
141+
board[row][col] = num
142+
if count_solutions([r[:] for r in board]) == 1:
143+
print(f"Computer placed {num} at ({row+1},{col+1})")
144+
return
145+
board[row][col] = 0
146+
print("computer gives up. multiple solutions possible.")
147+
148+
if __name__ == "__main__":
149+
puzzle = create_board(removals=30)
150+
while True:
151+
player_turn(puzzle)
152+
cont = input("\nPress 't' if tired and let computer solve it, any other key to continue: ")
153+
if cont.lower() == 't':
154+
solve_board(puzzle)
155+
print_board(puzzle)
156+
print("\n Computer has solved the rest of the puzzle :(( Game over.")
157+
break
158+
if is_complete(puzzle):
159+
print_board(puzzle)
160+
print("Congratulations! You solved it!!!!")
161+
break
162+
computer_turn(puzzle)
163+
if is_complete(puzzle):
164+
print_board(puzzle)
165+
print("Computer solved it!! You lose!!!!")
166+
break

0 commit comments

Comments
 (0)