撲克牌發牌程式是一個很有趣的清單應用實例,把52張牌的內容建立為一個清單,就可以自由地在程式中操作這些牌了,在這一篇文章中就來說明如何運用清單以及隨機數的功能來建立一個有趣的簡單發牌程式。

這個APP的介面安排如下:

另外,因為會使用到52牌的內容以及一張背面圖,所以需要事先就上傳共53張圖形檔。在我們的例子中,0.jpg是背面(其實是鬼牌拿來當做背面用),而1.jpg到52.jpg則分別是依照順序排好的牌面:

因為撲克牌共有52張牌,因此第一步要建立一個清單,然後把52張牌依序放到清單中,為了簡化程式,在這裡很單純地把牌做了編號,就從1到52號,先建立一個可以放牌的清單deck:

在清單使用之前,也是先清除清單的內容:

然後透過一個迴圈,把數字依序放進去(1到52):

同樣地,也是把它們放到Screen1的初始化事件以及重新開始的按鈕事件中,以下是重新開始按鈕事件的程式積木:

先不考慮隨機數,可以透過以下的方式,把前五張牌放到按鈕背景圖中:

在上面的程式中,使用一個for each迴圈,讓number從1數到5,透過select list item的方式,依序從 deck中取出第number個內容,拿到之後,使用join函數把這個數字和".jpg"合併在一起,讓它成為圖形檔名,接著再以這個檔名設定到相對應的按鈕之背景圖形中,以下是程式的執行結果:

由上面可以看出來,前面五張圖是依序排列好的。如果要亂數發牌的話,很多同學第一個想法就是透過隨機數來拿,只要拿5次就可以了,把發牌按鈕中的程式改為如下的樣子:

這樣可以做到隨機發牌,但是卻不能避免拿到重複牌的情況發生。為了避免重複拿到牌,有一種做法是再建立一個清單用來存放目前拿到的牌的內容,然後在正式發一張牌下去之前,一定要確定此牌是否已經存在了,如果存在的話,就要重新取牌,直到不重複為止,先宣告一個清單變數hold用來存放目前已經發出去的牌,而另一個變數target則是接下來想要發出去的牌:

開始發牌時,第一步要把hold清單的內容清空:

接著以一個條件式迴圈來控制,一直找到沒有發過的牌才會離開迴圈:

離開迴圈的條件是目前找到的target並不存在於hold清單中,要特別注意的是,在真正進行牌面設定之前,一定要把target放進hold才可以避免此牌被重複取用:

以下是完整的程式:

另外一個發牌邏輯和上面的方式不一樣,它不考慮重複發牌的問題,而是直接去打亂原有在deck清單中的52張牌,因為只是打亂順序,就可以保證不會有重複的牌出現,在牌被打亂之後,最後再直接取出前5張牌就可以了。以下是隨機交換2張牌內容的方式:

交換兩張不夠,要交換至少100次才行:

交換完畢之後再把5張顯示出來,就是隨機發牌的內容了:

看起來很長對嗎?沒關係,我們有procedure(自訂程序)可以使用,先設定一個procedure叫做shuffle,如下:

然後再於迴圈中呼叫shuffle這個procedure就可以了:

這樣是不是簡單多了?

 

(1273)