用python編寫的45行精簡版俄羅斯方塊遊戲

2021-10-07 15:46:11 字數 3645 閱讀 3917

我以前用js寫過乙個60行**的俄羅斯方塊,現在python比較流行,決定再寫乙個python版本的。

遊戲演算法與之前的基本一致,也是用二進位製作為位圖資料,用位運算的「與」來判斷方塊與場地是否重疊,用位運算的「或」來把方塊與場地合併。

這次重新優化了程式,並改良了之前不那麼優雅的語法。

本想用python編寫會超過60行,結果最終優化後的程式不算注釋和空行只有45行。

#-*- coding:utf-8 -*-

import random, tkinter, tkinter.messagebox

# 7種方塊圖案(以4*4的16位二進位制點陣儲存)

tetris =

(0x66,)

,(0x2222

,0xf0),

(0xc60

,0x264),

(0x6c0

,0x462),

(0x446

,0x2e

,0x622

,0x74),

(0x226

,0xe2

,0x644

,0x470),

(0x262

,0x72

,0x232

,0x270

)# 遊戲場地資料 (以每行12位二進位制點陣儲存,底線設定兩行是為了防止計算時列表索引越界)

fie =

[0x801]*

25+[0x7fe]*

2# 遊戲執行需要的資料

p =# 將012字元對映成空格,實心方塊與空心方塊的轉換表

mak =

str.maketrans(

"012"

,"\u3000\u25a0\u25a1"

)# 初始化新方塊函式

definit()

:# 為了方便在標題欄顯示分數

win.title(

%(p[

"lines"]*

100)

)# 初始化新方塊的資料 dia是隨機選擇出的一種方塊圖案,r是方塊圖案旋轉的次數,x和y是方塊位置座標

p.update(dia=random.choice(tetris)

,r=random.randrange(4)

,y=0

,x=8

,pause=

false

)# 動作函式 e是操作的屬性名,v是對屬性增減的數值

defact

(e, v)

:# 如果是暫停狀態則退出函式

if p[

"pause"]:

return

# 對操作的屬性增減

p[e]

+= v

# 取得當前旋轉的方塊圖案

h = p[

'dia'

][p[

'r']

%len

(p['dia'])

]# 將4*4的16位二進位制點陣轉換成4行每行12位二進位制點陣

f =# 用位運算的「與」來判斷方塊與場地是否重疊

ifall

(map

(lambda i: f[i]

&fie[p[

'y']

+i]==

0, f)):

# 將二進位制資料轉換成方塊字元並顯示

box[

'text']=

'\n'

.join(

str(

int(

bin(fie[i])[

2:])

+int

(bin

(f.get(i-p[

'y'],0

))[2

:])*

2)[1

:-1]

for i in

range(4

,25))

.translate(mak)

return

true

# 解決方塊處於左右邊緣無法旋轉的問題

if e!=

'r'or

not(act(

'x',-1

)or act(

'x',1)

or act(

'x',2)

):# 對之前的屬性增減反向操作,等於撤銷之前的操作

p[e]

-= v

# 判斷方塊已到底部

if e==

'y':

for i in f:

# 用位運算的「或」來把方塊與場地合併

fie[p[

'y']

+i]|

= f[i]

# 如果一行已填滿,則刪除這一行並在列表頭新增新行

if fie[p[

'y']

+i]==

0xfff

:del fie[p[

'y']

+i] fie.insert(0,

0x801

) p[

"lines"]+=

1# 判斷遊戲結束

if fie[3]

!=0x801

: p.update(pause=

true

,lines=0)

fie[:25

]=[0x801]*

25if

not tkinter.messagebox.askyesno(

"遊戲結束"

,"方塊到頂了,要重新再來一局嗎"):

win.quit(

) init(

)# 定時器函式

deftimeout()

:# 方塊下落一行

act(

'y',1)

# 間隔一定的時間再次呼叫本函式

win.after(

300-p[

"lines"]*

3,timeout)

# 建立遊戲視窗和元件

win = tkinter.tk(

)box = tkinter.label(win,font=

("\u5b8b\u4f53",28

),fg=

"#fc9"

,bg=

"#024"

)box.pack(

)# 繫結鍵盤事件,上鍵是旋轉,左右下鍵是移動,空格鍵是暫停

win.bind('',

lambda e: act(

'r',1)

)win.bind('',

lambda e: act(

'y',1)

)win.bind('',

lambda e: act(

'x',-1

))win.bind('',

lambda e: act(

'x',1)

)win.bind('',

lambda e: p.update(pause=

not p[

"pause"])

)init(

)timeout(

)# 進入視窗訊息迴圈

用Python編寫《唐僧大戰白骨精》簡單小遊戲

遊戲規則 1.無論使用者選擇什麼角色,都會以 唐僧 角色進行遊戲 選擇後會顯示選擇的角色以及攻擊力和生命值 2.唐僧可以進行的選擇有三個 練級 打boss 逃跑 當唐僧選擇練級,生命值和攻擊力會提公升 當唐僧選擇打boss,雙方會交替互相攻擊,直至一方死亡,不可逃跑 當唐僧選擇逃跑,給出提示資訊,退...

用 Python 編寫網路爬蟲 筆記

每個 都應該提供 api,然而這是不可能的 即使提供了 api,往往也會限速,不如自己找介面 robots.txt 中可能會有陷阱 sitemap 中可能提供了重要的鏈結 乙個簡便方法是使用 site example.com 查詢,然而這種方法對於大戰不適用 builtwith 模組 pip ins...

用python來編寫TSP問題

import math from os import path import numpy as np import matplotlib.pyplot as plt class tspinstance 設計乙個類,實現從檔案讀入乙個旅行商問題的例項 檔案格式為 city number best kn...