夜市麻將賓果

heron yang's production

簡介

台灣夜市裡有個麻將賓果遊戲,規則簡單也總是有客人源源不絕,雖說是遊戲,但卻有跟魔術一樣的神奇效果。

遊戲設備

  • 36個麻將
  • 6×6的麻將牌

遊戲玩法

  1. 所有翻到背面後洗牌
  2. 玩家選15張牌
  3. 將15張牌放到麻將牌上
  4. 若聯成至少一條線,可以得到娃娃當獎品

獲勝機率分析

由於麻將牌上每一張牌是不同的,其機率跟我們想像有張6×6的棋盤,隨機選15格造成連線的機率是相同的。於是我們可以套用高中所學的機率,如下:

C^6_6 \times C^{30}_9 \times \frac{ 6+6+2 }{ C^{36}_{15} } = 3.597\%

其中C^6_6表示六個格子成一條線,C^{30}_9表示剩格子隨意選9個(從原本15個已經被選掉6個),6+6+2表示成線的數量,直的橫的各6條,加上2條對角線,最後C^{36}_{15}是36格選15格的所有可能量(由於出現兩條以上後重複計算的情況發生機率小,所以不列入計算)。

透過程式採樣驗證我的數值接近實際值:

#!/usr/bin/python

import random

SAMPLE_AMOUNT = 1000000

CHESS_TOTAL_AMOUNT = 36
CHESS_PICKED_AMOUNT = 15
CHESS_BOARD_SIZE = 6

def grab_random_chesses():
    return random.sample(range(CHESS_TOTAL_AMOUNT), CHESS_PICKED_AMOUNT)

def lines_found(chesses):

    ans = 0

# Horizontal lines.
    for i in range(CHESS_BOARD_SIZE):
        fail = False
        for j in range(CHESS_BOARD_SIZE):
            pos = CHESS_BOARD_SIZE * i + j
            if not pos in chesses:
                fail = True
                break

        if not fail:
            ans += 1

# Vertical lines.
    for i in range(CHESS_BOARD_SIZE):
        fail = False
        for j in range(CHESS_BOARD_SIZE):
            pos = CHESS_BOARD_SIZE * j + i
            if not pos in chesses:
                fail = True
                break

        if not fail:
            ans += 1

# Diagonal lines 1.
    ans += 1
    for i in range(CHESS_BOARD_SIZE):
        pos = CHESS_BOARD_SIZE * i + i
        if not pos in chesses:
            ans -= 1
            break

# Diagonal lines 2.
    ans += 1
    for i in range(CHESS_BOARD_SIZE):
        pos = CHESS_BOARD_SIZE * i + (CHESS_BOARD_SIZE - i - 1)
        if not pos in chesses:
            ans -= 1
            break

    return ans

def debug(chesses):

    chesses.sort()
    print chesses

    for i in range(CHESS_BOARD_SIZE):
        for j in range(CHESS_BOARD_SIZE):
            pos = CHESS_BOARD_SIZE * i + j
            if pos in chesses:
                print ' * ',
            else:
                print ' - ',
        print

    print 'lines', lines_found(chesses)

def main():

    success = 0
    for i in range(SAMPLE_AMOUNT):
        chesses = grab_random_chesses()
        if lines_found(chesses) >= 1:
            success += 1

        # debug(chesses)
        # raw_input("Press Enter to continue...")

    print 'success' , success
    print 'percentage', 100.0 * success / SAMPLE_AMOUNT

if __name__ == '__main__':
    main()

得到:

> python night_market_game.py
success 3667
percentage 3.667

獲利模型

有了勝率之後剩下就很簡單了,由於老闆長期在夜市擺攤,雖然對我們客人來說,玩一兩次有無中獎意義重大,但對老闆來說,很多客人光臨讓勝率更接近實際值(機率在較大的數目下較接近我們計算出來的數值)。
已知玩一場計費20元、獎品娃娃一隻200元、玩家勝率3.597%,我們可以得知玩一場實際上:

  • 成本:200 × 3.597% = 7.194(元)
  • 營收:20元
  • 獲利:12.806元

賭博心理

當我們把背後的數學搞懂之後,剩下來就是瞭解為什麼我們還是會去玩這樣的遊戲,而不外乎就跟賭博是一樣的道理。在我去過的賭場其實可以拿遊戲規則的紙,上面甚至會直接告訴你期望值,且當然每一個都是負的,所以賭場只要有客人必定賺錢,但賭客們還是源源不絕的前往奉錢。
而人對於最後獲得獎品的慾望太強烈,混雜貪婪心理、僥倖心理、不服輸心理等,同時遊戲的複雜或是包裝掩蓋住背後的事實,加上「別人有贏」的心理影響等等,讓人難耐住一玩再玩的衝動,至於賭博相關心理的細節就不在這篇文章中的範疇了。

遊戲破解

一般情況下,通常會有差一個或兩個就連成線的情況。於是,帶幾位朋友,針對快連線的幾個麻將,大家各別分配幾顆然後盯住,在老闆洗牌過後仍知道位置,接著再下一回合時,除了馬上把這幾顆選出來之外,剩下的盡量選上一次沒有選過的牌。
這個方式不能保證獲勝,但可以提升獲勝機率,以下以成功記住原本快連線的牌,且剩餘都選先前沒選過的牌的情況為基準,得勝率:

若原本已經有五個(差一個就連線): \frac{ C^{20}_9 }{ C^{21}_{10} } = 47.619\%
若原本已經有四個(差兩個就連線): \frac{ C^{20}_9 }{ C^{22}_{11} } = 23.810\%

(由於出現兩條以上後重複計算的情況發生機率小,所以不列入計算)

參考資料

廣告

讀心術 – 數字

簡介

魔術師大衛(David Blaine)在電視上的讀心術表演。

表演方式

  • 魔術師請觀眾想一個數字但不說出口:「請想一個數字介於50到100之間,注意兩個位數要都是整數,而且兩個數字要不相同,想好了嗎?」
  • 觀眾:「好了!」
  • 魔術師:「是68嗎?」
  • (猜中)

表演變化與細節

  1. 變更講出答案的方式:可以先把68寫在紙上再翻面讓觀眾看到,配合上動作張力較大。
  2. 變更題目:以下另外有幾題,
    • 介於1到50之間,兩位皆為奇數,且兩位不相同的數字:答案為37
    • 介於1到10之間的數:答案為7
    • 介於1到4之間的數:答案為3
    • 介於1到1000之間的數:答案為333
  3. 須留好猜錯的退路。

原理分析

魔術裡的原理包含認知偏誤(Cognitive Bias)中的「首因效應(Primacy Effect)」、直覺與統計。

首因效應(Primacy Effect)

Serial_position

首因效應即是在講先入為主的概念,人會對於先讀到的資訊保有較高的印象,而用在這裡即是魔術師的第一句話:「選擇50到100之間的數」,於是觀眾會一直把關注重心放在數值範圍很大這件事情上,即使後來加設很多條件讓範圍變小,觀眾仍會覺得他是在一個約莫50的數值範圍中猜測(實際上只有八個數字)。

#!/usr/bin/python

for i in range(50, 100):

    v1 = i / 10
    v2 = i % 10

# should both be even
    if v1 % 2:
        continue
    if v2 % 2:
        continue

# should be two different digits
    if v1 == v2:
        continue

    print i

可得到:

>> python value_domain.py
60
62
64
68
80
82
84
86

直覺

從Apple在人機介面上的成功之後,介面上按鈕位置、使用者中心思考等變成很重要的議題,其中各種問題建立在使用者在不同情境下,會有不同的想法與情緒,而透過反覆的討論、設計與驗證,我們可以漸漸設計出一個所謂「符合直覺」的介面。
在這魔術中不外乎運用類似的道理,由於我們人多半經歷過相同或類似的學習,所以在面對選擇時候,會拿建立在這些經歷上去做選擇,所以在60、62、64、68、80、82、84、86數字之間,我們選了68。這慨念跟以下問題是一樣的概念:

  • 用直覺選一個顏色:多數人會選「紅色」
  • 用直覺選一種蔬菜:多數人會選「紅蘿蔔」

統計

直覺雖然存在我們腦中,而除了反覆去討論原因以外,「統計」也是去了解他的方式之一,用逆向工程的概念,可以知道多數人在這樣的情況下會回答68。然而,沒有錯,仍有「少數人」不會回答68。

魔術失敗

上述三個原理都有可能會造成對應的魔術失敗,包含以下的可能:

  • 觀眾聽錯題目:若魔術師沒有好好表達、確認觀眾有聽正確,即可以造成觀眾沒有聽對,像是選成78
  • 觀眾聯想到過往經驗中的數字:他可能會直接回答另一個數字,而魔術師沒有把這件事情預料進來
  • 表演過程中或之前出現其他數字影響:比如表演環境中出現84,觀眾會很直接的選用了

待了解的問題

以外有幾點我覺得需要更深入的了解:

  • 部分網路資料寫人會選擇靠近數值中間的數字,是否真有其事?而又是建立在什麼基礎上?
  • 實際上是多少人會選68?是否可以進行更大量調查?

結語

這魔術很有趣,因為不用任何道具、只需要一張嘴就可以達到很好的效果,我自己與約莫十個朋友玩過之後,大概80%的成功機率,也就是說過程中要顧慮好20%失敗的可能。

參考資料