美しいコード?

なにやらテニスの勝負判定コードを書くのが流行ってる(もう遅いか)らしいので、rubyで書いてみた。元ネタは http://www.atmarkit.co.jp/im/carc/serial/redge51/redge51.html
どうしても我慢できなかったので、メッセージ(文字列)を作るところと、状態を判定するところをわけてみた。たいした構造があるわけでもないので、お手軽にStruct使用仕様。元ネタの片方のプログラムでは6-6の時だけちょっとメッセージが違うがそれは無視。

module Tennis
  Player = Struct.new(:name,:games)
  module_function
  def get_setscore(player_a,player_b)
    state,leader,loser = state_check(player_a,player_b)
    case state
    when :win
      return "#{leader.name} wins the set #{score(leader,loser)}"
    when :lead
      return "#{leader.name} leads #{score(leader,loser)}"
    when :tie
      return "Set is tied at #{leader.games}"
    end
  end

  def score(a,b)
    return "#{a.games} - #{b.games}"
  end

  def state_check(a,b)
    leader,loser = if a.games > b.games then [a,b] else [b,a] end
    state =
      if (leader.games == loser.games)
        :tie
      elsif (leader.games == 7)
        :win
      elsif (leader.games == 6 && loser.games < 5)
        :win
      else
        :lead
      end
    return [state,leader,loser]
  end

end

if __FILE__ == $0
  a = Tennis::Player.new("Player1",(ARGV.shift || 6).to_i)
  b = Tennis::Player.new("Player2",(ARGV.shift || 6).to_i)
  puts Tennis::get_setscore(a,b)
end

こう見ると、"def score"はちょっとやりすぎな気もするが、"まとめたい"病がそうしろと言うのでそのままにしておく。本当はget_setscoreの中に定義したいんだけどなあ。procにするのも変だしなあ。

追記

関数名や変数名をちょっと修正。

他にrubyで書いてる人をみつけた

http://d.hatena.ne.jp/Tommy1/20070115/1168877925
おなじrubyでもけっこう違うもんだなあ。