欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

150行Python代碼實現(xiàn)帶界面的數(shù)獨游戲

 更新時間:2020年04月04日 08:48:39   作者:HoLoong  
這篇文章主要介紹了150行Python代碼實現(xiàn)帶界面的數(shù)獨游戲,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

今天閑著沒事干,以前做過html+js版的數(shù)獨,這次做個python版本的,界面由pygame完成,數(shù)獨生成由遞歸算法實現(xiàn),由shuffle保證每次游戲都是不一樣的情況,have fun;

功能列表:

  • 圖形化的數(shù)獨游戲;
  • python實現(xiàn),依賴pygame庫;
  • 隨機生成游戲,每次運行都不一樣;
  • 數(shù)字填入后的正確性判斷以及顏色提示;
  • 顯示剩余需填入的空格,已經(jīng)操作的次數(shù);
  • 難度可選,通過修改需要填入的空的數(shù)量;

 游戲界面

初始界面

過程中界面

運行方式

python main.py 15

這里的15表示需要填入的空格數(shù)量為15,理論上這個值越大,難度就越高,大家可以隨機調整,或者設置容易、簡單、困難、地獄等對應不同的值即可,很方便修改;

程序分析

界面部分

這部分很簡單的通過pygame來實現(xiàn),主要使用了其中的主循環(huán)、鼠標鍵盤監(jiān)聽、畫矩形線條、字體、顏色控制等,理解起來很容易,對于這部分不太熟悉的同學,這樣理解就好: pygame的主循環(huán)中一方面負責接收用戶輸入,一般就是鼠標和鍵盤,另一方面負責實時更新界面顯示內容 ;

對于界面上各部分內容的繪制的函數(shù)封裝

# 繪制背景部分,這里就是9*9的九宮格
def draw_background():
  # white background
  screen.fill(COLORS['white'])

  # draw game board
  pygame.draw.rect(screen,COLORS['black'],(0,0,300,900),5)
  pygame.draw.rect(screen,COLORS['black'],(300,0,300,900),5)
  pygame.draw.rect(screen,COLORS['black'],(600,0,300,900),5)

  pygame.draw.rect(screen,COLORS['black'],(0,0,900,300),5)
  pygame.draw.rect(screen,COLORS['black'],(0,300,900,300),5)
  pygame.draw.rect(screen,COLORS['black'],(0,600,900,300),5)

# 將用戶選中的各自背景改為藍色塊表示選中
def draw_choose():
  pygame.draw.rect(screen,COLORS['blue'],(cur_j*100+5,cur_i*100+5,100-10,100-10),0)

# 繪制九宮格中的數(shù)字,包括本來就有的,以及用戶填入的,本來就在的用灰色,用戶填入的如何合法則為綠色,否則為紅色,是一種提示
def draw_number():
  for i in range(len(MATRIX)):
    for j in range(len(MATRIX[0])):
      _color = check_color(MATRIX,i,j) if (i,j) in BLANK_IJ else COLORS['gray']
      txt = font80.render(str(MATRIX[i][j] if MATRIX[i][j] not in [0,'0'] else ''),True,_color)
      x,y = j*100+30,i*100+10
      screen.blit(txt,(x,y))

# 繪制最下方的當前空格子數(shù)量以及用戶的操作數(shù)量
def draw_context():
  txt = font100.render('Blank:'+str(cur_blank_size)+'  Change:'+str(cur_change_size),True,COLORS['black'])
  x,y = 10,900
  screen.blit(txt,(x,y))

主循環(huán)中對上述函數(shù)的調用以及鼠標鍵盤事件處理

# 主循環(huán),負責監(jiān)聽鼠標鍵盤時間,以及刷新界面內容,以及檢查是否贏得了游戲
running = True
while running:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      running = False
      break
    elif event.type == pygame.MOUSEBUTTONDOWN:
      cur_j,cur_i = int(event.pos[0]/100),int(event.pos[1]/100)
    elif event.type == event.type == pygame.KEYUP:
      if chr(event.key) in ['1','2','3','4','5','6','7','8','9'] and (cur_i,cur_j) in BLANK_IJ:
        MATRIX[cur_i][cur_j] = int(chr(event.key))
        cur_blank_size = sum([1 if col==0 or col=='0' else 0 for row in MATRIX for col in row])
        cur_change_size +=1
  # background
  draw_background()
  # choose item
  draw_choose()
  # numbers
  draw_number()
  # point
  draw_context()
  # flip
  pygame.display.flip()

  # check win or not
  if check_win(MATRIX_ANSWER,MATRIX):
    print('You win, smarty ass!!!')
    break

pygame.quit()

生成表示數(shù)獨的二維數(shù)組

相對于界面部分,這部分在邏輯上要難一些,思路以遞歸為核心,輔以隨機性,得到一個每次生成都不一致的數(shù)獨游戲,生成思路簡單描述如下:

  • 遍歷每個空格,填入目前為止合法的數(shù)字;
  • 如果有數(shù)字可以填入,則繼續(xù)向下一個空格;
  • 如果沒有數(shù)字可以填入,表示之前的數(shù)字有問題,則結束遞歸;
  • 當遞歸到最后一個格子的下一個時,表示已經(jīng)生成完畢,返回即可;
  • 這個過程中對1~9這九個數(shù)字的遍歷數(shù)字會經(jīng)過shuffle處理,保證隨機性而不是每次都得到同一個合法的數(shù)獨數(shù)組;

生成過程代碼

遞歸的一個優(yōu)勢是通常代碼都很短,當然閱讀性不強,歡迎大佬們改為循環(huán);

def shuffle_number(_list):
  random.shuffle(_list)
  return _list

def check(matrix,i,j,number):
  if number in matrix[i]:
    return False
  if number in [row[j] for row in matrix]:
    return False
  group_i,group_j = int(i/3),int(j/3)
  if number in [matrix[i][j] for i in range(group_i*3,(group_i+1)*3) for j in range(group_j*3,(group_j+1)*3)]:
    return False
  return True

def build_game(matrix,i,j,number):
  if i>8 or j>8:
    return matrix
  if check(matrix,i,j,number):
    _matrix = [[col for col in row] for row in matrix]
    _matrix[i][j] = number
    next_i,next_j = (i+1,0) if j==8 else (i,j+1)
    for _number in shuffle_number(number_list):
      __matrix = build_game(_matrix,next_i,next_j,_number)
      if __matrix and sum([sum(row) for row in __matrix])==(sum(range(1,10))*9):
        return __matrix
  return None

隨機覆蓋數(shù)獨數(shù)組中的N個位置

  •  matrix_all表示整個數(shù)獨數(shù)組
  • matrix_blank表示部分被替換為0的用于顯示的數(shù)組
  • blank_ij表示被覆蓋位置的i和j
def give_me_a_game(blank_size=9):
  matrix_all = build_game(matrix,0,0,random.choice(number_list))
  set_ij = set()
  while len(list(set_ij))<blank_size:
    set_ij.add(str(random.choice([0,1,2,3,4,5,6,7,8]))+','+str(random.choice([0,1,2,3,4,5,6,7,8])))
  matrix_blank = [[col for col in row] for row in matrix_all]
  blank_ij = []
  for ij in list(set_ij):
    i,j = int(ij.split(',')[0]),int(ij.split(',')[1])
    blank_ij.append((i,j))
    matrix_blank[i][j] = 0
  return matrix_all,matrix_blank,blank_ij

最后附上全部代碼

大家也可以直接從我的 Github倉庫 fork下來直接運行;

main.py:主流程+界面+執(zhí)行

import sys

import pygame
from pygame.color import THECOLORS as COLORS

from build import print_matrix,give_me_a_game,check

def draw_background():
  # white background
  screen.fill(COLORS['white'])

  # draw game board
  pygame.draw.rect(screen,COLORS['black'],(0,0,300,900),5)
  pygame.draw.rect(screen,COLORS['black'],(300,0,300,900),5)
  pygame.draw.rect(screen,COLORS['black'],(600,0,300,900),5)

  pygame.draw.rect(screen,COLORS['black'],(0,0,900,300),5)
  pygame.draw.rect(screen,COLORS['black'],(0,300,900,300),5)
  pygame.draw.rect(screen,COLORS['black'],(0,600,900,300),5)

def draw_choose():
  pygame.draw.rect(screen,COLORS['blue'],(cur_j*100+5,cur_i*100+5,100-10,100-10),0)

def check_win(matrix_all,matrix):
  if matrix_all == matrix:
    return True
  return False

def check_color(matrix,i,j):
  _matrix = [[col for col in row]for row in matrix]
  _matrix[i][j] = 0
  if check(_matrix,i,j,matrix[i][j]):
    return COLORS['green']
  return COLORS['red']

def draw_number():
  for i in range(len(MATRIX)):
    for j in range(len(MATRIX[0])):
      _color = check_color(MATRIX,i,j) if (i,j) in BLANK_IJ else COLORS['gray']
      txt = font80.render(str(MATRIX[i][j] if MATRIX[i][j] not in [0,'0'] else ''),True,_color)
      x,y = j*100+30,i*100+10
      screen.blit(txt,(x,y))

def draw_context():
  txt = font100.render('Blank:'+str(cur_blank_size)+'  Change:'+str(cur_change_size),True,COLORS['black'])
  x,y = 10,900
  screen.blit(txt,(x,y))

if __name__ == "__main__":
  # init pygame
  pygame.init()
  
  # contant
  SIZE = [900,1000]
  font80 = pygame.font.SysFont('Times', 80)
  font100 = pygame.font.SysFont('Times', 90)
  
  # create screen 500*500
  screen = pygame.display.set_mode(SIZE)
  
  # variable parameter
  cur_i, cur_j = 0,0
  cur_blank_size = int(sys.argv[1])
  cur_change_size = 0
  
  # matrix abount
  MATRIX_ANSWER,MATRIX,BLANK_IJ = give_me_a_game(blank_size=cur_blank_size)
  print(BLANK_IJ)
  print_matrix(MATRIX)
  
  # main loop
  running = True
  while running:
    for event in pygame.event.get():
      if event.type == pygame.QUIT:
        running = False
        break
      elif event.type == pygame.MOUSEBUTTONDOWN:
        cur_j,cur_i = int(event.pos[0]/100),int(event.pos[1]/100)
      elif event.type == event.type == pygame.KEYUP:
        if chr(event.key) in ['1','2','3','4','5','6','7','8','9'] and (cur_i,cur_j) in BLANK_IJ:
          MATRIX[cur_i][cur_j] = int(chr(event.key))
          cur_blank_size = sum([1 if col==0 or col=='0' else 0 for row in MATRIX for col in row])
          cur_change_size +=1
    # background
    draw_background()
    # choose item
    draw_choose()
    # numbers
    draw_number()
    # point
    draw_context()
    # flip
    pygame.display.flip()
  
    # check win or not
    if check_win(MATRIX_ANSWER,MATRIX):
      print('You win, smarty ass!!!')
      break
  
  pygame.quit()

build.py:生成數(shù)獨數(shù)組部分

import random

def print_matrix(matrix):
  print('—'*19)
  for row in matrix:
    print('|'+' '.join([str(col) for col in row])+'|')
  print('—'*19)

def shuffle_number(_list):
  random.shuffle(_list)
  return _list

def check(matrix,i,j,number):
  if number in matrix[i]:
    return False
  if number in [row[j] for row in matrix]:
    return False
  group_i,group_j = int(i/3),int(j/3)
  if number in [matrix[i][j] for i in range(group_i*3,(group_i+1)*3) for j in range(group_j*3,(group_j+1)*3)]:
    return False
  return True

def build_game(matrix,i,j,number):
  if i>8 or j>8:
    return matrix
  if check(matrix,i,j,number):
    _matrix = [[col for col in row] for row in matrix]
    _matrix[i][j] = number
    next_i,next_j = (i+1,0) if j==8 else (i,j+1)
    for _number in shuffle_number(number_list):
      #_matrixs.append(build_game(_matrix,next_i,next_j,_number))
      __matrix = build_game(_matrix,next_i,next_j,_number)
      if __matrix and sum([sum(row) for row in __matrix])==(sum(range(1,10))*9):
        return __matrix
  #return _matrixs
  return None

def give_me_a_game(blank_size=9):
  matrix_all = build_game(matrix,0,0,random.choice(number_list))
  set_ij = set()
  while len(list(set_ij))<blank_size:
    set_ij.add(str(random.choice([0,1,2,3,4,5,6,7,8]))+','+str(random.choice([0,1,2,3,4,5,6,7,8])))
  matrix_blank = [[col for col in row] for row in matrix_all]
  blank_ij = []
  for ij in list(set_ij):
    i,j = int(ij.split(',')[0]),int(ij.split(',')[1])
    blank_ij.append((i,j))
    matrix_blank[i][j] = 0
  return matrix_all,matrix_blank,blank_ij

number_list = [1,2,3,4,5,6,7,8,9]
matrix = [([0]*9) for i in range(9)]
if __name__ == "__main__":
  print_matrix(build_game(matrix,0,0,random.choice(number_list)))

總結

如果刻意減少代碼的話,實際應該控制在100行以內,這也充分表達了python的強大,確實可以在很短的時間內完成一些看似復雜的工作,這個例子供一些同學上手python個人覺得還是不錯的,沒有太復雜的用法,對界面開發(fā)有一點點了解,對遞歸有一些理解基本就能完全掌握這份代碼,希望大家玩的開心,挑戰(zhàn)一下50個空格唄,哈哈,反正我沒通過,太難了。。。。

最后

大家可以到我的Github上看看有沒有其他需要的東西,目前主要是自己做的機器學習項目、Python各種腳本工具、有意思的小項目以及Follow的大佬、Fork的項目等:

https://github.com/NemoHoHaloAi

到此這篇關于150行Python代碼實現(xiàn)帶界面的數(shù)獨游戲的文章就介紹到這了,更多相關Python 數(shù)獨游戲內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

作者:Ho Loong
Github:https://github.com/NemoHoHaloAi
Kaggle:https://www.kaggle.com/holoong9291

相關文章

  • Python函數(shù)中不定長參數(shù)的寫法

    Python函數(shù)中不定長參數(shù)的寫法

    今天小編就為大家分享一篇關于Python函數(shù)中不定長參數(shù)的寫法,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • influx+grafana自定義python采集數(shù)據(jù)和一些坑的總結

    influx+grafana自定義python采集數(shù)據(jù)和一些坑的總結

    一些數(shù)據(jù)的類型不正確會導致no datapoint的錯誤,真是令人抓狂,本文就是總結一下采集數(shù)據(jù)種的一些坑,希望大家可以從中獲益
    2018-09-09
  • 詳解python的幾種標準輸出重定向方式

    詳解python的幾種標準輸出重定向方式

    這篇文章是基于Python2.7版本,介紹常見的幾種標準輸出(stdout)重定向方式。顯然,這些方式也適用于標準錯誤重定向。學習python的小伙伴們可以參考借鑒。
    2016-08-08
  • 簡單總結Python中序列與字典的相同和不同之處

    簡單總結Python中序列與字典的相同和不同之處

    這篇文章主要介紹了Python中序列與字典的相同和不同之處,序列這里講到Python中最常用的列表和元組以及字典三種,需要的朋友可以參考下
    2016-01-01
  • Python中Numpy包的安裝與使用方法簡明教程

    Python中Numpy包的安裝與使用方法簡明教程

    這篇文章主要介紹了Python中Numpy包的安裝與使用方法,結合簡單實例形式分析了Python使用pip命令在線與離線whl包安裝,以及使用numpy打印隨機數(shù)矩陣的操作技巧,需要的朋友可以參考下
    2018-07-07
  • Python中出現(xiàn)IndentationError:unindent does not match any outer indentation level錯誤的解決方法

    Python中出現(xiàn)IndentationError:unindent does not match any outer

    今天在網(wǎng)上copy的一段代碼,代碼很簡單,每行看起來該縮進的都縮進了,運行的時候出現(xiàn)了如下錯誤,IndentationError: unindent does not match any outer indentation level,如果看起來縮進正常所有tab與空格混用就會出現(xiàn)這個問題
    2019-01-01
  • keras 自定義loss層+接受輸入實例

    keras 自定義loss層+接受輸入實例

    這篇文章主要介紹了keras 自定義loss層+接受輸入實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • python逆向微信指數(shù)爬取實現(xiàn)步驟

    python逆向微信指數(shù)爬取實現(xiàn)步驟

    這篇文章主要為大家介紹了python逆向微信指數(shù)爬取的實現(xiàn)步驟,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-02-02
  • PyCharm代碼整體縮進,反向縮進的方法

    PyCharm代碼整體縮進,反向縮進的方法

    今天小編就為大家分享一篇PyCharm代碼整體縮進,反向縮進的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • python GUI模擬實現(xiàn)計算器

    python GUI模擬實現(xiàn)計算器

    這篇文章主要為大家詳細介紹了python GUI模擬實現(xiàn)計算器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06

最新評論