if と別れる50の方法《03》ジャンケン問題, double-dispatch
Python.use(better) # OOP への道 《Python3.1, Jython2.5.0, IronPython2.6.x》
ジャンケン問題, double-dispatch
■ 概要
if/switch 文は多くの問題を抱え、OOP を実践するときの「障害」になります。
伝統的なC言語風の for 文や悪名高い switch 文、配列の呪縛から解かれ、オブジェクト指向プログラミング〔OOP〕の醍醐味を堪能するための準備を行います。
■ 関連記事
- Java プログラマーのための Python 導入ガイド《Jython2.5》改訂版
- 例題で学ぶ Jython/Swing デザインパターン《Jython2.5》改訂版
- ゲームに学ぶ Jython/Swing フレームワーク《Jython2.5》改訂版
- IronPython で学ぶ WPF プログラミングの世界《IronPython2.6》改訂版
ジャンケン問題とは
《Note》n人が3つの手(石/鋏/紙)の中からひとつを出したときに、その勝敗(引分を含む)を判定します。
じゃん拳 ¶ 大辞林 第二版 (三省堂)
- 二人以上の人が片手で石(ぐう)・はさみ(ちょき)・紙(ぱあ)の形をつくり、どの形を出したかで勝負を決めること。また、その遊び。石ははさみに、はさみは紙に、紙は石に勝つ。いしけん。じゃんけんぽん。
じゃん拳 ¶ 新英和中辞典第6版 (研究社)
- the game of ‘paper, stone and scissors.'
SP による解法
まず「テストケース」を提示します。
def ex(): p1 = Player("A") p2 = Player("B") for e in range(9): print(">>>", p1.next(), p2.next()) print(judge(p1, p2))
2人のプレーヤー p1,p2 が出した手 next() を比較して、勝敗を判定 judge します。
from random import randint R,P,S = 0,1,2 class Player(object): def __init__(self, id): self.id = id def __repr__(self): return "%s(%s)"%(self.__class__.__name__, self.id) def next(self): self.hand = randint(0, 2) return self.hand
■ 多重 if 文
def judge(p1, p2): if p1.hand == R: if p2.hand == R: return None if p2.hand == P: return p1 if p2.hand == S: return p2 if p1.hand == P: if p2.hand == R: return p2 if p2.hand == P: return None if p2.hand == S: return p1 if p1.hand == S: if p2.hand == R: return p1 if p2.hand == P: return p2 if p2.hand == S: return None
2人で対戦する場合には、入れ子になった2重の if 文が必要になります。すると、3人で対戦する場合には3重の if 文が、そして、n人で対戦する場合にはn重の if 文が必要になります。
Tips
》作業中です《
*1:p1.hand == R and p2.hand == R) or (p1.hand == P and p2.hand == P) or (p1.hand == S and p2.hand == S
*2:p1.hand == R and p2.hand == P) or (p1.hand == P and p2.hand == S) or (p1.hand == S and p2.hand == R
*3:p1.hand == R and p2.hand == S) or (p1.hand == P and p2.hand == R) or (p1.hand == S and p2.hand == P