前些天在b站上看到有個大佬用c寫了一個2048小遊戲,我便一下來了興趣。心想着,我貌似也能用Python來整一波,話很少說,直接開搞。
2048的遊戲規則:
2048遊戲共有16個格子,初始時會有兩個格子上安放了兩個數字2,每次能夠選擇上下左右其中一個方向去滑動,每滑動一次,全部的數字方塊都會往滑動的方向靠攏外,系統也會在空白的地方隨即出現一個數字方塊,相同數字的方塊在靠攏、相撞時會相加。系統給予的數字方塊不是2就是4,玩家要想辦法在這小小的16格範圍中湊出「2048」這個數字方塊
python
我們能夠從遊戲規則裏面一步一步來:數組
第一步:框架
2048遊戲共有16個格子,初始時會有兩個格子上安放了兩個數字2
這一步比較簡單,咱們能夠創建一個二維數組,而後隨機在上面放上兩個數字2
用代碼就能夠這麼寫:
spa
list1=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] def map1(map_list): count=0 while(count<2): a=r.randint(0,3) b=r.randint(0,3) if map_list[a][b]==0: map_list[a][b]=2 count+=1
第二步:code
每次能夠選擇上下左右其中一個方向去滑動,每滑動一次,全部的數字方塊都會往滑動的方向靠攏,相同數字的方塊在靠攏、相撞時會相加。orm
這一步就是這個遊戲裏,比較複雜的地方了。這裏涉及到兩種運算,我稱之爲,去0運算和合並運算blog
去0運算:
咱們先從最簡單的2—0開始寫:
開始是這樣:
遊戲
咱們要假設要進行上滑操做,使其變成這樣:
這裏咱們能夠看到在(2,1)的地方的2,上滑到了(1,1),那麼咱們來寫代碼:
圖片
def qu0(dire,list1):#去0運算,w,a,s,d分別表示各個方向 if (dire=="w" or dire=="W"): #h表示行,s表示列 for s in range(4): for h in [3,2,1]: elif(list1[h-1][s]==0): list1[h-1][s]=list1[h][s] list1[h][s]=0 if (dire=="s" or dire=="S"): for s in range(4): for h in [0,1,2]: elif(list1[h+1][s]==0): list1[h+1][s]=list1[h][s] list1[h][s]=0 if (dire=="a" or dire=="A"): for h in range(4): for s in [3,2,1]: elif(list1[h][s-1]==0): list1[h][s-1]=list1[h][s] list1[h][s]=0 if (dire=="d"or dire=="D"): for h in range(4): for s in [0,1,2]: elif(list1[h][s+1]==0): list1[h][s+1]=list1[h][s] list1[h][s]=0
這裏咱們經過看本身格子的前一個格子裏的數字是否爲0,若是是,那麼咱們就把這個格子裏的數字移動到前一個格子裏。input
合併運算:
相同數字的方塊在靠攏、相撞時會相加
(示意圖就不給畫了,大家應該都能想象,orz )
先上代碼
def heB(dire,list1): if (dire=="w" or dire=="W"): for s in range(4): for h in [3,2,1]: elif(list1[h][s]==list1[h-1][s] ): #合併運算 list1[h-1][s]=list1[h-1][s]*2 list1[h][s]=0 if (dire=="s" or dire=="S"): for s in range(4): for h in [0,1,2]: elif(list1[h][s]==list1[h+1][s] ): list1[h+1][s]=list1[h+1][s]*2 list1[h][s]=0 if (dire=="a" or dire=="A"): for h in range(4): for s in [3,2,1]: elif(list1[h][s]==list1[h][s-1]): list1[h][s-1]=list1[h][s-1]*2 list1[h][s]=0 if (dire=="d"or dire=="D"): for h in range(4): for s in [0,1,2]: elif(list1[h][s]==list1[h][s+1]): list1[h][s+1]=list1[h][s+1]*2 list1[h][s]=0
這裏咱們仍然仍是看格子的前一個數字,若是格子裏的前一個數字跟格子裏的數字相同,那麼就要把原來的格子裏的數字變爲0,格子裏的前一個數字翻倍(相加)。
瞭解完2048的這兩種運算,咱們就要開始研究斷定順序了,研究斷定順序須要拿出一個極端的例子好比下面這個:
咱們使這個這個二維數組往上相加,它經歷的過程以下:
第一步:
第二步:
第三步:
由上可見,即便是最極端的例子也只進行了2次合併運算,因此咱們能夠得出結論,在2048進行運算時的順序是 去0運算——合併運算——去0運算——合併運算
因此咱們能夠寫出下面的代碼:
def move(dire,list1): # h表示行 s表示列 qu0(dire,list1) heB(dire,list1) qu0(dire,list1) heB(dire,list1)
那麼,最繁瑣的移動過程就這麼結束嘍(鼓掌,啪啪啪),接下來就是產生隨機數了
第三步:
系統會在空白的地方隨即出現一個數字方塊,系統給予的數字方塊不是2就是4
這玩意兒挺簡單的,咱們可讓系統隨機生成一個座標地址,而後咱們再檢驗這個座標地址內的數字是否爲0。若是爲0,就隨機填一個2或4進去,若是不爲0,那我們就再隨機生成一個座標地址,而後接着檢驗,直到這個座標內的數字爲0
代碼以下:
def mainmap(map_list): count = 0 while (count < 1): a = r.randint(0, 3) b = r.randint(0, 3) if map_list[a][b] == 0: c = r.choice([2, 4]) map_list[a][b] = c count += 1
寫到這,一個基本的框架就差很少完成了,接下來就是斷定遊戲勝負的時候了
第四步:
玩家在這小小的16格範圍中湊出「2048」這個數字方塊,就能斷定爲遊戲的勝利。若是這個16格的範圍內,已經沒有空間(0)能夠移動了,那麼遊戲就斷定爲失敗。
這其實咱們只須要遍歷每一個表格中的數字,若是有一個數字爲2048,就斷定勝利,全部表格中,沒有一個表格裏的數字爲0,就斷定失敗。
代碼以下:
def panding(list1): panding = 0 count = 0 for i in list1: for b in i: if (b == 2048): panding = 1 if (b == 0): count = 1 if (panding == 1): print("恭喜您,挑戰成功") input() break if (count == 0): print("真遺憾,挑戰失敗") input() break
到這邊,2048的遊戲已經能夠正常的玩耍了,可是浪漫的人不能知足於此, 咱們來給表格添上一個好看 的框框
def kuangkuang(list1): print("+----+----+----+----+") for i in list1: a=i[0] b=i[1] c=i[2] d=i[3] print("| | | | |") print("| {0} | {1} | {2} | {3} |".format(a,b,c,d)) print("+----+----+----+----+")
終於,咱們終於把它給攻佔完了(撒花)
最後讓咱們把它們拼接在一塊兒吧
def main(): print("哇呼,你發現了一個2048,要不要進行遊戲") input() print("1.好的 2.沒問題 3.棒極了") input() print("請使用wasd進行操做,w爲往上滑,s爲往下滑,a爲往左滑,d爲往右滑") input() print("那麼,遊戲開始嘍。") map1(list1) while True: dire = input("請輸入方向:") if dire == "abc": break move(dire, list1) mainmap(list1) kuangkuang(list1) panding(list1)
Nice!結束嘍,下次見,88!