Đại Diễn Pháp Là Gì — Thuật Toán Bói Kinh Dịch Cổ Đại Với 50 Thẻ Thi

Đại Diễn Pháp (大衍法) — Yarrow Stalk Oracle

1. Nguồn Gốc

Đại Diễn Pháp (大衍法, Dà Yǎn Fǎ) là phương pháp bói Kinh Dịch cổ xưa nhất còn tồn tại, được mô tả trong chương Hệ Từ Truyện (繫辭傳 Xìcí Zhuàn) — phần phụ lục triết học của Kinh Dịch, có niên đại khoảng 300-200 TCN (Chiến Quốc).

Nguyên văn cổ:

大衍之數五十,其用四十有九。
Dà yǎn zhī shù wǔshí, qí yòng sìshí yǒu jiǔ.

"Số đại diễn là năm mươi, sử dụng bốn mươi chín."

分而為二以象兩,掛一以象三,揲之以四以象四時,
歸奇於扐以象閏。五歲再閏,故再扐而後掛。

Fēn ér wéi èr yǐ xiàng liǎng, guà yī yǐ xiàng sān,
shé zhī yǐ sì yǐ xiàng sì shí,
guī qí yú lè yǐ xiàng rùn.
Wǔ suì zài rùn, gù zài lè ér hòu guà.

2. Ý Nghĩa Triết Học

Mỗi bước trong Đại Diễn Pháp đều mang tượng trưng vũ trụ luận:

  • 50 thẻ = Số Đại Diễn — con số bao trùm vạn vật
  • 1 thẻ bỏ ra = Thái Cực (太極) — nguồn gốc chưa phân chia, không sử dụng
  • 49 thẻ sử dụng = Số của Dụng — vạn vật từ Thái Cực sinh ra
  • Chia 2 nhóm = Lưỡng Nghi (兩儀) — Âm-Dương, Trời-Đất
  • Rút 1 thẻ = Tam Tài (三才) — Trời-Đất-Người
  • Đếm theo 4 = Tứ Thời (四時) — 4 mùa Xuân-Hạ-Thu-Đông
  • Phần dư = Nhuận (閏) — tháng nhuận trong lịch âm

3. Quy Trình 18 Bước (3 Biến × 6 Hào)

Mỗi quẻ Kinh Dịch có 6 hào. Mỗi hào cần 3 lần "biến" (操作, thao tác). Tổng cộng: 6 hào × 3 biến = 18 bước.

3.1. Một Biến (1 iteration):

  1. Bắt đầu với N thẻ thi (lần đầu: 49; các lần sau: số còn lại)
  2. Chia ngẫu nhiên thành 2 nhóm (Tả 左 và Hữu 右)
  3. Rút 1 thẻ từ nhóm Hữu, kẹp vào ngón tay út (tượng Tam Tài)
  4. Đếm nhóm Tả theo từng 4 thẻ, giữ phần dư (1-4 thẻ)
  5. Đếm nhóm Hữu theo từng 4 thẻ, giữ phần dư (1-4 thẻ)
  6. Tổng phần dư (1 thẻ kẹp + dư Tả + dư Hữu) = thẻ bỏ ra lần này

3.2. Giá trị phần dư mỗi biến:

Biến 1: Tổng dư = 5 hoặc 9 (chỉ có 2 giá trị khả dĩ)

Biến 2: Tổng dư = 4 hoặc 8

Biến 3: Tổng dư = 4 hoặc 8

3.3. Xác định hào:

Sau 3 biến, tổng thẻ bỏ ra ∈ {13, 17, 21, 25}. Thẻ còn lại chia 4:

  • 36 ÷ 4 = 9 → Thái Dương (老陽 Lão dương) — Dương động, giá trị 9
  • 32 ÷ 4 = 8 → Thiếu Âm (少陰 Thiếu âm) — Âm tĩnh, giá trị 8
  • 28 ÷ 4 = 7 → Thiếu Dương (少陽 Thiếu dương) — Dương tĩnh, giá trị 7
  • 24 ÷ 4 = 6 → Thái Âm (老陰 Lão âm) — Âm động, giá trị 6

4. Xác Suất — Không Cân Bằng

Khác với gieo 3 đồng xu (xác suất đều 1/8 cho mỗi tổ hợp), Đại Diễn Pháp có xác suất KHÔNG đều:

# Xác suất Đại Diễn Pháp (tính toán chính xác)
# Biến 1: P(5) = 4/49,  P(9) = 45/49  → gần như chắc chắn ra 9
# ...nhưng kết quả cuối cùng:

probs = {
    6: 1/16,    # Thái Âm  (lão âm)   — 6.25%
    7: 5/16,    # Thiếu Dương          — 31.25%
    8: 7/16,    # Thiếu Âm             — 43.75%
    9: 3/16,    # Thái Dương (lão dương) — 18.75%
}

# So sánh với 3 đồng xu:
coin_probs = {
    6: 1/8,     # Thái Âm   — 12.5%
    7: 3/8,     # Thiếu Dương — 37.5%
    8: 3/8,     # Thiếu Âm   — 37.5%
    9: 1/8,     # Thái Dương — 12.5%
}

# Đại Diễn Pháp thiên về Âm (8) hơn Dương (7)
# → phản ánh triết lý: Âm (vạn vật) nhiều hơn Dương (trời)

5. Triển Khai Thuật Toán

5.1. Python

import random

def yarrow_one_change(n_stalks):
    """Thực hiện 1 biến (thao tác) Đại Diễn Pháp.
    
    Args:
        n_stalks: Số thẻ hiện có (49 cho biến 1, ít hơn cho biến 2, 3)
    Returns:
        Số thẻ bỏ ra (phần dư)
    """
    # Chia ngẫu nhiên thành 2 nhóm
    left = random.randint(1, n_stalks - 1)
    right = n_stalks - left
    
    # Rút 1 từ nhóm phải (Tam Tài)
    right -= 1
    hand = 1
    
    # Đếm nhóm trái theo 4
    left_remainder = left % 4
    if left_remainder == 0:
        left_remainder = 4
    
    # Đếm nhóm phải theo 4
    right_remainder = right % 4
    if right_remainder == 0:
        right_remainder = 4
    
    return hand + left_remainder + right_remainder


def yarrow_one_line():
    """Tạo 1 hào bằng Đại Diễn Pháp (3 biến).
    
    Returns:
        6 (Thái Âm), 7 (Thiếu Dương), 8 (Thiếu Âm), hoặc 9 (Thái Dương)
    """
    stalks = 49
    total_removed = 0
    
    for _ in range(3):  # 3 biến
        removed = yarrow_one_change(stalks)
        total_removed += removed
        stalks -= removed
    
    # Thẻ còn lại chia 4 → giá trị hào
    return stalks // 4


def yarrow_hexagram():
    """Tạo 1 quẻ 6 hào bằng Đại Diễn Pháp.
    
    Returns:
        List 6 giá trị [hào 1 (dưới), ..., hào 6 (trên)]
    """
    return [yarrow_one_line() for _ in range(6)]


# Sử dụng
hexagram = yarrow_hexagram()
print(f"Quẻ: {hexagram}")
for i, line in enumerate(hexagram, 1):
    names = {6: "Thái Âm ⚋⚋", 7: "Thiếu Dương ⚊", 8: "Thiếu Âm ⚋", 9: "Thái Dương ⚊⚊"}
    print(f"  Hào {i}: {line} — {names[line]}")

5.2. JavaScript

/**
 * Đại Diễn Pháp (Yarrow Stalk Method)
 * Thuật toán bói Kinh Dịch cổ đại
 */
function yarrowOneChange(nStalks) {
  const left = Math.floor(Math.random() * (nStalks - 1)) + 1;
  let right = nStalks - left - 1; // -1 cho thẻ Tam Tài
  
  let leftRem = left % 4 || 4;
  let rightRem = right % 4 || 4;
  
  return 1 + leftRem + rightRem; // hand + left + right
}

function yarrowOneLine() {
  let stalks = 49;
  for (let i = 0; i < 3; i++) {
    stalks -= yarrowOneChange(stalks);
  }
  return stalks / 4; // 6, 7, 8, or 9
}

function yarrowHexagram() {
  return Array.from({ length: 6 }, () => yarrowOneLine());
}

// Sử dụng
const hexagram = yarrowHexagram();
console.log("Quẻ:", hexagram);

5.3. C

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int yarrow_one_change(int n_stalks) {
    int left = 1 + rand() % (n_stalks - 1);
    int right = n_stalks - left - 1;
    int left_rem = left % 4;
    if (left_rem == 0) left_rem = 4;
    int right_rem = right % 4;
    if (right_rem == 0) right_rem = 4;
    return 1 + left_rem + right_rem;
}

int yarrow_one_line(void) {
    int stalks = 49;
    for (int i = 0; i < 3; i++)
        stalks -= yarrow_one_change(stalks);
    return stalks / 4;
}

int main(void) {
    srand((unsigned)time(NULL));
    printf("Quẻ Kinh Dịch (Đại Diễn Pháp):\n");
    for (int i = 0; i < 6; i++)
        printf("  Hào %d: %d\n", i + 1, yarrow_one_line());
    return 0;
}

6. So Sánh Với Các Phương Pháp Bói Dịch Khác

  • Đại Diễn Pháp (蓍草法): 50 cọng thi → 18 bước → xác suất không đều. Chậm nhất nhưng trang trọng nhất
  • Gieo 3 đồng xu (擲錢法): 3 xu tung → 1 hào. Nhanh, xác suất đều P(6)=P(9)=1/8, P(7)=P(8)=3/8
  • Phương pháp Chu Dịch Tiên Sinh: Dùng 6 đồng xu tung 1 lần → 1 quẻ. Nhanh nhất nhưng ít truyền thống
  • Mai Hoa Dịch Số (梅花易數): Thiệu Ung — dùng số từ thời gian, sự kiện. Không cần công cụ vật lý

7. Đại Diễn Pháp Trong QuizzMan

Trong hệ thống Kinh Dịch của QuizzMan (lab.quizzman.com), Đại Diễn Pháp được triển khai với:

  • Mô phỏng trực quan: Animation 49 thẻ chia nhóm, đếm, bỏ dư — giúp visualize toàn bộ 18 bước
  • Entropy nguồn: Dùng CSPRNG (crypto.getRandomValues) thay vì Math.random() — đảm bảo tính ngẫu nhiên thật sự
  • Kiểm chứng xác suất: Sau 1 triệu lần chạy, phân phối khớp với lý thuyết (6.25%, 31.25%, 43.75%, 18.75%)
  • So sánh song song: Cùng 1 câu hỏi, xem kết quả từ Đại Diễn Pháp vs 3 đồng xu — thấy rõ sự khác biệt phân phối