最近android入門書で例としてじゃんけんアプリを作りました。その中でじゃんけんの勝敗判定方法の説明が省略されていたので、自分なりに整理してみました。
愚直に判定
ここでは普段じゃんけんするときに人間が行っている方法でじゃんけんの勝敗判定をしてみます。
普段行っている判定方法は「相手:グー、自分:パー」なら「自分が勝ち」見たく、相手の手と自分の手で勝ち負けを判定しています。相手の手が3通り、自分の手が3通りなので3×3=9通りの手の組み合わせについて判定すれば、じゃんけんの勝敗判定が出来ます。
自分の手 | 相手の手 | 勝敗 |
---|---|---|
グー | グー | あいこ |
グー | チョキ | 勝ち |
グー | パー | 負け |
チョキ | グー | 負け |
チョキ | チョキ | あいこ |
チョキ | パー | 勝ち |
パー | グー | 勝ち |
パー | チョキ | 負け |
パー | パー | あいこ |
上記の表に従って、pythonでじゃんけんの勝敗を判定してみます。後のじゃんけん勝敗判定アルゴリズムで使えるように、それぞれの手を以下のように数字で表します。
- グー:0
- チョキ:1
- パー:2
# それぞれの手を数字で表現
GU = 0
CHOKI = 1
PA = 2
# 勝敗
WIN = 'WIN'
LOSE = 'LOSE'
DRAW = 'DRAW'
def judge(my_hand, comp_hand):
# 自分の手がグー
if my_hand == GU:
if comp_hand == GU:
return DRAW
elif comp_hand == CHOKI:
return WIN
else:
return LOSE
# 自分の手がチョキ
elif my_hand == CHOKI:
if comp_hand == GU:
return LOSE
elif comp_hand == CHOKI:
return DRAW
else:
return WIN
# 自分の手がパー
else:
if comp_hand == GU:
return WIN
elif comp_hand == CHOKI:
return LOSE
else:
return DRAW
自分の手(my_hand)でif文で分岐して、さらにその中で相手の手(comp_hand)で分岐させて勝敗判定をしています。表の内容を実際に表現しています。
3で割った余りで判定
愚直に判定する方法でもできますが、もっと短いコードで書く方法があります。それが「自分の手の数字から相手の手の数字を引いて、それを3で割った余りで判定する」方法です。
愚直に判定するの表に「自分の手 – 相手の手」、「(自分の手 – 相手の手)% 3」という列を追加してみます。
自分の手 | 相手の手 | 自分の手 – 相手の手 | (自分の手 – 相手の手)% 3 | 勝敗 |
---|---|---|---|---|
グー(0) | グー(0) | 0 | 0 | あいこ |
グー(0) | チョキ(1) | -1 | 2 | 勝ち |
グー(0) | パー(2) | -2 | 1 | 負け |
チョキ(1) | グー(0) | 1 | 1 | 負け |
チョキ(1) | チョキ(1) | 0 | 0 | あいこ |
チョキ(1) | パー(2) | -1 | 2 | 勝ち |
パー(2) | グー(0) | 2 | 2 | 勝ち |
パー(2) | チョキ(1) | 1 | 1 | 負け |
パー(2) | パー(2) | 0 | 0 | あいこ |
この表を見ると、「(自分の手 – 相手の手) % 3」の値により以下のことがわかります。
- 0の時はあいこ
- 1の時は負け
- 2の時は勝ち
なんと、(自分の手 – 相手の手)を3で割った余りから勝敗が判定できてしまうのです。
ちなみに-1や-2を3で割った時の余りはこれらに3を足して、3で割った時の余りと同じという性質があります。詳しくはこちらを参照してください。
pythonで書くと次のようになります。
# それぞれの手を数字で表現
GU = 0
CHOKI = 1
PA = 2
# 勝敗
WIN = 'WIN'
LOSE = 'LOSE'
DRAW = 'DRAW'
def judge(my_hand, comp_hand):
m = (my_hand - comp_hand) % 3
if m == 0:
return DRAW
elif m == 1:
return LOSE
else:
return WIN
愚直に判定する場合よりかもはるかに短いコードで書くことが出来ました。