nikitast

SUDOKU_game

Jan 19th, 2021
861
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. from random import randint
  2. import pickle
  3.  
  4.  
  5. def swap_rows(field):
  6.     row1 = randint(0, 1)
  7.     row2 = row1 + 1
  8.     k = randint(0, 2)
  9.     row1, row2 = map(lambda x: x + 3 * k, [row1, row2])
  10.     tmp = field[row1]
  11.     field[row1] = field[row2]
  12.     field[row2] = tmp
  13.  
  14.  
  15. def swap_cols(field):
  16.     col1 = randint(0, 1)
  17.     col2 = col1 + 1
  18.     k = randint(0, 2)
  19.     col1, col2 = map(lambda x: x + 3 * k, [col1, col2])
  20.     for i in range(9):
  21.         tmp = field[i][col1]
  22.         field[i][col1] = field[i][col2]
  23.         field[i][col2] = tmp
  24.  
  25.  
  26. def transposition(field):
  27.     for i in range(9):
  28.         for j in range(9):
  29.             tmp = field[i][j]
  30.             field[i][j] = field[j][i]
  31.             field[j][i] = tmp
  32.  
  33.  
  34. class Session:
  35.     def __init__(self):
  36.         self.state = None
  37.         self.stage = None
  38.         self.field = None
  39.         self.n = None
  40.  
  41.     def set_field(self, n):
  42.         self.n = n
  43.         self.field = [[((j * 3 + j // 3 + i) % 9 + 1) for i in range(9)] for j in range(9)]
  44.         cnt = 0
  45.         while cnt < 81 - n:
  46.             i = randint(0, 8)
  47.             j = randint(0, 8)
  48.             if self.field[i][j] != 0:
  49.                 self.field[i][j] = 0
  50.                 cnt += 1
  51.         for i in range(randint(15, 30)):
  52.             swap_cols(self.field)
  53.         for i in range(randint(15, 30)):
  54.             swap_rows(self.field)
  55.         for i in range(randint(0, 1)):
  56.             transposition(self.field)
  57.  
  58.     def print_field(self):
  59.         print("   ", end='')
  60.         for i in range(9):
  61.             print("[{}]".format(i+1)+(" " if (i + 1) % 3 == 0 else ""), end='')
  62.         print("")
  63.         for i in range(9):
  64.             print("[{}]".format(i+1), end=' ')
  65.             for j in range(9):
  66.                 print(self.field[i][j], ("|" if (j + 1) % 3 == 0 else ""), end=' ')
  67.             print(('\n    ' + "-" * 28) if (i + 1) % 3 == 0 else "")
  68.  
  69.     def get_num(self, i, j, n):
  70.         if self.field[i-1][j-1] == 0:
  71.             self.field[i-1][j-1] = n
  72.             return True
  73.         else:
  74.             return False
  75.  
  76.     def check_sol(self):
  77.         flag = True
  78.         for row in self.field:
  79.             if len(set(row)) != 9:
  80.                 flag = False
  81.         for i in range(9):
  82.             set_arr = set([self.field[j][i] for j in range(9)])
  83.             if len(set_arr) != 9:
  84.                 flag = False
  85.         for i in range(0, 7, 3):
  86.             for j in range(0, 7, 3):
  87.                 set_arr = []
  88.                 arr = [row[j:(j+3)] for row in session.field[i:(i+3)]]
  89.                 for row in arr:
  90.                     set_arr += list(row)
  91.                 if len(set(set_arr)) != 9:
  92.                     flag = False
  93.         return flag
  94.  
  95.     def empty_cell(self):
  96.         return sum([self.field[i][j] == 0 for i in range(9) for j in range(9)])
  97.  
  98.     def save_game(self):
  99.         with open('data.pickle', 'wb') as f:
  100.             pickle.dump(self.field, f)
  101.  
  102.     def load_game(self):
  103.         with open('data.pickle', 'rb') as f:
  104.             self.field = pickle.load(f)
  105.  
  106.     @staticmethod
  107.     def clear():
  108.         print('\n' * 100)
  109.  
  110.  
  111. def find_next(grid, i, j):
  112.     for x in range(i, 9):
  113.         for y in range(j, 9):
  114.             if grid[x][y] == 0:
  115.                 return x, y
  116.     for x in range(0, 9):
  117.         for y in range(0, 9):
  118.             if grid[x][y] == 0:
  119.                 return x, y
  120.     return -1, -1
  121.  
  122.  
  123. def is_available(field, i, j, k):
  124.     check_row = all([k != field[i][x] for x in range(9)])
  125.     if check_row:
  126.         check_column = all([k != field[x][j] for x in range(9)])
  127.         if check_column:
  128.             # finding the top left x,y co-ordinates of the section containing the i,j cell
  129.             x_sec, y_sec = 3 * (i // 3), 3 * (j // 3)  # floored quotient should be used here.
  130.             for x in range(x_sec, x_sec + 3):
  131.                 for y in range(y_sec, y_sec + 3):
  132.                     if field[x][y] == k:
  133.                         return False
  134.             return True
  135.     return False
  136.  
  137.  
  138. def sudoku_solver(field, i=0, j=0):
  139.     i, j = find_next(field, i, j)
  140.     if i == -1:
  141.         return True
  142.     for k in range(1, 10):
  143.         if is_available(field, i, j, k):
  144.             field[i][j] = k
  145.             if sudoku_solver(field, i, j):
  146.                 return True
  147.             # Undo the current cell for backtracking
  148.             field[i][j] = 0
  149.     return False
  150.  
  151.  
  152. session = Session()
  153. session.clear()
  154. session.state = input("Enter 'auto' to solve the game automatically or\n"
  155.                         "Enter 'play' to start the game:\n")
  156. session.clear()
  157. if session.state == "play":
  158.     session.stage = input("Enter 'new' to start new game or\n"
  159.                           "Enter 'load' to load game:\n")
  160.     session.clear()
  161.     if session.stage == 'new':
  162.         session.set_field(int(input("Enter the number of prompts:\n")))
  163.         session.clear()
  164.         session.print_field()
  165.         print("Amount of empty cells: {}".format(session.empty_cell()))
  166.     elif session.stage == 'load':
  167.         session.load_game()
  168.         session.clear()
  169.         session.print_field()
  170.         print("Game loaded")
  171.         print("Amount of empty cells: {}".format(session.empty_cell()))
  172.     while True:
  173.         inp = input("Enter 'end' to end the game or\n"
  174.                     "Enter 'save' to save the game, or\n"
  175.                     "Enter <<row column number>> to put the number on the field:\n")
  176.         if inp == 'save':
  177.             session.save_game()
  178.             session.clear()
  179.             session.print_field()
  180.             print("Game saved")
  181.             print("Amount of empty cells: {}".format(session.empty_cell()))
  182.         elif inp == 'end':
  183.             session.clear()
  184.             if (input("Game is not finished. Do you want to save the game?\n"
  185.                   "Enter 'yes' to save the game, or\n"
  186.                   "Enter 'no' to end the game:\n") == 'yes'):
  187.                 session.clear()
  188.                 session.save_game()
  189.                 print("Game saved")
  190.                 input("Put 'Enter' to end the game:\n")
  191.             break
  192.         else:
  193.             inp = list(map(lambda x: int(x), inp.split(' ')))
  194.             if session.get_num(inp[0], inp[1], inp[2]):
  195.                 session.clear()
  196.                 session.print_field()
  197.                 print("Amount of empty cells: {}".format(session.empty_cell()))
  198.             else:
  199.                 session.clear()
  200.                 session.print_field()
  201.                 print("You can't change the filled cell. Choose not filled cell.")
  202.                 print("Amount of empty cells: {}".format(session.empty_cell()))
  203.     session.clear()
  204.     if session.empty_cell() != 0:
  205.         print("Game was not completed")
  206.     else:
  207.         if session.check_sol():
  208.             print("You won the game")
  209.         else:
  210.             print("You lost the game")
  211. elif session.state == "auto":
  212.     session.set_field(int(input("Enter the number of prompts:\n")))
  213.     session.clear()
  214.     session.print_field()
  215.     print("Amount of empty cells: {}".format(session.empty_cell()))
  216.     input("Put 'Enter' to win the game:\n")
  217.     session.clear()
  218.     sudoku_solver(session.field)
  219.     session.print_field()
  220.  
RAW Paste Data