Python によるオブジェクト指向ジャンケン・プログラム

なぜ、あなたはJavaでオブジェクト指向開発ができないのか―Javaの壁を克服する実践トレーニング

なぜ、あなたはJavaでオブジェクト指向開発ができないのか―Javaの壁を克服する実践トレーニング

この本の Java によるプログラムを、OOP の勉強のために Python 3 に移植してみました。Ruby 版はこちらです。

なるほど、きわめて読みやすい字面になっていますね。大いに気に入りました。インスタンス・メッソドをクラスの中から呼び出すには、Python では self が不可欠なのですね。それから、メッソドが引数を必要としない場合でも、括弧が省略できないと。これはまあ却って誤解の余地がなくなるという点、よい仕様なのかも知れません。インスタンス変数に self が例外なく必要なのは、読みにくいし、ちょっと面倒な気もします。

これを見ると、Ruby の簡潔さは際立っていますね。Python もとてもいい感じです。

import random

STONE = 0
SCISSORS = 1
PAPER = 2

class Player:
    def __init__(self, playername):
        self.name = playername
        self.wincount = 0

    def showHand(self):
        hand = 0
        randomNum = random.randint(0, 2)
        if randomNum == 0:
            hand = STONE
        elif randomNum == 1:
            hand = SCISSORS
        else:
            hand = PAPER
        return hand
 
    def notifyResult(self, result):
        if result:
            self.wincount += 1
 
    def getWinCount(self):
        return self.wincount
    
    def getName(self):
        return self.name

class Judge:
    def judgeJanken(self, player1, player2):
        winner = False
        player1hand = player1.showHand()
        player2hand = player2.showHand()
        self.printHand(player1hand)
        print(" vs. ", end="")
        self.printHand(player2hand)
        print("")
        if (player1hand == STONE and player2hand == SCISSORS) or \
              (player1hand == SCISSORS and player2hand == PAPER) or \
              (player1hand == PAPER and player2hand == STONE):
            winner = player1
        elif (player1hand == STONE and player2hand == PAPER) or \
              (player1hand == SCISSORS and player2hand == STONE) or \
              (player1hand == PAPER and player2hand == SCISSORS):
            winner = player2    
        return winner
 
    def judgeFinalWinner(self, player1, player2):
        winner = False
        player1WinCount = player1.getWinCount()
        player2WinCount = player2.getWinCount()
        if player1WinCount > player2WinCount:
            winner = player1
        elif player1WinCount < player2WinCount:
            winner = player2
        return winner

    def printHand(self, hand):
        if hand == STONE:
             print("グー", end="")
        elif hand == SCISSORS:
            print("チョキ", end="")
        elif hand == PAPER:
            print("パー", end="")

    def startJanken(self, player1, player2):
        print("【ジャンケン開始】")
        for cnt in range(1, 4):
            print("\n【" + str(cnt) + "回戦目】")
            winner = self.judgeJanken(player1, player2)
            if winner:
                print(winner.getName() + "が勝ちました!")
                winner.notifyResult(True)
            else:
                print("引き分けです")
 
        print("\n【ジャンケン終了】\n\n")
        finalWinner = self.judgeFinalWinner(player1, player2)
        print(str(player1.getWinCount()) + " 対 " + str(player2.getWinCount()) + "で",
              end="")
        if finalWinner:
            print(finalWinner.getName() + "の勝ちです!")
        else:
            print("引き分けです!") 

saito = Judge()
murata = Player("村田さん")
yamada = Player("山田さん")
saito.startJanken(murata, yamada)