タロットの偶奇で易の卦を出す
トランプやタロットといったカードで易の卦を出すとき、一度出たカードは次には出なくなることから、カードの数のパリティー(奇数か偶数か)で卦を診ようとすると微妙に結果が偏ることになる。
本稿では、易の卦を出す簡単な方法がすでにいろいろある中、あえて複雑な操作を用い、この結果の偏りを減らす方法を考案する。
■ |
はじめに
|
易の卦は、陰陽二つの状態を持つ爻を上卦の3爻、下卦の3爻、あわせて6爻で占い、2 の 6 乗 = 64 卦が、偏りなく出るようになっている。筮竹 をジャラジャラ鳴らすような本格的なもの(といってもいろいろあるのだが)の他に、古くから、6枚のコインを投げてその表裏で陰陽を決める擲銭法 が行われて来た。
タロットの場合、絵の正位置・逆位置があるので、数のパリティーではなく、 6 枚のカードを並べたあと、正逆の「スピン」を見ることによって擲銭法と同じように卦を出すことができる。
しかし、この方法だと、カードの象徴がほぼ無意味になってしまうため、易がタロットの象徴に完全に負けてしまうようで、おもしろくない。
同様の印象を持つ方も多いのだろうか、わざわざ、易の64卦を64枚のカードにそれぞれ描いた方法が開発され、そういうカードも市販されている。トランプの 4 スート 8 までの 32枚を使って、上卦・下卦を別に決める方法もありえよう。
最近、私はいろいろ思うところがあって、「易双六 」という易とタロットと双六その他を併せたような一人遊びゲームを(ブラウザゲームとともに)作った。そのとき、タロットのマルセイユ版とライダー=ウェイト版の違いである (8)力 と (11)正義 の位置を「記念」するために、それがスプレッドに出たときは入れ換えるというルールを入れておいた。
あとで気になって、確率を計算(シミュレート)してみると、(8) と (11) を決まったように入れ換えても、何か確率が変わることはないようだった。でも、そこで少し悩んで、これに数字として意味を与えることはできないかと考えた。ちょうど、最初に書いたようにカードによる易卦の導出には偏りがあるとは知ってたから、その偏りをただす方法につながらないかと考えてみた。
■ |
モンテカルロ法による開式置換法の発見
|
簡単に Perl でプログラムを書き、易双六のルール通り、大アルカナ 22枚から (0)愚者と (13)死神 のカードを抜いた 20枚をランダムにシャッフルして 6枚取り出し、(8) と (11) があれば入れ換え、そのパリティーでみた卦によって、統計をとってみた。
結果、入れ換えなかった場合と同じになる。つまり、卦の奇数の数を $odd で表すと、その卦の出る確率を次のように計算したとおりにほぼなる。
|
なお、Perm($n,$k) は、$n 個から $k 個選ぶ順列の場合の数とする。今後出てくる Comb($n,$k) は、$n 個から $k 個選ぶ組み合わせの場合の数とする。ちなみに、理想であるところの 1/64 == 0.015625 である。
この奇数の数によって、確率が決まるというのは、まぁ、シミュレーションしているうちに気付けるたぐいのものだろうが、要は、この数に基づいてチョチョッといじれば、確率を操作できそうだとあたりがつく。
(8) と (11) の入れ換えはちょうど偶奇の入れ換えになっており、これを使うとすると、$odd の数が少ないときに、むしろより少なくする方向に確率が足りてないので、次のようなルールにすると良さそうだ。
|
こうやっても、$odd == 6, 0 (乾か坤)のときは、レア度が高すぎて差が埋まらず、0.00866 ぐらいになるのが勢いっぱい。それはしようがないとしても、問題は $odd == 3 のときで、 0.01857ぐらいの数字になり、ここに属す卦が多いわりに確率が大きいように思う。$odd == 2 が 0.01430 ぐらいと少ないので、こちらに少し移動できなれば良さそうだが……。
そこで、$odd == 3 のときに何かルールを足せないかと考えた。単純に 3 のときも (8) と (11) の入れ換えをすると、今度は 0.01077 ぐらいと少なくなりすぎる。
それを 3 回に 1回ぐらいにしてシミュレーションすると、ちょうどいい感じなのだが、3回に 1回というのを例えば、配置に基づいて第5爻か第2爻に (8) や (11) が来たときとすると、卦がパリティー以外の要素でも変わることになり、どうもよろしくない。
がまんして 2 回に 1 回ぐらいにしてシミュレーションすると、$odd == 3 のときは 0.01467、$odd == 2,4 のときは 0.01690 ぐらいになる。2 回に 1 回ってことなら、ちょうど、タロットの正位置・逆位置を使えばいい!…ということで、次のルールにした。
|
これを偶奇の数をより増すほうに入れ換えをなすところから、「開式置換法」と呼ぶことにする。
■ |
総当り法による開式置換法の正確な確率の割り出し
|
さて、モンテカルロ法でだいたいの確率が求まったのはいいとして、操作して数値をそろえたから、実際のところどれぐらい違いがあるかわかりにくくなっていた。上で出した 0.0... といった数値は実は、これ以降の計算で割り出したもので、正直、この段階では、$odd が同じだと同じ数値になるというのも確信できてなかった。
かといって、ここまで複雑なルールを解析的に解くのもメンドクサイ。そこで、次善の策として、カードの状態を総当り的に作り出して、その場合の数を調べれば、正確な確率が出るので、それをやってみた。それが calc_prob_2.pl である。
つまり、20 枚から 6 枚選ぶ順列と、(8) か (11) の正逆を表す {0,1} の直積に関し、ループをかけて、そこに上のカード入れ換えのルールを適用した後、出た卦に関して統計をとるのである。
もちろん、順列の場合の数は 20×19×18×17×16×15 で、すごい時間がかかる。が、今は個人の PC でも十二分な速度があるから不可能というほどではなく、私の PC (Atom D525 1.8GHz) で 133 分で計算できた。
結果の出力は、卦をビットにし16進数で表したものに続いて $odd の数ごとの統計が続き次のようになる。
00: 0.00866873 ( 483840 / 55814400 ) 01: 0.0151703 ( 846720 / 55814400 ) 02: 0.0151703 ( 846720 / 55814400 ) 03: 0.016904 ( 943488 / 55814400 ) 04: 0.0151703 ( 846720 / 55814400 ) 05: 0.016904 ( 943488 / 55814400 ) 06: 0.016904 ( 943488 / 55814400 ) 07: 0.0146749 ( 819072 / 55814400 ) 08: 0.0151703 ( 846720 / 55814400 ) 09: 0.016904 ( 943488 / 55814400 ) 0a: 0.016904 ( 943488 / 55814400 ) 0b: 0.0146749 ( 819072 / 55814400 ) 0c: 0.016904 ( 943488 / 55814400 ) 0d: 0.0146749 ( 819072 / 55814400 ) 0e: 0.0146749 ( 819072 / 55814400 ) 0f: 0.016904 ( 943488 / 55814400 ) 10: 0.0151703 ( 846720 / 55814400 ) 11: 0.016904 ( 943488 / 55814400 ) 12: 0.016904 ( 943488 / 55814400 ) 13: 0.0146749 ( 819072 / 55814400 ) 14: 0.016904 ( 943488 / 55814400 ) 15: 0.0146749 ( 819072 / 55814400 ) 16: 0.0146749 ( 819072 / 55814400 ) 17: 0.016904 ( 943488 / 55814400 ) 18: 0.016904 ( 943488 / 55814400 ) 19: 0.0146749 ( 819072 / 55814400 ) 1a: 0.0146749 ( 819072 / 55814400 ) 1b: 0.016904 ( 943488 / 55814400 ) 1c: 0.0146749 ( 819072 / 55814400 ) 1d: 0.016904 ( 943488 / 55814400 ) 1e: 0.016904 ( 943488 / 55814400 ) 1f: 0.0151703 ( 846720 / 55814400 ) 20: 0.0151703 ( 846720 / 55814400 ) 21: 0.016904 ( 943488 / 55814400 ) 22: 0.016904 ( 943488 / 55814400 ) 23: 0.0146749 ( 819072 / 55814400 ) 24: 0.016904 ( 943488 / 55814400 ) 25: 0.0146749 ( 819072 / 55814400 ) 26: 0.0146749 ( 819072 / 55814400 ) 27: 0.016904 ( 943488 / 55814400 ) 28: 0.016904 ( 943488 / 55814400 ) 29: 0.0146749 ( 819072 / 55814400 ) 2a: 0.0146749 ( 819072 / 55814400 ) 2b: 0.016904 ( 943488 / 55814400 ) 2c: 0.0146749 ( 819072 / 55814400 ) 2d: 0.016904 ( 943488 / 55814400 ) 2e: 0.016904 ( 943488 / 55814400 ) 2f: 0.0151703 ( 846720 / 55814400 ) 30: 0.016904 ( 943488 / 55814400 ) 31: 0.0146749 ( 819072 / 55814400 ) 32: 0.0146749 ( 819072 / 55814400 ) 33: 0.016904 ( 943488 / 55814400 ) 34: 0.0146749 ( 819072 / 55814400 ) 35: 0.016904 ( 943488 / 55814400 ) 36: 0.016904 ( 943488 / 55814400 ) 37: 0.0151703 ( 846720 / 55814400 ) 38: 0.0146749 ( 819072 / 55814400 ) 39: 0.016904 ( 943488 / 55814400 ) 3a: 0.016904 ( 943488 / 55814400 ) 3b: 0.0151703 ( 846720 / 55814400 ) 3c: 0.016904 ( 943488 / 55814400 ) 3d: 0.0151703 ( 846720 / 55814400 ) 3e: 0.0151703 ( 846720 / 55814400 ) 3f: 0.00866873 ( 483840 / 55814400 ) 0: 0.00866873 ( 483840 / 55814400 ) 1: 0.0910217 ( 5080320 / 55814400 ) 2: 0.25356 ( 14152320 / 55814400 ) 3: 0.293498 ( 16381440 / 55814400 ) 4: 0.25356 ( 14152320 / 55814400 ) 5: 0.0910217 ( 5080320 / 55814400 ) 6: 0.00866873 ( 483840 / 55814400 )
■ |
組合せ論による開式置換法の確率
|
さて、正確な数値さえわかればこっちのもの。かりに複雑な論理を使って迷うようなことがあっても、検算はできることになる。
「(8)と(11)が同時に出る場合」(ex8ex11)、「「(8)と(11)がどちらも出ない場合」(ne8ne11)、「(8)が出て(11)が出ない場合」(ex8ne11)、「(11)が出て(8) が出ない場合」(ne8ex11) の四つの場合と、奇数の数で場合わけをしたとき、確率を求める式を Perl で書くと次のようになる。
MAIN: { our @CARDS = (0 .. 21); splice(@CARDS, 13, 1); splice(@CARDS, 0, 1); my $N = scalar @CARDS; my @p; for (my $odd = 0; $odd < 7; $odd++) { my $even = 6 - $odd; $p[$odd] = {}; if ($odd == 0 || $even == 0) { $p[$odd]->{ex8ex11} = 0; } else { $p[$odd]->{ex8ex11} = Perm($N/2 - 1, $odd - 1) * Perm($N/2 - 1, $even - 1) / Perm($N - 2, 4) * ($even / $N) * ($odd / ($N - 1)); } $p[$odd]->{ne8ne11} = Perm($N/2 - 1, $odd) * Perm($N/2 - 1, $even) / Perm($N, 6); if ($even == 0) { $p[$odd]->{ex8ne11} = 0; } else { $p[$odd]->{ex8ne11} = Perm($N/2 - 1, $odd) * Perm($N/2 - 1, $even - 1) / Perm($N - 1, 5) * ($even / $N); } if ($odd == 0) { $p[$odd]->{ne8ex11} = 0; } else { $p[$odd]->{ne8ex11} = Perm($N/2 - 1, $odd - 1) * Perm($N/2 - 1, $even) / Perm($N - 1, 5) * ($odd / $N); } } … }
これを正しく出すまでが苦労した。論理的導出で最初っから答えが出ましたとなればカッコいいが、残念ながら私にそんな実力はなく、いろいろ変数をいじくりまわしながら、何度もプログラムに計算しなおさせた結果、この式が出た。
そこから、これを開式のルールに従って操作するのは次のようにする。
{ … my @r; $r[3] = ($p[3]->{ex8ex11} * 2 * Comb(6, 3) + $p[3]->{ne8ne11} * 2 * Comb(6, 3) + $p[3]->{ex8ne11} * 1 * Comb(6, 3) + $p[3]->{ne8ex11} * 1 * Comb(6, 3)) / 2 / Comb(6, 3); $r[2] = ($p[2]->{ex8ex11} * 2 * Comb(6, 2) + $p[2]->{ne8ne11} * 2 * Comb(6, 2) + $p[3]->{ne8ex11} * 1 * Comb(6, 3) + $p[2]->{ex8ne11} * 2 * Comb(6, 2)) / 2 / Comb(6, 2); $r[1] = ($p[1]->{ex8ex11} * 2 * Comb(6, 1) + $p[1]->{ne8ne11} * 2 * Comb(6, 1) + $p[2]->{ne8ex11} * 2 * Comb(6, 2) + $p[1]->{ex8ne11} * 2 * Comb(6, 1)) / 2 / Comb(6, 1); $r[0] = ($p[0]->{ex8ex11} * 2 * Comb(6, 0) + $p[0]->{ne8ne11} * 2 * Comb(6, 0) + $p[1]->{ne8ex11} * 2 * Comb(6, 1) + $p[0]->{ne8ex11} * 2 * Comb(6, 0) + $p[0]->{ex8ne11} * 2 * Comb(6, 0)) / 2 / Comb(6, 0); $r[4] = $r[2]; $r[5] = $r[1]; $r[6] = $r[0]; … }
この Comb の掛け方の微妙さを見てくれ。出来たのを見れば、なるほど美しくもあるが、ここに辿りつくまで、$p[] がちゃんと数値的にあって喜んでるのも束の間、しばらく計算間違いで、まったく、総当りで出した数値と合わないのに焦りまくった。
とにかく、これで、「ロジカルな導出」というカードも、私の手に入ったわけだ。
■ |
固式置換法
|
こうして見てくると、私はすでに正逆位置(スピン)を使ってしまっている。そもそもスピンを使ってよいなら、すべてスピンを使えば、ちゃんとした易ができるのである。(……というのは、総当りを試したあとぐらいにやっと気付いたのだが。)
だったら、ちょうど $odd == 0,6 の場合のレア度が高いところを是正するのにスピンを使っちゃえばいいじゃないかというアイデアが浮かんだ。
もっとも簡単には、すべてのカードが正位置のときは強制的に「乾」の卦とし、すべてが逆位置なら「坤」の卦にするとするのである。そして、あとの部分を (8) と (11) の入れ換えで補ったらいいのではないか……?
しかし、これはうまくいかない。6 枚のカードの中に (8) も (11) も含まれず操作しようがないのに、全部が奇数または全部が偶数になることもありえ、すると、1/64 にその場合の数値を足すことになり、数値が大きくなってしまう(0.01779 ぐらい)。そこに目をつぶってもそれ以外の場合に 62/64 をかけて釣り合いをとる必要があり、どうも納得いかない。
組み合わせ論のプログラムをいじっていくうちに、とにかく $odd == 3 の場合の数を大きくしてしまって、それを $odd == 0,6 の場合に「降ろして」くればいいと考えた。
いろいろ試してみると、$odd == 2,3,4 のときのみとにかく (8) と (11) を入れ換えるようにすれば、$odd == 1,2,4,5 のときはまずまずの数値になる。そして、2/64 ずつぐらいを $odd == 3 から $odd == 0,6 に持ってくれば、すべての場合においてまずまずの結果になった。
とはいえ、2/64 って何だ?すべてが正位置・逆位置になるのはそれぞれ 1/64 だ。これに似た場合がもう一組必要になる。たとえば、「上卦はすべて正・下卦はすべて逆」と「上卦はすべて逆・下卦はすべて正」を特別視するという方法もある。しかし、それは易のリクツでは「否」「泰」の卦とすべきものだ。
だから、あえて複雑になるが、「奇数爻は正位置・偶数爻は逆位置」と「奇数爻は逆位置・偶数爻は正位置」という組を特別視することにした。
そうしてできた規則が次のようになる。
|
これを易双六においてトークン開始位置を固定する方法を含むものとして「固式置換法」と呼ぶことにする。
0: 0.0170279 (0.0170279) 1: 0.0942724 (0.0157121) 2: 0.214551 (0.0143034) 3: 0.348297 (0.0174149) 4: 0.214551 (0.0143034) 5: 0.0942724 (0.0157121) 6: 0.0170279 (0.0170279)
■ |
おわりに
|
とりあえず、はじめに目的としたカードの偶奇で易の卦を出すということはできたと思う。私は私の作ったゲームで使うことを考えてカード 20 枚で最適化したが、同様の方法で研究すれば、これ以外の場合にも対応できるだろう。
もちろん、擲銭法で易の卦は出せる。しかし、易の本格的な技法は別にあり、それは、呪術的意味・象徴的意味以外に、私がやったような確率論的探求が古代にもあったことを記念として留める意味があったのではないか。
今はコンピュータが個人で使える時代だから、人を使役して計算を訓練させるようなことはこれまで以上になくなっていくだろう。人を動かさず数だけで試して意味があるのだということを学生実習のレベルで知ることができる。
これが「福音」なのだと忘れぬ一助に本稿がなれば、これに勝る利 しきはない。
■ |
参考
|
上に挙げた Perl のプログラムは公開を前提にして作ったものではないので、きちゃないが、パブリックドメインなものとして好きにいじっていただいてかまわない。
|
更新: | 2011-11-18 |
初公開: | 2011年11月18日 22:57:30 |
最新版: | 2012年01月11日 15:53:37 |
2011-11-18 22:57:26 (JST) in シミュレーション | 固定リンク | コメント (1) | トラックバック (1)
トラックバック
他サイトなどからこの記事に自薦された関連記事(トラックバック)の一覧です。
» JRF のソフトウェア Tips:タロットの偶奇で易の卦を出す (この記事)
» 「易双六 PTC」開発記 from JRF のソフトウェア Tips
2013年正月明けに 3DS と共にプチコンをダウンロード購入。最初から作るものは決めていた。可能ならば、自作の(Web版の)『易双六』を移殖したい…。 しかし、その前には数々の困難が待ち受けるのであった。... 続きを読む
受信: 2013-02-21 04:51:06 (JST)
コメント
あと、いくつか "=" を "==" に変えた。
投稿: JRF | 2012-01-11 15:55:27 (JST)