summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/colonial_twilight/fln_bot_rules.rb181
-rw-r--r--spec/fln_bot_rules_spec.rb495
2 files changed, 460 insertions, 216 deletions
diff --git a/lib/colonial_twilight/fln_bot_rules.rb b/lib/colonial_twilight/fln_bot_rules.rb
index e9b9e79..cbe2145 100644
--- a/lib/colonial_twilight/fln_bot_rules.rb
+++ b/lib/colonial_twilight/fln_bot_rules.rb
@@ -12,44 +12,40 @@ module ColonialTwilight
end
end
- def pass?
+ def pass?(board = @board)
# if resources = 0 && Op Limited as only choice
- r = @board.fln_resources.zero? && limited_op_only?
+ r = board.fln_resources.zero? && limited_op_only?
dbg 'PASS', r
r
end
- def terror1?
- # unless any FLN base is (pop 0 && 0 FLN underground or pop 1+ && 1- FLN underground)
- r = !@board.has do |s|
- s.fln_bases.positive? &&
- ((s.pop.zero? && s.fln_underground.zero?) || (!s.pop.zero? && s.fln_underground < 2))
+ def terror1?(board = @board)
+ # if no FLN base is (pop 0 && 0 FLN underground or pop 1+ && 1- FLN underground)
+ r = !board.has do |s|
+ s.fln_bases.positive? && ((s.pop.zero? && s.fln_underground.zero?) || (!s.pop.zero? && s.fln_underground < 2))
end
dbg 'TERROR 1', r
r
end
- def terror2?
+ def terror2?(_board = nil)
# if GOV is first eligible && will be second eligible
r = !first_eligible? && will_be_next_first_eligible?
dbg 'TERROR 2', r
r
end
- def rally1?
- # rally would place bases (first 2 bullets)
- # 4+ or (3+ FLN and no GOV (unless limited_op_only))
- r = @board.available_fln_bases.positive? && @board.has do |s|
- may_add_base_in?(s) && (rally_2_in?(s) || rally_1_in?(s))
- end
+ def rally1?(board = @board)
+ # rally would place a base (rally 1 or 2)
+ r = board.available_fln_bases.positive? && board.has { |s| (may_rally_1_in?(s) || may_rally_2_in?(s)) }
dbg 'RALLY 1', r
r
end
- def rally2?
+ def rally2?(board = @board)
# if #FLN bases * 2 > #FLN at FLN bases + 1d6/2
- a = @board.count(&:fln_bases) * 2
- b = @board.count { |s| s.fln_bases.zero? ? 0 : s.fln_cubes }
+ a = board.count(&:fln_bases) * 2
+ b = board.count { |s| s.fln_bases.zero? ? 0 : s.guerrillas }
r = a > (b + d6 / 2)
dbg 'RALLY 2', r
r
@@ -57,87 +53,148 @@ module ColonialTwilight
# Rally
- def may_add_base_in?(space)
- r = space.fln_cubes > 2 && (space.fln_bases < (space.country? ? space.max_bases : 1))
- dbg " may_add_base : #{space.name}", r
- r
- end
-
- def rally_1_in?(space)
+ def may_rally_1_in?(space)
# 3+ FLN and no GOV (unless limited_op_only))
- r = space.fln_cubes >= 3 && (limited_op_only? ? true : space.gov_cubes.zero?)
- dbg " rally_1_in : #{space.name}", r
+ r = may_rally_in?(space) && may_add_base_in?(space) && space.guerrillas >= 3 &&
+ (limited_op_only? ? true : space.gov_cubes.zero?)
+ dbg " may_rally_1_in : #{space.name}", r
r
end
- def rally_2_in?(space)
+ def may_rally_2_in?(space)
# 4+ FLN
- r = space.fln_cubes >= 4
- dbg " rally_2_in : #{space.name}", r
+ r = may_rally_in?(space) && may_add_base_in?(space) && space.guerrillas >= 4
+ dbg " may_rally_2_in : #{space.name}", r
r
end
- def rally_3_in?(space)
+ def may_rally_3_in?(space)
# at FLN bases, with 2- FLN underground or 0 fln_undergroud in country or 0 pop
- r = !space.fln_bases.zero? &&
+ r = may_rally_in?(space) && !space.fln_bases.zero? &&
(space.country? || space.pop.zero? ? space.fln_underground.zero? : space.fln_underground < 2)
- dbg " rally_3_in : #{space.name}", r
+ dbg " may_rally_3_in : #{space.name}", r
r
end
def rally_3_priority(spaces)
# Algeria -> with cubes -> pop 1+ -> least FLN underground
- l0 = (l0 = spaces.reject(&:country?)).empty? ? spaces : l0
- l1 = (l1 = l0.select { |s| s.gov_cubes.positive? }).empty? ? l0 : l1
- l2 = (l2 = l1.select { |s| s.pop.positive? }).empty? ? l1 : l2
- l2.min { |a, b| a.fln_underground <=> b.fln_underground }
+ f = _filter(spaces) { |s| !s.country? }
+ f = _filter(f) { |s| s.gov_cubes.positive? }
+ f = _filter(f) { |s| s.pop.positive? }
+ _min(f, :fln_underground).shuffle
end
- def rally_5_in?(space)
+ def may_rally_5_in?(space)
# non-city at support with 0 FLN underground
- r = !space.city? && space.support? && space.fln_underground.zero?
- dbg " rally_5_in : #{space.name}", r
+ r = may_rally_in?(space) && !space.city? && space.support? && space.fln_underground.zero?
+ dbg " may_rally_5_in : #{space.name}", r
r
end
- def rally_6_in?(space)
- # 2+ pop to agitate
- r = space.pop > 1 && may_agitate_in?(space)
- dbg " rally_6_in : #{space.name}", r
+ def rally_5_priority(spaces)
+ # highest population
+ _max(spaces, :pop).shuffle
+ end
+
+ def may_rally_6_in?(space, already_rallied)
+ # 2+ pop to agitate after rally
+ r = (already_rallied || may_rally_in?(space)) && space.pop > 1
+ dbg " may_rally_6_in : #{space.name}", r
r
end
- def rally_8_in?(space)
- r = !space.fln_cubes.zero? && space.fln_bases.zero?
- dbg " rally_8_in : #{space.name}", r
+ def rally_6_priority(spaces)
+ # max pop, min terror, support : reference ?
+ f = _max(spaces, :pop)
+ f = _min(f, :terror)
+ f = _filter(f, &:support?)
+ # FIXME: maybe already selected first, or not
+ f.shuffle
+ end
+
+ def may_rally_7_in?(space)
+ r = may_rally_in?(space)
+ dbg " may_rally_7_in : #{space.name}", r
r
end
+ def rally_7_priority(spaces)
+ # highest population
+ _max(spaces, :pop).shuffle
+ end
+
+ def rally_7_priority_after(spaces)
+ # in city, least terror
+ f = _filter(spaces, &:city?)
+ _min(f, :terror).shuffle
+ end
+
+ def may_rally_8_in?(space)
+ r = may_rally_in?(space) && !space.guerrillas.zero? && space.fln_bases.zero?
+ dbg " may_rally_8_in : #{space.name}", r
+ r
+ end
+
+ def rally_8_priority(spaces)
+ # Algeria -> most Guerrillas -> no gov cubes
+ f = _filter(spaces) { |s| !s.country? }
+ f = _max(f, :guerrillas)
+ _filter(f) { |s| s.gov_cubes.zero? }.shuffle
+ end
+
# 8.1.2 - Procedure Guidelines
- def fln_to_place?
- @board.available_fln_underground.positive? || !place_from(@board.spaces).nil?
+
+ def _filter(spaces, &block)
+ (f = spaces.select(&block)).empty? ? spaces : f
+ end
+
+ def _max(spaces, sym)
+ v = spaces.max { |a, b| a.send(sym) <=> b.send(sym) }.send(sym)
+ spaces.select { |s| s.send(sym) == v }
+ end
+
+ def _min(spaces, sym)
+ v = spaces.min { |a, b| a.send(sym) <=> b.send(sym) }.send(sym)
+ spaces.select { |s| s.send(sym) == v }
+ end
+
+ def may_add_base_in?(space)
+ space.guerrillas > 2 && (space.fln_bases < (space.country? ? space.max_bases : 1))
+ end
+
+ def max_placable_guerrillas_in?(space)
+ n = max_placable_guerrillas(space)
+ n = n.clamp(0, space.pop + 1 - space.guerrillas) if space.fln_bases.positive?
+ n
end
- # 1) place: outofplay -> available | bases -> cubes if choice
- # 2) place: underground first unless from map then place active first flipped as underground
- # 3) march: underground -> active, unless march would activate then move active first
+ # 1) place: outofplay -> available | bases -> guerrillas if choice
+ # 2) place: underground first unless from map then place active first flipped as underground
+ # 3) march: underground -> active, unless march would activate then move active first
- def place_in(spaces)
+ def place_guerrillas(spaces)
# 4) support -> with friendly pieces -> random
l0 = (l0 = spaces.select(&:support?)).empty? ? spaces : l0
- l1 = (l1 = l0.select { |s| s.fln_cubes.positive? }).empty? ? l0 : l1
- (l1.empty? ? @board.spaces : l1).sample
+ l1 = (l1 = l0.select { |s| s.guerrillas.positive? }).empty? ? l0 : l1
+ l1.shuffle
end
- def place_from(spaces)
- # 5) active only, leave 2 cubes at base or support, most cubes first
- l = spaces.select do |s|
- s.fln_active.positive? && (s.support? || s.fln_bases.positive? ? s.fln_cubes > 2 : true)
- end
- return nil if l.empty?
+ def removable_guerrillas(space)
+ # 5) active only, leave 2 guerrillas at base or support
+ a = (a = space.fln_underground) > 2 ? 2 : a
+ n = space.fln_active - (space.support? || space.fln_bases.positive? ? (2 - a) : 0)
+ n.positive? ? n : 0
+ end
+
+ def not_selected(spaces, steps)
+ spaces.reject { |s| steps.key?(s) }
+ end
+
+ def remove_guerrillas_priority(spaces, steps)
+ # 5) #removable_guerrillas then most guerrillas first
+ return [] if (l = not_selected(spaces, steps).select { |s| removable_guerrillas(s).positive? }).empty?
- v = l.max { |a, b| a.fln_cubes <=> b.fln_cubes }.fln_cubes
- l.select { |s| s.fln_cubes == v }.sample
+ _max(l, :guerrillas).shuffle
end
def remove_from(space, num = 1)
diff --git a/spec/fln_bot_rules_spec.rb b/spec/fln_bot_rules_spec.rb
index 2330ac1..547e2ea 100644
--- a/spec/fln_bot_rules_spec.rb
+++ b/spec/fln_bot_rules_spec.rb
@@ -1,279 +1,466 @@
# frozen_string_literal: true
require './lib/colonial_twilight/fln_bot_rules'
-require './lib/colonial_twilight/game'
+require './spec/mock_board'
class FLNRulesImpl
include ColonialTwilight::FLNBotRules
+ attr_reader :board
+ attr_writer :limited_op_only, :first_eligible, :will_be_next_first_eligible
+
def initialize
@debug = 0
- @board = nil
+ @board = Board.new
+ @limited_op_only = true
+ @first_eligible = true
+ @will_be_next_first_eligible = true
+ end
+
+ def set(hash = {})
+ board.sector.data = hash
+ board.sector
end
- attr_writer :board
def limited_op_only?
- true
+ @limited_op_only
end
def d6
- 5
+ 3
end
- # def first_eligible?
- # true
- # end
- #
- # def will_be_next_first_eligible?
- # true
- # end
+ def first_eligible?
+ @first_eligible
+ end
+
+ def will_be_next_first_eligible?
+ @will_be_next_first_eligible
+ end
end
describe ColonialTwilight::FLNBotRules do
-
- rules = FLNRulesImpl.new
before do
- @board = ColonialTwilight::Board.new
- @board.load :short
- rules.board = @board
+ @rules = FLNRulesImpl.new
+ @board = @rules.board
end
describe 'Pass' do
- it 'pass? no' do
- expect(rules.pass?).to be false
+ it 'pass? no resources' do
+ expect(@rules.pass?).to be true
end
- it 'pass? no resources' do
- @board.shift_track :fln_resources, -15
- expect(rules.pass?).to be true
+ it 'pass? no resources but not op only' do
+ @rules.limited_op_only = false
+ expect(@rules.pass?).to be false
+ end
+
+ it 'pass? has resources' do
+ @rules.board.fln_resources = 15
+ expect(@rules.pass?).to be false
end
end
describe 'Terror' do
- it 'terror1? no' do
- expect(rules.terror1?).to be false
+ it 'terror1? 1 pop 2 underground' do
+ @rules.set({ pop: 1, fln_bases: 1, fln_underground: 2 })
+ expect(@rules.terror1?).to be true
end
- it 'terror1? all bases are protected' do
- @board.by_name('Souk Ahras').add :fln_underground
- @board.by_name('Tizi Ouzou').add :fln_underground
- @board.by_name('Bougie').add :fln_underground
- @board.by_name('Orleansville').add :fln_underground
- expect(rules.terror1?).to be true
+ it 'terror1? 1 pop 1 underground' do
+ @rules.set({ pop: 1, fln_bases: 1, fln_underground: 1 })
+ expect(@rules.terror1?).to be false
end
- # it 'terror2? true' do
- # expect(rules.terror2?).to be false
- # end
+ it 'terror1? 0 pop 1 underground' do
+ @rules.set({ pop: 0, fln_bases: 1, fln_underground: 1 })
+ expect(@rules.terror1?).to be true
+ end
+
+ it 'terror1? 0 pop 0 underground' do
+ @rules.set({ pop: 0, fln_bases: 1, fln_underground: 0 })
+ expect(@rules.terror1?).to be false
+ end
+
+ it 'terror2?' do
+ expect(@rules.terror2?).to be false
+ end
+
+ it 'terror2? true' do
+ @rules.first_eligible = false
+ expect(@rules.terror2?).to be true
+ end
+
+ it 'terror2? true' do
+ @rules.first_eligible = false
+ @rules.will_be_next_first_eligible = false
+ expect(@rules.terror2?).to be false
+ end
end
describe 'Rally' do
-
it 'rally1? false' do
- expect(rules.rally1?).to be false
+ expect(@rules.rally1?).to be false
end
it 'rally1? may rally_1' do
- space = @board.by_name('Barika')
- space.add :fln_active, 2
- expect(rules.rally1?).to be true
+ @rules.set({ fln_active: 1, fln_underground: 2 })
+ expect(@rules.rally1?).to be true
end
it 'rally1? may rally_2' do
- space = @board.by_name('Barika')
- space.add :fln_active, 3
- expect(rules.rally1?).to be true
+ @rules.set({ fln_active: 2, fln_underground: 2 })
+ expect(@rules.rally1?).to be true
+ end
+
+ it 'rally1? may rally_1 but no bases' do
+ @rules.set({ fln_active: 1, fln_underground: 2 })
+ @board.available_fln_bases = 0
+ expect(@rules.rally1?).to be false
+ end
+
+ it 'rally1? may rally_2 but no bases' do
+ @rules.set({ fln_active: 2, fln_underground: 2 })
+ @board.available_fln_bases = 0
+ expect(@rules.rally1?).to be false
end
it 'rally2? enough fln at bases' do
- expect(rules.rally2?).to be true
+ @rules.set({ fln_bases: 2, fln_underground: 3 })
+ expect(@rules.rally2?).to be false
end
it 'rally2? false' do
- @board.by_name('Bougie').add :fln_active, 1
- expect(rules.rally2?).to be false
+ @rules.set({ fln_bases: 2, fln_underground: 2 })
+ expect(@rules.rally2?).to be true
end
+ end
- it 'may_add_base_in?' do
- expect(@board.spaces.select(&rules.method(:may_add_base_in?)).size).to eq(0)
+ describe 'Rally Specific' do
+ it 'may_rally_1_in? not enough fln guerrillas' do
+ a = Sector.new({ fln_active: 1, fln_underground: 1 })
+ expect(@rules.may_rally_1_in?(a)).to be false
end
- it 'may_add_base_in?' do
- @board.by_name('Batna').add :fln_active, 3
- expect(@board.spaces.select(&rules.method(:may_add_base_in?))[0].name).to eq('Batna')
+ it 'may_rally_1_in? 3+ guerrillas' do
+ a = Sector.new({ fln_active: 1, fln_underground: 2 })
+ expect(@rules.may_rally_1_in?(a)).to be true
end
- it 'may_add_base_in?' do
- space = @board.by_name('Batna')
- space.add :fln_active, 6
- space.add :fln_base, 1
- expect(@board.spaces.select(&rules.method(:may_add_base_in?)).size).to eq(0)
+ it 'may_rally_1_in? 3+ guerrillas no limited op' do
+ a = Sector.new({ fln_active: 1, fln_underground: 2 })
+ @rules.limited_op_only = false
+ expect(@rules.may_rally_1_in?(a)).to be true
end
- it 'rally_1_in? not enough fln cubes' do
- space = @board.by_name('Barika')
- expect(rules.rally_1_in?(space)).to be false
+ it 'may_rally_1_in? 3+ guerrillas but gov cubes' do
+ a = Sector.new({ fln_active: 1, fln_underground: 2, gov_cubes: 1 })
+ @rules.limited_op_only = false
+ expect(@rules.may_rally_1_in?(a)).to be false
end
- it 'rally_1_in? enough fln cubes' do
- space = @board.by_name('Barika')
- space.add :fln_active, 2
- expect(rules.rally_1_in?(space)).to be true
+ it 'may_rally_2_in? not enough fln guerrillas' do
+ a = Sector.new({ fln_active: 2, fln_underground: 1 })
+ expect(@rules.may_rally_2_in?(a)).to be false
end
- it 'rally_2_in? not enough fln cubes' do
- space = @board.by_name('Barika')
- expect(rules.rally_2_in?(space)).to be false
+ it 'may_rally_2_in? 4+ guerrillas' do
+ a = Sector.new({ fln_active: 2, fln_underground: 2 })
+ expect(@rules.may_rally_2_in?(a)).to be true
end
- it 'rally_2_in? enough fln cubes' do
- space = @board.by_name('Barika')
- space.add :fln_active, 3
- expect(rules.rally_2_in?(space)).to be true
+ it 'may_rally_3_in? no base' do
+ a = Sector.new
+ expect(@rules.may_rally_3_in?(a)).to be false
end
- it 'rally_3_in? no base' do
- space = @board.by_name('Batna')
- expect(rules.rally_3_in?(space)).to be false
+ it 'may_rally_3_in? base and pop 0' do
+ a = Sector.new({ fln_bases: 1 })
+ expect(@rules.may_rally_3_in?(a)).to be true
end
- it 'rally_3_in? base and 0 pop and 0 fln underground' do
- space = @board.by_name('Batna')
- space.add :fln_base, 1
- expect(rules.rally_3_in?(space)).to be true
+ it 'may_rally_3_in? base and pop 0 but has fln underground' do
+ a = Sector.new({ fln_bases: 1, fln_underground: 1 })
+ expect(@rules.may_rally_3_in?(a)).to be false
end
- it 'rally_3_in? base and 0 pop but fln underground' do
- space = @board.by_name('Batna')
- space.add :fln_base, 1
- space.add :fln_underground, 1
- expect(rules.rally_3_in?(space)).to be false
+ it 'may_rally_3_in? base and country but not independent' do
+ a = Sector.new({ fln_bases: 1, pop: 1, name: 'country', independent: false })
+ expect(@rules.may_rally_3_in?(a)).to be false
end
- it 'rally_3_in? base and not enough fln underground' do
- space = @board.by_name('Bougie')
- expect(rules.rally_3_in?(space)).to be true
+ it 'may_rally_3_in? base and country' do
+ a = Sector.new({ fln_bases: 1, pop: 1, name: 'country', independent: true })
+ expect(@rules.may_rally_3_in?(a)).to be true
end
- it 'rally_3_in? base but not enough fln underground' do
- space = @board.by_name('Bougie')
- space.add :fln_underground, 1
- expect(rules.rally_3_in?(space)).to be false
+ it 'may_rally_3_in? base and country but has fln underground' do
+ a = Sector.new({ fln_bases: 1, pop: 1, name: 'country', independent: true, fln_underground: 1 })
+ expect(@rules.may_rally_3_in?(a)).to be false
+ end
+
+ it 'may_rally_3_in? base and pop' do
+ a = Sector.new({ fln_bases: 1, pop: 1, fln_underground: 1 })
+ expect(@rules.may_rally_3_in?(a)).to be true
+ end
+
+ it 'may_rally_3_in? base and pop but too many fln underground ' do
+ a = Sector.new({ fln_bases: 1, pop: 1, fln_underground: 2 })
+ expect(@rules.may_rally_3_in?(a)).to be false
end
it 'rally_3_priority Algeria' do
- a = @board.by_name('Ain Oussera')
- b = @board.by_name('Morocco')
- b.add :fln_base, -2
- b.add :fln_underground, -4
- expect(rules.rally_3_priority([a, b]).name).to eq('Ain Oussera')
+ a = Sector.new
+ b = Sector.new({ name: 'country' })
+ expect(@rules.rally_3_priority([a, b])[0]).to be a
end
it 'rally_3_priority with GOV cubes' do
- a = @board.by_name('Mecheria')
- b = @board.by_name('Saida')
- expect(rules.rally_3_priority([a, b]).name).to eq('Mecheria')
+ a = Sector.new
+ b = Sector.new({ gov_cubes: 1 })
+ expect(@rules.rally_3_priority([a, b])[0]).to be b
end
it 'rally_3_priority pop 1+' do
- a = @board.by_name('Ain Oussera')
- b = @board.by_name('Sidi Aissa')
- expect(rules.rally_3_priority([a, b]).name).to eq('Ain Oussera')
+ a = Sector.new({ pop: 1 })
+ b = Sector.new({ gov_cubes: 1, pop: 1 })
+ c = Sector.new({ gov_cubes: 1 })
+ expect(@rules.rally_3_priority([a, b, c])[0]).to be b
end
it 'rally_3_priority least fln_underground' do
- a = @board.by_name('Tebessa')
- a.add :fln_underground, 1
- b = @board.by_name('Barika')
- expect(rules.rally_3_priority([a, b]).name).to eq('Barika')
+ a = Sector.new({ pop: 1 })
+ b = Sector.new({ gov_cubes: 1, pop: 1 })
+ c = Sector.new({ gov_cubes: 1, pop: 1, fln_underground: 1 })
+ expect(@rules.rally_3_priority([a, b, c])[0]).to be b
+ end
+
+ it 'may_rally_5_in? city' do
+ a = Sector.new({ name: 'city', support: true })
+ expect(@rules.may_rally_5_in?(a)).to be false
+ end
+
+ it 'may_rally_5_in? fln underground' do
+ a = Sector.new({ support: true, fln_underground: 1 })
+ expect(@rules.may_rally_5_in?(a)).to be false
+ end
+
+ it 'may_rally_5_in? no support' do
+ a = Sector.new({ support: false })
+ expect(@rules.may_rally_5_in?(a)).to be false
+ end
+
+ it 'may_rally_5_in? good' do
+ a = Sector.new({ support: true })
+ expect(@rules.may_rally_5_in?(a)).to be true
+ end
+
+ it 'rally_5_priority most pop' do
+ a = Sector.new({ pop: 1 })
+ b = Sector.new({ pop: 2 })
+ expect(@rules.rally_5_priority([a, b])[0]).to be b
+ end
+
+ it 'may_rally_6_in? pop 1' do
+ a = Sector.new({ pop: 1 })
+ expect(@rules.may_rally_6_in?(a, false)).to be false
+ end
+
+ it 'may_rally_6_in? pop 1+' do
+ a = Sector.new({ pop: 2 })
+ expect(@rules.may_rally_6_in?(a, false)).to be true
+ end
+
+ it 'rally_6_priority population' do
+ a = Sector.new({ pop: 2 })
+ b = Sector.new({ pop: 1 })
+ expect(@rules.rally_6_priority([a, b])[0]).to be a
+ end
+
+ it 'rally_6_priority min terror' do
+ a = Sector.new({ pop: 1, terror: 2 })
+ b = Sector.new({ pop: 2, terror: 1 })
+ c = Sector.new({ pop: 2, terror: 2 })
+ expect(@rules.rally_6_priority([a, b, c])[0]).to be b
+ end
+
+ it 'rally_6_priority support' do
+ a = Sector.new({ pop: 2, terror: 1, support: false })
+ b = Sector.new({ pop: 2, terror: 1, support: true })
+ c = Sector.new({ pop: 2, terror: 2, support: true })
+ expect(@rules.rally_6_priority([a, b, c])[0]).to be b
+ end
+
+ it 'may_rally_7_in?' do
+ a = Sector.new
+ expect(@rules.may_rally_7_in?(a)).to be true
+ end
+
+ it 'may_rally_7_in? not in city at support' do
+ a = Sector.new({ name: 'city', support: true })
+ expect(@rules.may_rally_7_in?(a)).to be false
+ end
+
+ it 'may_rally_7_in? not in not independent country' do
+ a = Sector.new({ name: 'country', independent: false })
+ expect(@rules.may_rally_7_in?(a)).to be false
+ end
+
+ it 'rally_7_priority_after city?' do
+ a = Sector.new({ name: 'city' })
+ b = Sector.new
+ expect(@rules.rally_7_priority_after([a, b])[0]).to be a
+ end
+
+ it 'rally_7_priority_after least terror' do
+ a = Sector.new
+ b = Sector.new({ name: 'city', terror: 1 })
+ c = Sector.new({ name: 'city', terror: 2 })
+ expect(@rules.rally_7_priority_after([a, b, c])[0]).to be b
end
- it 'rally_5_in? city' do
- space = @board.by_name('Oran')
- expect(rules.rally_5_in?(space)).to be false
+ it 'rally_7_priority population' do
+ a = Sector.new({ pop: 2 })
+ b = Sector.new({ pop: 1 })
+ expect(@rules.rally_7_priority([a, b])[0]).to be a
end
- it 'rally_5_in? support but fln underground' do
- space = @board.by_name('Barika')
- space.shift :support
- expect(rules.rally_5_in?(space)).to be false
+ it 'rally_7_priority population' do
+ a = Sector.new({ pop: 2 })
+ b = Sector.new({ pop: 1 })
+ expect(@rules.rally_7_priority([a, b])[0]).to be a
end
- it 'rally_5_in? support and fln underground' do
- space = @board.by_name('Barika')
- space.shift :support
- space.add :fln_underground, -1
- expect(rules.rally_5_in?(space)).to be false
+ it 'may_rally_8_in? no fln guerrillas' do
+ a = Sector.new
+ expect(@rules.may_rally_8_in?(a)).to be false
end
- it 'rally_6_in? 2+ pop but no fln control' do
- space = @board.by_name('Medea')
- expect(rules.rally_6_in?(space)).to be false
+ it 'may_rally_8_in? fln guerrillas but base' do
+ a = Sector.new({ fln_active: 1, fln_bases: 1 })
+ expect(@rules.may_rally_8_in?(a)).to be false
end
- it 'rally_6_in? 2+ pop and fln' do
- space = @board.by_name('Medea')
- space.add :fln_active, 3
- expect(rules.rally_6_in?(space)).to be true
+ it 'may_rally_8_in? fln guerrillas and 0 base' do
+ a = Sector.new({ fln_underground: 1 })
+ expect(@rules.may_rally_8_in?(a)).to be true
end
- it 'rally_8_in? no fln cubes' do
- space = @board.by_name('Tiaret')
- expect(rules.rally_8_in?(space)).to be false
+ it 'rally_8_priority Algeria' do
+ a = Sector.new
+ b = Sector.new({ name: 'country' })
+ expect(@rules.rally_8_priority([a, b])[0]).to be a
end
- it 'rally_8_in? fln cubes but base' do
- space = @board.by_name('Bougie')
- expect(rules.rally_8_in?(space)).to be false
+ it 'rally_8_priority most guerrillas' do
+ a = Sector.new
+ b = Sector.new({ fln_active: 2, fln_underground: 1 })
+ c = Sector.new({ fln_active: 1, fln_underground: 1 })
+ expect(@rules.rally_8_priority([a, b, c])[0]).to be b
end
- it 'rally_8_in? fln cubes and 0 base' do
- space = @board.by_name('Barika')
- expect(rules.rally_8_in?(space)).to be true
+ it 'rally_8_priority no cubes' do
+ a = Sector.new
+ b = Sector.new({ fln_active: 1, fln_underground: 1 })
+ c = Sector.new({ fln_active: 1, fln_underground: 1, gov_cubes: 1 })
+ expect(@rules.rally_8_priority([a, b, c])[0]).to be b
end
end
describe '8.1.2 Procedure Guidelines' do
- it 'place_in' do
- expect(rules.place_in(@board.spaces).city?).to be true
+ it 'may_add_base_in?' do
+ a = Sector.new({ fln_active: 3 })
+ expect(@rules.may_add_base_in?(a)).to be true
+ end
+
+ it 'may_add_base_in? not enough fln' do
+ a = Sector.new({ fln_active: 2 })
+ expect(@rules.may_add_base_in?(a)).to be false
+ end
+
+ it 'may_add_base_in? but has base' do
+ a = Sector.new({ fln_bases: 1, fln_active: 3 })
+ expect(@rules.may_add_base_in?(a)).to be false
+ end
+
+ it 'may_add_base_in? country ' do
+ a = Sector.new({ name: 'country', fln_bases: 2, fln_active: 3 })
+ expect(@rules.may_add_base_in?(a)).to be true
+ end
+
+ it 'may_add_base_in? country but limit' do
+ a = Sector.new({ name: 'country', fln_bases: 3, fln_active: 3 })
+ expect(@rules.may_add_base_in?(a)).to be false
+ end
+
+ it 'max_placable_guerrillas_in? 1' do
+ a = Sector.new({ pop: 2 })
+ expect(@rules.max_placable_guerrillas_in?(a)).to eq(1)
+ end
+
+ it 'max_placable_guerrillas_in? pop + base' do
+ a = Sector.new({ pop: 2, fln_bases: 1 })
+ expect(@rules.max_placable_guerrillas_in?(a)).to eq(3)
+ end
+
+ it 'max_placable_guerrillas_in? max pop + 1' do
+ a = Sector.new({ pop: 2, fln_bases: 1, fln_active: 1, fln_underground: 1 })
+ expect(@rules.max_placable_guerrillas_in?(a)).to eq(1)
+ end
+
+ it 'removable_guerrillas active' do
+ a = Sector.new({ fln_active: 2, fln_underground: 3 })
+ expect(@rules.removable_guerrillas(a)).to eq(2)
+ end
+
+ it 'removable_guerrillas leave 2 at support' do
+ a = Sector.new({ support: true, fln_active: 3 })
+ expect(@rules.removable_guerrillas(a)).to eq(1)
+ end
+
+ it 'removable guerrillas leave 2 at bases' do
+ a = Sector.new({ fln_bases: 1, fln_active: 3, fln_underground: 1 })
+ expect(@rules.removable_guerrillas(a)).to eq(2)
end
- it 'place_in support' do
- space = @board.by_name('Mostaganem')
- space.add :fln_active, 3
- expect(rules.place_in(@board.spaces).city?).to be true
+ it 'place_guerrillas support' do
+ a = Sector.new({ support: false })
+ b = Sector.new({ support: true })
+ c = Sector.new({ support: false })
+ expect(@rules.place_guerrillas([a, b, c])[0]).to be b
end
- it 'place_in support and fln_active' do
- space = @board.by_name('Mostaganem')
- space.shift :support
- space.add :fln_active, 3
- expect(rules.place_in(@board.spaces).name).to be 'Mostaganem'
+ it 'place_guerrillas support and fln_active' do
+ a = Sector.new({ support: false })
+ b = Sector.new({ support: true, fln_active: 1 })
+ c = Sector.new({ support: true })
+ expect(@rules.place_guerrillas([a, b, c])[0]).to be b
end
- it 'place_from none' do
- expect(rules.place_from(@board.spaces).nil?).to be true
+ it 'remove_guerrillas_priority none' do
+ a = Sector.new
+ b = Sector.new
+ expect(@rules.remove_guerrillas_priority([a, b], {}).empty?).to be true
end
- it 'place_from most active' do
- @board.by_name('Oran').add :fln_active, 1
- @board.by_name('Batna').add :fln_active, 3
- @board.by_name('Negrine').add :fln_active, 2
- expect(rules.place_from(@board.spaces).name).to be 'Batna'
+ it 'remove_guerrillas_priority most guerrillas' do
+ a = Sector.new({ fln_active: 2, fln_underground: 1 })
+ b = Sector.new({ fln_active: 2, fln_underground: 2 })
+ c = Sector.new({ fln_active: 1, fln_underground: 2 })
+ d = Sector.new({ fln_active: 3, fln_underground: 2 })
+ expect(@rules.remove_guerrillas_priority([a, b, c, d], { d => true })[0]).to be b
end
it 'remove_from all' do
- space = @board.by_name('Bougie')
- space.add :fln_active, 2
- h = rules.remove_from(space, 6)
+ a = Sector.new({ fln_active: 2, fln_underground: 1, fln_bases: 1 })
+ h = @rules.remove_from(a, 6)
expect(h[:fln_underground]).to be 1
expect(h[:fln_active]).to be 2
expect(h[:fln_bases]).to be 1
end
it 'remove_from a few' do
- space = @board.by_name('Bougie')
- space.add :fln_active, 1
- h = rules.remove_from(space, 2)
+ a = Sector.new({ fln_active: 1, fln_underground: 1 })
+ h = @rules.remove_from(a, 2)
expect(h[:fln_underground]).to be 1
expect(h[:fln_active]).to be 1
expect(h[:fln_bases]).to be 0