SequenceableCollection >> #after: を使ってジャンケンの勝敗判定

Prologの話をしよう - CROSS2012・言語CROSS のコードが簡潔でよかったので、Squeak Smalltalk でも何か珍しい方法で簡潔に書けないかと考えて、いぜん見かけて使う機会がその後なかった #after:(実際には #after:ifAbsent: )というのを思い出したので、それを使って書いてみる試み。

| jankens player1 player2 judge |
jankens := #('グー' 'チョキ' 'パー').
player1 := jankens atRandom.
player2 := jankens atRandom.
judge := player1 = player2 ifTrue: ['引き分け'] ifFalse: [
   ((player2 = (jankens after: player1 ifAbsent: [jankens first]))
      ifTrue: [player1] ifFalse: [player2]
   ), 'の勝ち'].
^{player1. player2} -> judge  "=> #('グー' 'パー')->'パーの勝ち' "


#after: にも #atWrap: 的な機能が欲しいですね。ちなみに #atWrap: で上のを書くとこんな感じになります。

| jankens player1 player2 judge |
jankens := #('グー' 'チョキ' 'パー').
player1 := jankens atRandom.
player2 := jankens atRandom.
judge := player1 = player2 ifTrue: ['引き分け'] ifFalse: [
   ((player2 = (jankens atWrap: (jankens indexOf: player1) + 1))
      ifTrue: [player1] ifFalse: [player2]
   ), 'の勝ち'].
^{player1. player2} -> judge  "=> #('チョキ' 'グー')->'グーの勝ち' "


いや。#atWrap: みたいな動きは、むしろ通常の #at: に対してコレクションのほうが「環状である」という性質として持つほうが好ましいか。