Report abuse


			
class Array
  def sum
    inject(0){|sum, x| sum + x}
  end
  def map_with_index!
    each_with_index{|e, idx| self[idx] = yield(e, idx)}
  end
  def map_with_index(&block)
    clone.map_with_index!(&block)
  end
end

class Player
  attr_accessor :games

  @@InitialRank = 100

  def initialize
    @games = Array.new
  end

  def rank
    return @@InitialRank if games.empty?
    games[0,100].map_with_index{|game, index|
      (game[:rank] + (game[:won] ? 50 : -50)) * (150-index)
    }.sum / (150 - games[0,100].length/2) / games[0,100].length
  end

  def boundRank(otherRank)
    [[otherRank, rank+40].min, rank-40].max
  end

  def won(otherPlayer)
    if (games.empty? and otherPlayer.games.empty?)
      otherPlayer.games.unshift({:rank => @@InitialRank, :won => false})
      games.unshift({:rank => @@InitialRank, :won => true})
    elsif (games.empty?)
      games.unshift({:rank => boundRank(otherPlayer.rank), :won => true})
      otherPlayer.games.unshift({:rank => otherPlayer.boundRank(rank), :won => false})
    elsif (otherPlayer.games.empty?)
      otherPlayer.games.unshift({:rank => otherPlayer.boundRank(rank), :won => false})
      games.unshift({:rank => boundRank(otherPlayer.rank), :won => true})
    else
      otherRank = otherPlayer.rank
      otherPlayer.games.unshift({:rank => otherPlayer.boundRank(rank), :won => false})
      games.unshift({:rank => boundRank(otherRank), :won => true})
    end
  end
end