今天來分析一個益智遊戲,數字華容道。
當初對這個遊戲頗有印象還是在最強大腦節目上面,何猷君以幾十秒就完成了這個遊戲。前幾天寫2048的時候,又想起了這個遊戲,想着來研究一下。
遊戲玩法用盡量少的步數,盡量短的時間,将棋盤上的數字方塊,按照從左到右、從上到下的順序重新排列整齊。
效果圖
第一種是通過鍵盤的按鍵來移動數字,比如按上鍵,需要做的操作是把13移上去。
第二種是通過鼠标點擊13,13移上去。不論采取哪種操作方式,可移動數字隻能往固定的方向移動,做的操作都是把13和0位置互換即可。考慮到操作性,我們選用鼠标點擊這種更為簡單的操作方式。
定義棋盤的大小:4 * 4, 當然我把這個棋盤的大小做成了可自定義的屬性,如果你覺得4*4沒有挑戰性, 還可以5 * 5 、6 * 6等等,下面以4 * 4為例做介紹。
看過我之前2048那篇文章的,一定明白接下來應該怎麼做。沒錯,忽略棋盤背景,把棋盤看作一個4*4的二維矩陣,空白格用數字0填充:
接下來,我們應該考慮的問題是,數字的移動該怎麼做?看上圖的狀态,此時隻有0的上,右,下三格可以移動,别的都不能動。這裡大家可以停頓一下考慮考慮,看看能不能找到一個移動的算法方案?
數字移動通過數字在二維矩陣中的下标來表示數字的位置,比如8的位置是第一行、第一列即(0,0)(列表元素的下标從0開始), 第二行、第一列是(1, 0)。可以看下圖:
圖中,13的坐标是(3,0)。當鼠标點擊13時,13和0交換位置,13的位置變成(2,0)。從(3,0)到(2,0)可以看作加了一個矢量(-1,0)。那如果點擊不是13, 而是(1,0)位置的3,發生的變化就是(1,0)變成(2,0),矢量是(1,0),同理(2,1)位置移到(2, 0) 矢量是(0, -1),我們得到了一個上下左右的矢量集合, 上(-1, 0), 下(1, 0), 左(0, -1), 右(0, 1) 。
遊戲的邏輯就變成了,當我們随便點擊一個數字時,判斷該數字的位置分别在加上4個矢量後的位置上的數字是否為0,是0,就把兩個位置的數字交換,不是0,不做任何變動即可。
為什麼會變成這樣,因為一個數字可移動的方向隻有0個或者1個。
數據矩陣存放縷清了遊戲的邏輯,那在記錄數據二維矩陣時,就需要記錄每個數字在矩陣中的位置下标。所以我們不打算采用2048中的矩陣的記錄方式,而是采用python中的dict, 把位置作為key,把數字作為value。
整個操作的邏輯就是,當我們鼠标點擊時,首先獲取點擊的坐标(x, y),通過坐标(x, y),獲取到點擊了哪一行,哪一列,得到(row_index, col_index)。然後把(row_index, col_index)分别加四個矢量, 判斷加矢量後的位置(row_index vector, col_index vector) 在不在上圖中的dict中且值是否等于0, 如果等于0, 使(row_index, col_index) 和 (row_index vector, col_index vector)的值互換。
如何判斷遊戲勝利?判斷dict中的最後一位是否為0,且0之前的所有值,是否按照順序排序, 即為勝利。字典考慮到需要順序,所以可以采用collections庫中的OrderedDict 有序字典的數據格式。
代碼開撸1. 定義全局變量
2. 定義邏輯,初始化棋盤數據
在初始化過程中,首先要生成一個已勝利的數據順序,然後随機移動一千次。如果是随機生成數據,有可能數據無解。
3. 初始化點擊數據,和移動邏輯
4. 點擊移動和判斷遊戲勝利的邏輯
5. 監控事件,自定義了定時器,記錄遊戲時間。監控鼠标點擊事件,獲取坐标,移動數字。
6. 主函數
不到兩百行,代碼完成。完整源代碼私信回複 華容道 即可獲取。
遊戲運行
2048文章鍊接:用python寫遊戲之 2048
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!