以前游戲2048火的時(shí)候,正好用其他的語(yǔ)言編寫(xiě)了一個(gè),現(xiàn)在學(xué)習(xí)python,正好想起來(lái),便決定用python寫(xiě)一個(gè)2048,由于沒(méi)學(xué)過(guò)python里面的界面編程,所以寫(xiě)了一個(gè)極其簡(jiǎn)單的無(wú)界面2048。游戲2048的原理和實(shí)現(xiàn)都不難,正好可以拿來(lái)練手,要是不知道這游戲的話(huà),可以去網(wǎng)上查一下,或者下載一個(gè)到手機(jī)來(lái)玩一下,我就不在說(shuō)其原理。我知道不放圖的話(huà)大家一點(diǎn)興趣都沒(méi),下面首先放一張游戲成型圖,然后我們?cè)趤?lái)講如何一步步用最基礎(chǔ)的知識(shí)來(lái)實(shí)現(xiàn)。
一、生成4*4的矩陣
游戲的第一步便是生成一個(gè)4*4的矩陣,當(dāng)作我們游戲的主界面,其實(shí)說(shuō)起來(lái)也比較簡(jiǎn)單,這里用了最原始的方法,直接用
print將其打印出來(lái)。首先我們要生成一個(gè)全為0的4*4二維列表,然后用一些類(lèi)似 '┌ ├└,┤,┘┐│,─,┬,┴'這樣的字符來(lái)組成我們的邊框,下面來(lái)看一下代碼的實(shí)現(xiàn)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
matix = [[ for i in range ()] for i in range ()] # 用列表推導(dǎo)式初始化生成一個(gè)*的列表,列表元素全為 # notzero函數(shù)的作用:游戲界面上非零的時(shí)候才顯示,當(dāng)為的時(shí)候,讓其顯示空, def notzero(s): return s if s! = else ' ' # 非零的話(huà)返回本身,否則返回 ' ' def display(): # 顯示界面函數(shù),用┌ ├└,┤,┘┐│,─,┬,┴ 等顯示邊框,中間顯示*矩陣?yán)锏牡脑?/code> print ("\r\ ┌──┬──┬──┬──┐\n\ │ % s│ % s│ % s│ % s│\n\ ├──┬──┬──┬──┤\n\ │ % s│ % s│ % s│ % s│\n\ ├──┬──┬──┬──┤\n\ │ % s│ % s│ % s│ % s│\n\ ├──┬──┬──┬──┤\n\ │ % s│ % s│ % s│ % s│\n\ └──┴──┴──┴──┘"\ % (notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),\ notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),\ notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),notzero(matix[][]), \ notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),) ) display() |
來(lái)看一下上面代碼的效果,是不是感覺(jué)一個(gè)游戲的框架已經(jīng)到搭好了,由于初始化的時(shí)候,矩陣元素都為零,下面的圖也就沒(méi)有顯示出0,是不是很簡(jiǎn)單,一個(gè)游戲的界面就被我們搭好了,不過(guò)畢竟沒(méi)學(xué)過(guò)界面,所以大家就不要抱怨這界面有多么丑了哈。
二、初始化生成隨機(jī)數(shù)
這個(gè)游戲每次開(kāi)始的時(shí)候都會(huì)隨機(jī)在上面的一個(gè)矩陣中生成兩個(gè)隨機(jī)數(shù)2或4,那么我們要如何來(lái)實(shí)現(xiàn)在上面矩陣中隨機(jī)的一個(gè)位置生成一個(gè)隨機(jī)數(shù)2或4了,當(dāng)然是用到我們前面學(xué)過(guò)的random模塊以及divmod(),下面我們就來(lái)看一下如何用random模塊實(shí)現(xiàn)著一功能。
1
2
3
4
5
6
7
8
9
10
11
12
|
def init(): # 初始化矩陣 initNumFlag = while : k = if random.randrange(, ) > else # 當(dāng)生成隨機(jī)數(shù)大于的時(shí)候k=否則k= 生成和的概率為: s = divmod (random.randrange(, ), ) # 生成矩陣初始化的下標(biāo) 比如divmod(,)的話(huà),s為(,)正好可以作為矩陣下標(biāo) if matix[s[]][s[]] = = : # 只有當(dāng)其值不為的時(shí)候才賦值,避免第二個(gè)值重復(fù) matix[s[]][s[]] = k initNumFlag + = if initNumFlag = = : # 當(dāng)initNumFlag== 的話(huà)表示矩陣?yán)飪蓚€(gè)隨機(jī)數(shù)都已經(jīng)生成了,退出循環(huán) break init() display( ) |
來(lái)看一下上面代碼的效果,是不是已經(jīng)在兩個(gè)隨機(jī)的位置生成了兩個(gè)數(shù),如果大家有時(shí)間的試一下,可以看見(jiàn)每次執(zhí)行的時(shí)候,出現(xiàn)在矩陣上面位置不一樣,而且每次出現(xiàn)的數(shù)也不一樣,因?yàn)槲疑厦嬖O(shè)置了出現(xiàn)2:4的概率為9:1所以大多時(shí)候出現(xiàn)2,這也是游戲的需要。到了這里矩陣已經(jīng)可以動(dòng)起來(lái)了,游戲的功能也可以說(shuō)完成了一半。
三、游戲邏輯部分實(shí)現(xiàn)
如果玩過(guò)這游戲的話(huà)就知道,游戲中每次向上下左右移動(dòng)的時(shí)候,比如像下移動(dòng)的話(huà),所有的數(shù)都會(huì)向下移動(dòng),碰到相同的數(shù),就會(huì)成一個(gè)新的數(shù),比如2和2碰到的話(huà),就會(huì)生成4,然后再隨機(jī)在其他位置生成一個(gè)2或4 ,同理4和4碰到的話(huà)也會(huì)生成8,直到合成了2048游戲就算成功了,或者說(shuō)矩陣中的數(shù)字都不能移動(dòng)那就是Game Over。當(dāng)然我們?cè)谑謾C(jī)上玩游戲的話(huà),隨便滑動(dòng)一下,所有的數(shù)字就可以向其中一個(gè)方向滑動(dòng),但是這里沒(méi)有界面,條件比較艱苦,所以只能從控制臺(tái)讀入用戶(hù)輸入的字母,然后一個(gè)個(gè)來(lái)判斷是向哪里移動(dòng)了,所以我們要寫(xiě)4個(gè)函數(shù)來(lái)分別處理用戶(hù)的上下左右移動(dòng),讓后一個(gè)函數(shù)處理在每次用戶(hù)移動(dòng)后,如何添加一個(gè)隨機(jī)數(shù),下面先寫(xiě)一段偽代碼來(lái)解釋流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
def addRandomNum(): #每次移動(dòng)后隨機(jī)在矩陣中在生成一個(gè)數(shù) pass def moveDown(): #向上移動(dòng)的處理函數(shù) pass <br> addRandomNum() #移動(dòng)處理完成后,隨機(jī)生成一個(gè)數(shù) def moveLeft(): #向左移動(dòng)的處理函數(shù) pass addRandomNum() def moveUp(): #向上移動(dòng)的處理函數(shù) pass addRandomNum() def moveRight(): #向右移動(dòng)的處理函數(shù) pass addRandomNum() def main(): while flag: #定義一個(gè)死循環(huán),不斷讀入用戶(hù)的輸入,然后在做判斷,看是向哪里移動(dòng) d = input (' (↑:w) (↓:s) (←:a) (→:d),q(uit) :“) if d = = 'a' : moveLeft() elif d = = 's' : moveDown() elif d = = 'w' : moveUp() elif d = = 'd' : moveRight() elif d = = 'q' : break else : pass |
上面是一段為了理解的偽代碼,下面我們來(lái)看一下如何實(shí)現(xiàn)移動(dòng)處理函數(shù),這里是整個(gè)游戲中最難處理的部分,完成了這一部分的話(huà),整個(gè)游戲也就基本上實(shí)現(xiàn)了,這里我以向下的移動(dòng)處理函數(shù)為例,其他的都一樣,當(dāng)用戶(hù)輸入向下移動(dòng)的時(shí)候,所有的數(shù)字都向下移動(dòng),如果碰到相同的數(shù)字要和并,有數(shù)字的方塊向沒(méi)有數(shù)字的方塊移動(dòng)。這里需要用循環(huán)實(shí)現(xiàn),有4列所以最外層的循環(huán)有4次,每一列里面又需要循環(huán)處理,下面來(lái)看一下具體怎么實(shí)現(xiàn),
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
def addRandomNum(): # 跟初始化生成隨機(jī)數(shù)一樣,只不過(guò)這里只是生成一個(gè)隨機(jī)數(shù) while : k = if random.randrange(, ) > else s = divmod (random.randrange(, ), ) if matix[s[]][s[]] = = : matix[s[]][s[]] = k break display() # 隨機(jī)數(shù)添加完成后就直接調(diào)用顯示函數(shù),直接顯示一下游戲界面 def moveDown(): #處理向下移動(dòng)的函數(shù) for i in range (): #外層次循環(huán)處理例,內(nèi)層兩個(gè)層循環(huán),來(lái)處理相鄰的兩個(gè)數(shù) for j in range (, , - ): for k in range (j - , - , - ): if matix[k][i] > : # 從最下面的數(shù)開(kāi)始處理相鄰的兩個(gè)數(shù) if matix[j][i] = = : matix[j][i] = matix[k][i] # 如果下面的數(shù)為空,上面的數(shù)字不為空就移動(dòng)上面的數(shù)為下面的數(shù) matix[k][i] = elif matix[j][i] = = matix[k][i]: # 如果相鄰的兩個(gè)數(shù)相等的話(huà),就和并,并把上面的輸置零,下面的數(shù)變成兩倍 matix[j][i] * = matix[k][i] = break addRandomNum() # 移動(dòng)完成后再隨機(jī)生成一個(gè)數(shù) |
寫(xiě)完了向下移動(dòng)的處理函數(shù),那么向其他方向的移動(dòng)函數(shù)也一樣,照著寫(xiě),就可以,到這里游戲中最難的部分就完成,可以說(shuō)勝利就在眼前了,好了在這之前,我們還需要處理一下其他問(wèn)題,那就是每次移動(dòng)后都要檢查,游戲是不是Game Over了,還有就是定義一個(gè)變量來(lái)紀(jì)錄分?jǐn)?shù)了,這些實(shí)現(xiàn)起來(lái)都比較簡(jiǎn)單。
四、游戲紀(jì)錄分?jǐn)?shù)和檢查游戲是否結(jié)束
游戲結(jié)束的標(biāo)志是矩陣中所有的數(shù)都不為0,而且所有相鄰的數(shù)都不能合并,根據(jù)這個(gè)我們就可以來(lái)寫(xiě)一個(gè)函數(shù)來(lái)判斷游戲是否GG,至于分?jǐn)?shù)紀(jì)錄,我們只需定義一個(gè)變量,然后每次有何并的時(shí)候,就加上一定的分?jǐn)?shù)即可。下面我們來(lái)看檢查函數(shù)的實(shí)現(xiàn)。
1
2
3
4
5
6
7
|
def check(): for i in range ( 4 ): #按每一排循環(huán)4 次 for j in range ( 3 ): # 如果矩陣中有0存在,或者有相鄰的數(shù)就表示游戲還可以繼續(xù)經(jīng)行,否則就是GG if matix[i][j] = = 0 or matix[i][j] = = matix[i][j + 1 ] or matix[j][i] = = matix[j + 1 ][i]: return True else : return False |
五、完整游戲源碼
完成了上面的部分,整個(gè)游戲的過(guò)程就實(shí)現(xiàn)了,下面附上整個(gè)游戲的源碼。游戲還有很多不夠完善的地方,比如說(shuō)游戲中如果出現(xiàn)2048的話(huà),就表示玩家勝利,游戲結(jié)束,但是我這里沒(méi)有做處理,所以這個(gè)游戲可以一直玩到4096....沒(méi)有結(jié)束,除非你游戲中GG了,要處理也很簡(jiǎn)單,還可以將矩陣存在文件中,完成一個(gè)游戲存檔的功能。有興趣的話(huà)大家去實(shí)現(xiàn)一下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
import random score = 0 # 紀(jì)錄游戲的分?jǐn)?shù) matix = [[ 0 for i in range ( 4 )] for i in range ( 4 )] # 初始化生成一個(gè)4*4的列表 def notzero(s): return s if s ! = 0 else '' def display(): print ("\r\ ┌──┬──┬──┬──┐\n\ │ % 4s │ % 4s │ % 4s │ % 4s │\n\ ├──┬──┬──┬──┤\n\ │ % 4s │ % 4s │ % 4s │ % 4s │\n\ ├──┬──┬──┬──┤\n\ │ % 4s │ % 4s │ % 4s │ % 4s │\n\ ├──┬──┬──┬──┤\n\ │ % 4s │ % 4s │ % 4s │ % 4s │\n\ └──┴──┴──┴──┘" \ % (notzero(matix[ 0 ][ 0 ]), notzero(matix[ 0 ][ 1 ]), notzero(matix[ 0 ][ 2 ]), notzero(matix[ 0 ][ 3 ]), \ notzero(matix[ 1 ][ 0 ]), notzero(matix[ 1 ][ 1 ]), notzero(matix[ 1 ][ 2 ]), notzero(matix[ 1 ][ 3 ]), \ notzero(matix[ 2 ][ 0 ]), notzero(matix[ 2 ][ 1 ]), notzero(matix[ 2 ][ 2 ]), notzero(matix[ 2 ][ 3 ]), \ notzero(matix[ 3 ][ 0 ]), notzero(matix[ 3 ][ 1 ]), notzero(matix[ 3 ][ 2 ]), notzero(matix[ 3 ][ 3 ]),) ) def init(): # 初始化矩陣 initNumFlag = 0 while 1 : k = 2 if random.randrange( 0 , 10 ) > 1 else 4 # 隨機(jī)生成 2 或 4 s = divmod (random.randrange( 0 , 16 ), 4 ) # 生成矩陣初始化的下標(biāo) if matix[s[ 0 ]][s[ 1 ]] = = 0 : # 只有當(dāng)其值不為0的時(shí)候才賦值,避免第二個(gè)值重復(fù) matix[s[ 0 ]][s[ 1 ]] = k initNumFlag + = 1 if initNumFlag = = 2 : break display() def addRandomNum(): #處理完移動(dòng)后添加一個(gè)新的隨機(jī)數(shù) while 1 : k = 2 if random.randrange( 0 , 10 ) > 1 else 4 s = divmod (random.randrange( 0 , 16 ), 4 ) if matix[s[ 0 ]][s[ 1 ]] = = 0 : matix[s[ 0 ]][s[ 1 ]] = k break display() def check(): #檢查游戲是否GG for i in range ( 4 ): for j in range ( 3 ): if matix[i][j] = = 0 or matix[i][j] = = matix[i][j + 1 ] or matix[j][i] = = matix[j + 1 ][i]: return True else : return False def moveRight(): # 向右移動(dòng)處理函數(shù) global score for i in range ( 4 ): for j in range ( 3 , 0 , - 1 ): for k in range (j - 1 , - 1 , - 1 ): if matix[i][k] > 0 : if matix[i][j] = = 0 : matix[i][j] = matix[i][k] matix[i][k] = 0 elif matix[i][j] = = matix[i][k]: matix[i][j] * = 2 score + = matix[i][j] #將當(dāng)前數(shù)作為score加上 matix[i][k] = 0 break addRandomNum() def moveUp(): global score for i in range ( 4 ): for j in range ( 3 ): for k in range (j + 1 , 4 ): if matix[k][i] > 0 : if matix[j][i] = = 0 : matix[j][i] = matix[k][i] matix[k][i] = 0 elif matix[k][i] = = matix[j][i]: matix[j][i] * = 2 score + = matix[j][i] matix[k][i] = 0 break addRandomNum() def moveDown(): global score for i in range ( 4 ): for j in range ( 3 , 0 , - 1 ): for k in range (j - 1 , - 1 , - 1 ): if matix[k][i] > 0 : if matix[j][i] = = 0 : matix[j][i] = matix[k][i] matix[k][i] = 0 elif matix[j][i] = = matix[k][i]: matix[j][i] * = 2 score + = matix[j][i] matix[k][i] = 0 break addRandomNum() def moveLeft(): global score for i in range ( 4 ): for j in range ( 3 ): for k in range ( 1 + j, 4 ): if matix[i][k] > 0 : if matix[i][j] = = 0 : matix[i][j] = matix[i][k] matix[i][k] = 0 elif matix[i][j] = = matix[i][k]: matix[i][j] * = 2 score + = matix[i][j] matix[i][k] = 0 break addRandomNum() def main(): print ( " \033[33;1mWelcome to the Game of 2048!\033[0m" ) flag = True init() while flag: #循環(huán)的標(biāo)志 print ( ' \033[33;1m You Score:%s\033[0m' % (score)) d = input ( '\033[33;1m (↑:w) (↓:s) (←:a) (→:d),q(uit) :\033[0m' ) #不斷處理用戶(hù)輸入 if d = = 'a' : moveLeft() if not check(): #檢查游戲是否GG print ( 'GG' ) flag = False #GG的話(huà)直接退出 elif d = = 's' : moveDown() if not check(): print ( 'GG' ) flag = False elif d = = 'w' : moveUp() if not check(): print ( 'GG' ) flag = False elif d = = 'd' : moveRight() if not check(): print ( 'GG' ) flag = False elif d = = 'q' : # 退出 break else : # 對(duì)用戶(hù)的其他輸入不做處理 pass if __name__ = = '__main__' : main() |
最后在附上一張圖片最為結(jié)束
以上所述是小編給大家介紹的用Python寫(xiě)一個(gè)無(wú)界面的2048小游戲,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!