MOE3: 交換移動の解決

spec/models/main_phase_spec.rb

テスト。

マニュアルの Diagram6、German F Ber–PruGerman A Pru–Ber の交換移動禁止処理を実装する。

f:id:asagix:20130912114126p:plain:w200

describe MainPhase do
  describe "#resolve_orders" do
    let(:phase) { MainPhase.create }
    let(:resolved_orders) { phase.resolve_orders }

    #(略)

    shared_context "Diagram6 交換", diagram: 6 do
      let(:fleet_ber) { FactoryGirl.create(:fleet, :g, :ber, phase: phase) }
      let(:army_pru) { FactoryGirl.create(:army, :g, :pru, phase: phase) }

      let(:prov_ber) { fleet_ber.province }
      let(:prov_pru) { army_pru.province }

      let!(:move_ber_pru) { FactoryGirl.create(:move_order, unit: fleet_ber, destination: prov_pru) }
      let!(:move_pru_ber) { FactoryGirl.create(:move_order, unit: army_pru, destination: prov_ber) }
    end

    context "Diagram6", diagram: 6 do
      subject { resolved_orders }
      example { expect(subject.find(move_ber_pru).status).to eq OrderStatus::FAILURE }
      example { expect(subject.find(move_pru_ber).status).to eq OrderStatus::FAILURE }
    end
  end
end

MainPhase#resolve_exchange メソッド

まずは効率度外視で思いついたまま、テストを通過するためだけの処理を書いてみた。

class MainPhase < Phase
  #(略)

  # 交換
  def resolve_exchange
    moves = @orders.select{|o| o.move?}
    moves.collect{|m| m.dst}.uniq.each do |dst|
      move1 = moves.select{|m| m.dst == dst && m.unexecuted?}[0]
      next unless move1
      move2 = moves.select{|m| m.src == move1.dst && m.dst == move1.src}[0]
      next unless move2

      move1.failure!
      move2.failure!
    end
  end

  #(略)
end

ここでリファクタリングを実施しても良いが、少し思うところがあるので今はこのままにしておく。