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

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

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

『なぜ、あなたは Javaオブジェクト指向開発ができないのか』という本がありますが、勉強のために、オブジェクト指向で書かれたそのジャンケン・プログラム(第三章)を Ruby に移植してみました。コードは以下です。

class Player
  STONE = 0
  SCISSORS = 1
  PAPER = 2
  
  def initialize(playername)
    @name = playername
    @wincount = 0
  end

  def showHand
    hand = 0
    randomNum = rand * 3
    if randomNum < 1
      hand = STONE
    elsif randomNum < 2
      hand = SCISSORS
    else
      hand = PAPER
    end
    return hand
  end
  
  def notifyResult(result)
    if result == true
      @wincount += 1
    end
  end
  
  def getWinCount
    return @wincount
  end
  
  def getName
    return @name
  end
end


class Judge
  def startJanken(player1, player2)
    puts "【ジャンケン開始】"
    for cnt in 1..3
      puts "\n" + cnt.to_s  + "回戦目】"
      winner = judgeJanken(player1, player2)
      if winner != nil
        puts winner.getName + "が勝ちました!"
        winner.notifyResult(true)
      else
        puts "引き分けです"
      end
    end
    puts "\n【ジャンケン終了】\n\n"
    finalWinner = judgeFinalWinner(player1, player2)
    print player1.getWinCount.to_s + "" + player2.getWinCount.to_s + ""
    if finalWinner != nil
      puts finalWinner.getName + "の勝ちです!"
    else
      puts "引き分けです!"
    end
  end
  
  def judgeJanken(player1, player2)
    winner = nil
    player1hand = player1.showHand
    player2hand = player2.showHand
    printHand(player1hand)
    print "  vs.  "
    printHand(player2hand)
    print "\n"
    if player1hand == Player::STONE && player2hand == Player::SCISSORS or player1hand == Player::SCISSORS && player2hand == Player::PAPER or player1hand == Player::PAPER && player2hand == Player::STONE then
      winner = player1
    elsif player1hand == Player::STONE && player2hand == Player::PAPER or player1hand == Player::SCISSORS && player2hand == Player::STONE or player1hand == Player::PAPER && player2hand == Player::SCISSORS then
      winner = player2
    end
    return winner
  end
  
  def judgeFinalWinner(player1, player2)
    winner = nil
    player1WinCount = player1.getWinCount
    player2WinCount = player2.getWinCount
    if player1WinCount > player2WinCount
      winner = player1
    elsif player1WinCount < player2WinCount
      winner = player2
    end
    return winner
  end
  
  def printHand(hand)
    case hand
    when Player::STONE
      print "グー"
    when Player::SCISSORS
      print "チョキ"
    when Player::PAPER
      print "パー"
    end
  end
end


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


※追記
コードを少し変えました。多少 Ruby らしくなったと思います。(8/17)

class Player
  STONE = 0
  SCISSORS = 1
  PAPER = 2
  
  def initialize(playername)
    @name = playername
    @wincount = 0
  end
  attr_reader :wincount, :name

  def showHand
    hand = 0
    random_num = rand * 3
    if random_num < 1
      hand = STONE
    elsif random_num < 2
      hand = SCISSORS
    else
      hand = PAPER
    end
    hand
  end
  
  def notifyResult(result)
    @wincount += 1 if result
  end
end


class Judge
  def janken(player1, player2)
    puts "【ジャンケン開始】"
    (1..3).each { |c| playJanken(c, player1, player2) }
    
    puts "\n【ジャンケン終了】\n\n"
    final_winner = judgeFinalWinner(player1, player2)
    print "#{player1.wincount}#{player2.wincount}"
    if final_winner
      puts final_winner.name + "の勝ちです!"
    else
      puts "引き分けです!"
    end
  end
  
  def playJanken(c, player1, player2)
    puts "\n#{c}回戦目】"
    winner = judgeJanken(player1, player2)
    if winner
      puts winner.name + "が勝ちました!"
      winner.notifyResult(true)
    else
      puts "引き分けです"
    end
  end
  
  def judgeJanken(player1, player2)
    winner = nil
    p1hand = player1.showHand
    p2hand = player2.showHand
    printHand(p1hand); print "  vs.  "; printHand(p2hand); puts
    if p1hand == Player::STONE && p2hand == Player::SCISSORS or
        p1hand == Player::SCISSORS && p2hand == Player::PAPER or
        p1hand == Player::PAPER && p2hand == Player::STONE
      winner = player1
    elsif p1hand == Player::STONE && p2hand == Player::PAPER or
        p1hand == Player::SCISSORS && p2hand == Player::STONE or
        p1hand == Player::PAPER && p2hand == Player::SCISSORS
      winner = player2
    end
    winner
  end
  
  def judgeFinalWinner(player1, player2)
    winner = nil
    p1 = player1.wincount
    p2 = player2.wincount
    if p1 > p2
      winner = player1
    elsif p1 < p2
      winner = player2
    end
    winner
  end
  
  def printHand(hand)
    case hand
    when Player::STONE
      print "グー"
    when Player::SCISSORS
      print "チョキ"
    when Player::PAPER
      print "パー"
    end
  end
end


player1 = Player.new("村田さん")
player2 = Player.new("山田さん")
Judge.new.janken(player1, player2)



※追記
Python 版はこちらです。
 
 
※再追記
自力で再実装してみました。こちらの方がいいと思います。