在Rails中的Agricola棋盘游戏记分卡建模

时间:2011-03-24 16:23:13

标签: ruby-on-rails ruby-on-rails-3

我正在使用Rails中的小型网络应用程序来模拟棋盘游戏的分数卡Agricola

问题是:在Rails中为记分卡建模的最佳(阅读:正确)方法是什么/

目前,我有一个ScoreCard模型,其中的列是计入最终得分的“类别”。它类似于:

class ScoreCard < ActiveRecord::Base
  validates :field_tile,
            :pasture,
            :grain,
            :vegetable,
            :sheep,
            :wild_boar,
            :cattle,
            :unused_space,
            :fenced_stable,
            :clay_room,
            :stone_room,
            :family_member,
            :victory_point,
            :bonus_point,
            :numericality => true
end

评分机制描述为in this game manual(参见第8页的“评分”部分)。这是手册中的一个片段:

  

字段:打开的所有字段切片   球员的农场得分,   不管他们是否是   目前休耕或播种。一个玩家   0或1个字段丢失1个点。每   场后第一分1分,   5或者最多4分   更多领域。球员得分-1/1/2/3/4   0-1 / 2/3/4/5 +场的分数。

     

牧场:积分奖励   围栏区(“牧场”),不适合   有多少农场空间   围栏(“牧场空间”)。尺寸   个别牧场是   无关。没有牧场的球员   输了1分。每个牧场得1分   点,最多4点   4个或更多牧场。球员得分   -1 / 1/2 / 3/4分为0/1/2/3/4牧场。

由于每个“类别”(牧场,谷物等)都有不同的评分机制,我定义了一些私有方法,它们返回每个“类别”的最终得分:

private
  def calculate_field_tiles_score
    case field_tile
      when 0..1 then -1
      when 2..4 then field_tile - 1
      else 4
    end 
  end

  def calculate_pasture_score
    # return proper score
  end

我在模型中也有一个(公共)calculate方法来计算最终得分:

def calculate
  calculate_field_tiles_score +
  calculate_pasture_score +
  # ... other scores
end

这是一个好方法吗?我不确定它的建模方法是什么,但它感觉不对。

1 个答案:

答案 0 :(得分:2)

我会采取以下方式:

class Scorer
  def initialize(farmyard); @farmyard=farmyard; end
end

class FieldTilesScorer < Scorer
  def score
    case @farmyard.field_tile 
      #etc
    end
  end
end

class PasturesScorer < Scorer
   def score
     #return proper score
   end
end

等等。然后,当我想要一个农场的时候,我会这样做:

[FieldTilesScorer, PastureScorer, ...].
  map{|s| s.new(@farmyard).score}.
  inject(0){|m,r| m+r}

通过这种方式,您可以将每个类别建模为自己的类,并且可以轻松添加依赖于农场中任何状态组合的规则。