多人数でのジャンケンの決着のつかなさ加減を Squeak Smalltalk で体感する


おもしろそうなので試してみた。

じゃんけんゲームの結果はなかなか興味深い。10人いっぺんにじゃんけんさせると、4回程度で勝負つくときもあれば、99回かかるときもある。希だけど。50人いると10万回やっても延々と引き分け。ほんまか?

Twitter / あひる


50人だと本当に延々とやっていて終わる気がしなかったので 30人で。

| N 推移 選択肢 |

N := 30.
推移 := OrderedCollection with: #N -> N.
選択肢 := #(グー チョキ パー).

[  | 場 |
   場 := Bag new.
   N timesRepeat: [場 add: 選択肢 atRandom].
   場 asSet size ~= 2
      ifTrue: [推移 last key = #あいこ
         ifTrue: [推移 last value: 推移 last value + 1]
         ifFalse: [推移 add: #あいこ -> 1]]
      ifFalse: [
         | 手 脱落者数 |
         推移 add: #N -> 場 sortedCounts.
         手 := 場 anyOne.
         脱落者数 := 場 occurrencesOf: (選択肢 atWrap: (選択肢 indexOf:手) + 1).
         脱落者数 = 0 ifTrue: [脱落者数 := 場 occurrencesOf: 手].
         N := N - 脱落者数].
   N = 1
] whileFalse.

^推移 asArray
=> {
   #N->30.
   #'あいこ'->74134.
   #N->{17->#'チョキ'. 13->#'グー'}.
   #'あいこ'->35.
   #N->{8->#'チョキ'. 5->#'グー'}.
   #N->{4->#'チョキ'. 1->#'パー'}.
   #'あいこ'->2.
   #N->{3->#'チョキ'. 1->#'グー'}
}

ところで、本論とは関係ないのですが、ジャンケンの勝敗判定の処理について。個人的には、全組み合わせについて勝敗を条件式で網羅的に記述するのはなんだか負けた気がするので嫌いで、これだけはぜったい書かないようにしています。^^;

今回は負け抜けの人数を知れば十分だったので、「引き分けでない」、すなわち「場にはきっちり二種類の手が出ている」という状況を情報として活用し、「場の一方の手に注目し、それに負ける手が出ていないとき、その手を出したお前らが負け」というふうに、やや富豪的かついささか回りくどく解決してみました。ここらへんの判定方法はいろいろとバリエーションをつけられそうですね。