diff options
-rw-r--r-- | lib/colonial_twilight/board.rb | 712 |
1 files changed, 416 insertions, 296 deletions
diff --git a/lib/colonial_twilight/board.rb b/lib/colonial_twilight/board.rb index 9110755..facbbbe 100644 --- a/lib/colonial_twilight/board.rb +++ b/lib/colonial_twilight/board.rb @@ -1,47 +1,46 @@ #! /usr/bin/env ruby -# -*- coding: UTF-8 -*- +# frozen_string_literal: true -module ColonialTwilight +# rubocop:disable Style/AccessorGrouping +# rubocop:disable Style/ParallelAssignment +# rubocop:disable Layout/ArrayAlignment +module ColonialTwilight + # pieces container class Forces - attr_accessor :algerian_troops, :algerian_police attr_accessor :french_troops, :french_police attr_accessor :fln_underground, :fln_active attr_accessor :fln_bases, :gov_bases attr_reader :max_bases, :control - def initialize k - @algerian_troops = 0 - @algerian_police = 0 - @french_troops = 0 - @french_police = 0 - @gov_bases = 0 - @fln_underground = 0 - @fln_active = 0 - @fln_bases = 0 + def initialize(kind) + @algerian_troops, @algerian_police = 0, 0 + @french_troops, @french_police, @gov_bases = 0, 0, 0 + @fln_underground, @fln_active, @fln_bases = 0, 0, 0 @max_bases = nil @control = :uncontrolled - rm = nil - case k - when :available - rm = [:@control, :@fln_active] - when :casualties - rm = [:@control, :@fln_active, :@fln_bases] - when :out_of_play - rm = [:@control, :@algerian_troops, :@algerian_police, :@fln_active, :@fln_bases] - when :Country - @max_bases = 2 - rm = [:@control, :@algerian_troops, :@algerian_police, :@french_troops, :@french_police, :@gov_bases] - when :Sector - @max_bases = 2 - end - rm.each do |sym| + @max_bases = 2 if %i[Country Sector].include? kind + _instance_variables(kind)&.each do |sym| instance_variable_set(sym, nil) - end unless rm.nil? + end end - def to_s; inspect end + private + + def _instance_variables(kind) + case kind + when :available then %i[@control @fln_active] + when :casualties then %i[@control @fln_active @fln_bases] + when :out_of_play then %i[@control @algerian_troops @algerian_police @fln_active @fln_bases] + when :Country then %i[@control @algerian_troops @algerian_police @french_troops @french_police @gov_bases] + when :Sector then nil + end + end + + public + + alias to_s inspect def inspect " #{gov_bases} GOV bases @@ -55,28 +54,28 @@ module ColonialTwilight end def data - h={} - [:algerian_troops, :algerian_police, :french_troops, :french_police, - :fln_underground, :fln_active, :fln_bases, :gov_bases, :control].each do |sym| + h = {} + %i[algerian_troops algerian_police french_troops french_police + fln_underground fln_active fln_bases gov_bases control].each do |sym| h[sym] = send(sym) unless send(sym).nil? end h end def bases - (@gov_bases||0) + (@fln_bases||0) + (@gov_bases || 0) + (@fln_bases || 0) end def fln - guerrillas + (@fln_bases||0) + guerrillas + (@fln_bases || 0) end def guerrillas - (@fln_underground||0) + (@fln_active||0) + (@fln_underground || 0) + (@fln_active || 0) end def gov - gov_cubes + (@gov_bases||0) + gov_cubes + (@gov_bases || 0) end def gov_cubes @@ -84,208 +83,323 @@ module ColonialTwilight end def french_cubes - (@french_troops||0) + (@french_police||0) + (@french_troops || 0) + (@french_police || 0) end def algerian_cubes - (@algerian_troops||0) + (@algerian_police||0) + (@algerian_troops || 0) + (@algerian_police || 0) end def troops - (@french_troops||0) + (@algerian_troops||0) + (@french_troops || 0) + (@algerian_troops || 0) end def police - (@french_police||0) + (@algerian_police||0) - end - - def add t, n=1 - case t - when :french_troops; @french_troops += n - when :french_police; @french_police += n - when :algerian_troops; @algerian_troops += n - when :algerian_police; @algerian_police += n - when :fln_underground; @fln_underground += n - when :fln_active; @fln_active += n - when :gov_base; add_base :gov_base, n - when :fln_base; add_base :fln_base, n + (@french_police || 0) + (@algerian_police || 0) + end + + def add(type, num = 1) + case type + when :french_troops then @french_troops += num + when :french_police then @french_police += num + when :algerian_troops then @algerian_troops += num + when :algerian_police then @algerian_police += num + when :fln_underground then @fln_underground += num + when :fln_active then @fln_active += num + when :gov_base then add_base(:gov_base, num) + when :fln_base then add_base(:fln_base, num) else - raise "unknown force type : #{t}" + raise "unknown force type : #{type}" end update_control end private - def add_base t, n=1 - raise "too much bases in #@name (#{bases} + #{n}) > #@max_bases" if not @max_bases.nil? and (bases + n) > @max_bases - @gov_bases += n if t == :gov_base - @fln_bases += n if t == :fln_base + def add_base(type, num = 1) + if !@max_bases.nil? && (bases + num) > @max_bases + raise "too much bases in #{@name} (#{bases} + #{num}) > #{@max_bases}" + end + + @gov_bases += num if type == :gov_base + @fln_bases += num if type == :fln_base end def update_control return if @control.nil? + @control = ( case gov <=> fln - when 0; :uncontrolled - when 1; :GOV - when -1; :FLN + when 0 then :uncontrolled + when 1 then :GOV + when -1 then :FLN end - ) + ) end - end + # a point Track class Track attr_accessor :v - def initialize max + + def initialize(max) @v = 0 @max = max end - def shift v - w = @v + v - return false if (w < 0 or w > @max) + + def shift(val) + w = @v + val + return false if w.negative? || w > @max + @v = w true end - def clamp v - @v = (@v + v).clamp(0, @max) + + def clamp(val) + @v = (@v + val).clamp(0, @max) + end + + def data + @v end - def data; @v end end + # a piece holding Box class Box < Forces attr_reader :name - def initialize sym + + def initialize(sym) super sym @name = sym end end + # a map Sector class Sector - - MOUNTAIN=1 - COASTAL=2 - BORDER=4 + MOUNTAIN = 1 + COASTAL = 2 + BORDER = 4 attr_reader :wilaya, :sector, :name, :resettled attr_accessor :pop, :terror, :adjacents attr_accessor :alignment - def initialize n, w, s, p, attrs=0 - @name = n - @wilaya = w - @sector = s - @pop = p - @terror = 0 - @attributes = attrs - @descr = "#{self.class.name} #@name #{@wilaya == 0 ? '' : @wilaya}" + (@sector == 0 ? '' : "-#{@sector}") - @terrain = [mountain? ? 'mountain' : nil ,coastal? ? 'coastal' : nil, border? ? 'border' : nil].reject(&:nil?).join '/' - @forces = Forces.new self.class.name.split('::')[-1].to_sym + def initialize(name, wilaya, sector, pop, attrs = 0) + @name = name + @wilaya = wilaya + @sector = sector + @pop = pop + @attrs = attrs @alignment = :neutral @resettled = false + @terror = 0 + @forces = Forces.new self.class.name.split('::')[-1].to_sym + _compute_strings + end + + private + + def _compute_strings + @terrain = %i[mountain coastal border].map { |s| send("#{s}?") ? s : nil }.reject(&:nil?).join('/') + @descr = "#{self.class.name} #{@name} #{@wilaya.nil? ? '' : @wilaya}" + (@sector.nil? ? '' : "-#{@sector}") + end + + public + + def to_s + @name end - def to_s; @name end def inspect - "#@descr #@terrain + "#{@descr} #{@terrain} control : #{@forces.control} - alignment : #@alignment - terror : #@terror + alignment : #{@alignment} + terror : #{@terror} population : #{@pop}#{@resettled ? ' resettled' : ''} forces : #{@forces} adjs : #{@adjacents}" end def data - { :name=>@name, :alignment=>@alignment, :terror=>@terror, :pop=>@pop, :resettled=>@resettled }.merge(@forces.data) - end - - [:gov, :gov_cubes, :french_cubes, :algerian_cubes, :troops, :police, :gov_bases, :french_troops, :french_police, :algerian_troops, :algerian_police, - :fln, :guerrillas, :fln_bases, :fln_underground, :fln_active, - :max_bases].each do |sym| - define_method sym do @forces.send(sym) end - end - - def city?; false; end - def country?; false; end - def border?; (@attributes & BORDER) == BORDER end - def coastal?; (@attributes & COASTAL) == COASTAL end - def mountain?; (@attributes & MOUNTAIN) == MOUNTAIN end - def support?; @alignment == :support end - def oppose?; @alignment == :oppose end - def neutral?; @alignment == :neutral end - def control; @forces.control end - def uncontrolled?; @forces.control == :uncontrolled end - def fln_control?; @forces.control == :FLN end - def gov_control?; @forces.control == :GOV end - def has_terror?; terror > 0 end - def has_gov?; not gov_bases_0? or not gov_cubes_0? end - def has_fln?; not fln_bases_0? or fln > 0 end - def gov_bases_0?; gov_bases == 0 end - def fln_bases_0?; fln_bases == 0 end - def gov_bases_1m?; gov_bases > 0 end - def fln_bases_1m?; fln_bases > 0 end - def pop0?; pop == 0 end - def gov_cubes_0?; gov_cubes == 0 end - def add t, n=1; @forces.add t, n end - def fln_u_1l?; fln_underground < 2 end - def fln_u_0?; fln_underground == 0 end - def fln_u_1m?; fln_underground > 0 end - def fln_u_2m?; fln_underground > 1 end - def fln_u_3m?; fln_underground > 2 end + { name: @name, alignment: @alignment, terror: @terror, pop: @pop, resettled: @resettled }.merge(@forces.data) + end + + %i[gov gov_cubes french_cubes algerian_cubes troops police gov_bases + french_troops french_police algerian_troops algerian_police + fln guerrillas fln_bases fln_underground fln_active max_bases].each do |sym| + define_method(sym) { @forces.send(sym) } + end + + def city? + false + end + + def country? + false + end + + def border? + (@attrs & BORDER) == BORDER + end + + def coastal? + (@attrs & COASTAL) == COASTAL + end + + def mountain? + (@attrs & MOUNTAIN) == MOUNTAIN + end + + def support? + @alignment == :support + end + + def oppose? + @alignment == :oppose + end + + def neutral? + @alignment == :neutral + end + + def control + @forces.control + end + + def uncontrolled? + @forces.control == :uncontrolled + end + + def fln_control? + @forces.control == :FLN + end + + def gov_control? + @forces.control == :GOV + end + + def has_terror? + terror.positive? + end + + def has_gov? + !gov_bases_0? || !gov_cubes_0? + end + + def has_fln? + !fln_bases_0? or fln.positive? + end + + def gov_bases_0? + gov_bases.zero? + end + + def fln_bases_0? + fln_bases.zero? + end + + def gov_bases_1m? + gov_bases.positive? + end + + def fln_bases_1m? + fln_bases.positive? + end + + def pop0? + pop.zero? + end + + def gov_cubes_0? + gov_cubes.zero? + end + + def add(type, num = 1) + @forces.add(type, num) + end + + def fln_u_1l? + fln_underground < 2 + end + + def fln_u_0? + fln_underground.zero? + end + + def fln_u_1m? + fln_underground.positive? + end + + def fln_u_2m? + fln_underground > 1 + end + + def fln_u_3m? + fln_underground > 2 + end + def resettle! raise "can't resettle a country " if country? raise "can't resettle a sector with a population > 1" if @pop != 1 + @pop = 0 @resettled = true end - def shift towards + def shift(towards) if towards == :oppose raise "can't shift towards oppose" if oppose? + @alignment = (support? ? :neutral : :oppose) - end - if towards == :support + elsif towards == :support raise "can't shift towards support" if support? + @alignment = (oppose? ? :neutral : :support) end end - end + # a City Sector class City < Sector - def initialize n, w, p, attrs=0 - super n, w, 0, p, attrs + def initialize(name, wilaya, pop, attrs = 0) + super name, wilaya, 0, pop, attrs + end + + def city? + true end - def city?; true; end end + # a Country Sector class Country < Sector - attr_reader :independant - def initialize n, w - super n, w, 0, 1, MOUNTAIN|BORDER|COASTAL + def initialize(name, wilaya) + super(name, wilaya, nil, 1, MOUNTAIN | BORDER | COASTAL) @descr += " #{@independant ? 'Independant' : 'French'}" end - def add_gov_base n=1; raise "no gov bases allowed in #@name" end - def country?; true; end - end + def add_gov_base + raise "no gov bases allowed in #{@name}" + end - class Board + def country? + true + end + end - FRANCE_TRACK=['A','B','C','D','E','F'].freeze + # the game Board + class Board + FRANCE_TRACK = %w[A B C D E F].freeze attr_reader :spaces_h, :spaces, :sectors, :cities, :countries - [:commitment, :gov_resources, :fln_resources, :resettled_sectors, :france_track, :border_zone_track].each do |sym| - define_method sym do instance_variable_get("@#{sym}").v end + %i[commitment gov_resources fln_resources resettled_sectors france_track border_zone_track].each do |sym| + define_method(sym) { instance_variable_get("@#{sym}").v } end - [:gov_bases, :french_troops, :french_police, :algerian_troops, :algerian_police, :fln_bases, :fln_underground].each do |sym| - define_method "available_#{sym}" do @available.send(sym) end + %i[gov_bases french_troops french_police algerian_troops algerian_police fln_bases fln_underground].each do |sym| + define_method("available_#{sym}") { @available.send(sym) } # define_method "casualties_#{sym}" do @casualties.send(sym) end # define_method "out_of_play_#{sym}" do @out_of_play.send(sym) end end @@ -305,58 +419,57 @@ module ColonialTwilight @opposition_bases = Track.new 50 @france_track = Track.new 5 @border_zone_track = Track.new 4 - feed + set_sectors + set_adjacents @spaces = @spaces_h.values - @sectors = @spaces.select { |s| not s.country? } - @cities = @spaces.select { |s| s.city? } - @countries = @spaces.select { |s| s.country? } + @sectors = @spaces.reject(&:country?) # FIXME + @cities = @spaces.select(&:city?) # FIXME + @countries = @spaces.select(&:country?) # FIXME end - def transfer n, what, from, to, towhat=nil + def transfer(num, what, from, to, towhat = nil) towhat = what if towhat.nil? from = get_var from if from.is_a? Symbol to = get_var to if to.is_a? Symbol - from.add what, -n - to.add towhat, n - { :n => n, :what => what, :from=>from, :to => to, :towhat=> towhat } + from.add what, -num + to.add towhat, num + { nn: num, what: what, from: from, to: to, towhat: towhat } end - def terror where, n - where.terror += n + def terror(where, num) + where.terror += num end - def shift where, towards, n=1 - n.times do - where.shift towards - end + def shift(where, towards, num = 1) + num.times { where.shift towards } end - def shift_track what, dt + def shift_track(what, amount) case what - when :fln_resources; @fln_resources.clamp dt - when :gov_resources; @gov_resources.clamp dt - when :commitment; @commitment.clamp dt - when :france_track; @france_track.shift dt - when :border_zone_track; @border_zone_track.shift dt + when :fln_resources then @fln_resources.clamp amount + when :gov_resources then @gov_resources.clamp amount + when :commitment then @commitment.clamp amount + when :france_track then @france_track.shift amount + when :border_zone_track then @border_zone_track.shift amount else raise "shift_track: '#{what}'unknown" end end - def has where=:spaces, &block - r = search &block - r.length > 0 + def has(where = :spaces, &block) + r = search(where, &block) + r.length.positive? end - def search where=:spaces, &block - send(where).select &block + def search(where = :spaces, &block) + send(where).select(&block) end - def count where=:spaces, &block - send(where).inject(0) {|i,s| i + block.call(s) } + def count(where = :spaces, &block) + send(where).inject(0) { |i, s| i + block.call(s) } end - def resettle sector + def resettle(sector) @spaces_h[sector].resettle! @resettled_sectors += 1 end @@ -364,8 +477,8 @@ module ColonialTwilight def compute_victory_points values = [@support_commitment.v, @opposition_bases.v] @opposition_bases.v = 0 - @support_commitment.v = @commitment.v - @spaces_h.each do |n,s| + @support_commitment.v = @commitment.v + @spaces_h.each do |_n, s| @opposition_bases.clamp s.fln_bases @opposition_bases.clamp s.pop if s.alignment == :oppose @support_commitment.clamp s.pop if s.alignment == :support @@ -374,85 +487,88 @@ module ColonialTwilight end def data - h = { } - [:gov_resources, :fln_resources, :commitment, :support_commitment, :opposition_bases, - :france_track, :border_zone_track, :available, :casualties, :out_of_play].each do |sym| + h = {} + %i[gov_resources fln_resources commitment support_commitment opposition_bases + france_track border_zone_track available casualties out_of_play].each do |sym| h[sym] = instance_variable_get("@#{sym}").data end h[:resettled_sectors] = @resettled_sectors h[:capabilities] = @capabilities - h[:spaces] = @spaces_h.inject([])do |a,(k,s)| a << s.data end + h[:spaces] = @spaces_h.inject([]) { |a, (_k, s)| a << s.data } h end - def load scenario + def load(scenario) case scenario - when :short; short - when :medium; medium - when :full; full + when :short then short + when :medium then medium + when :full then full else raise "unknown scenario : #{scenario}" end end private - def get_var sym + def get_var(sym) case sym - when :available; return @available - when :casualties; return @casualties - when :out_of_play; return @out_of_play + when :available then @available + when :casualties then @casualties + when :out_of_play then @out_of_play else raise "unknown Board variable named #{sym}" end end - def add k, *args - s = k.new *args + def add(kls, *args) + s = kls.new(*args) # puts s @names << s.name @spaces_h[s.name] = s end - def adjacents i, *args - @spaces_h[@names[i]].adjacents = args - # @spaces_h[@names[i]].adjacents = args.map { |i| @names[i] } - # puts @spaces_h[@names[i]] - end - - def feed - mountain=Sector::MOUNTAIN - border=Sector::BORDER - coastal=Sector::COASTAL - add Sector, 'Barika', 'I', 1, 1, mountain # 0 - add Sector, 'Batna', 'I', 2, 0, mountain # 1 - add Sector, 'Biskra', 'I', 3, 0, border # 2 - add Sector, 'Oum El Bouaghi', 'I', 4, 0, mountain # 3 - add Sector, 'Tebessa', 'I', 5, 1, mountain|border # 4 - add Sector, 'Negrine', 'I', 6, 0, mountain|border # 5 - add City, 'Constantine', 'II', 2 # 6 - add Sector, 'Setif', 'II', 1, 1, mountain|coastal # 7 - add Sector, 'Philippeville', 'II', 2, 2, mountain|coastal # 8 - add Sector, 'Souk Ahras', 'II', 3, 2, coastal|border # 9 - add Sector, 'Tizi Ouzou', 'III', 1, 2, mountain|coastal # 10 - add Sector, 'Bordj Bou Arreridj', 'III', 2, 1, mountain # 11 - add Sector, 'Bougie', 'III', 3, 2, mountain|coastal # 12 - add City, 'Algiers', 'IV', 3, coastal # 13 - add Sector, 'Medea', 'IV', 1, 2, mountain|coastal # 14 - add Sector, 'Orleansville', 'IV', 2, 2, mountain|coastal # 15 - add City, 'Oran', 'V', 2, coastal # 16 - add Sector, 'Mecheria', 'V', 1, 0, mountain|border # 17 - add Sector, 'Tlemcen', 'V', 2, 1, border|coastal # 18 - add Sector, 'Sidi Bel Abbes', 'V', 3, 1, coastal # 19 - add Sector, 'Mostaganem', 'V', 4, 2, mountain|coastal # 20 - add Sector, 'Saida', 'V', 5, 0, mountain # 21 - add Sector, 'Mascara', 'V', 6, 0, mountain # 22 - add Sector, 'Tiaret', 'V', 7, 0, mountain # 23 - add Sector, 'Ain Sefra', 'V', 8, 0, border # 24 - add Sector, 'Laghouat', 'V', 9, 0 # 25 - add Sector, 'Sidi Aissa', 'VI', 1, 0, mountain # 26 - add Sector, 'Ain Oussera', 'VI', 2, 1, mountain # 27 - add Country, 'Moroco', 0 # 28 - add Country, 'Tunisia', 1 # 29 + def adjacents(idx, *args) + @spaces_h[@names[idx]].adjacents = args + # @spaces_h[@names[idx]].adjacents = args.map { |i| @names[i] } + # puts @spaces_h[@names[idx]] + end + + def set_sectors + mountain = Sector::MOUNTAIN + border = Sector::BORDER + coastal = Sector::COASTAL + add Sector, 'Barika', 'I', 1, 1, mountain + add Sector, 'Batna', 'I', 2, 0, mountain + add Sector, 'Biskra', 'I', 3, 0, border + add Sector, 'Oum El Bouaghi', 'I', 4, 0, mountain + add Sector, 'Tebessa', 'I', 5, 1, mountain | border + add Sector, 'Negrine', 'I', 6, 0, mountain | border + add City, 'Constantine', 'II', 2 + add Sector, 'Setif', 'II', 1, 1, mountain | coastal + add Sector, 'Philippeville', 'II', 2, 2, mountain | coastal + add Sector, 'Souk Ahras', 'II', 3, 2, coastal | border + add Sector, 'Tizi Ouzou', 'III', 1, 2, mountain | coastal + add Sector, 'Bordj Bou Arreridj', 'III', 2, 1, mountain + add Sector, 'Bougie', 'III', 3, 2, mountain | coastal + add City, 'Algiers', 'IV', 3, coastal + add Sector, 'Medea', 'IV', 1, 2, mountain | coastal + add Sector, 'Orleansville', 'IV', 2, 2, mountain | coastal + add City, 'Oran', 'V', 2, coastal + add Sector, 'Mecheria', 'V', 1, 0, mountain | border + add Sector, 'Tlemcen', 'V', 2, 1, border | coastal + add Sector, 'Sidi Bel Abbes', 'V', 3, 1, coastal + add Sector, 'Mostaganem', 'V', 4, 2, mountain | coastal + add Sector, 'Saida', 'V', 5, 0, mountain + add Sector, 'Mascara', 'V', 6, 0, mountain + add Sector, 'Tiaret', 'V', 7, 0, mountain + add Sector, 'Ain Sefra', 'V', 8, 0, border + add Sector, 'Laghouat', 'V', 9, 0 + add Sector, 'Sidi Aissa', 'VI', 1, 0, mountain + add Sector, 'Ain Oussera', 'VI', 2, 1, mountain + add Country, 'Moroco', 0 + add Country, 'Tunisia', 1 + end + + def set_adjacents adjacents 0, 1, 2, 3, 7, 8, 11, 26 adjacents 1, 0, 2, 3, 5 adjacents 2, 0, 1, 5, 25, 26, 29 @@ -485,16 +601,18 @@ module ColonialTwilight adjacents 29, 2, 4, 5, 9 end - def set_sector i, h, align=nil - s = @spaces_h[@names[i]] + def set_sector(idx, opts, align = nil) + s = @spaces_h[@names[idx]] s.alignment = align unless align.nil? - s.add :gov_base, h[:govb] if h.has_key? :govb - s.add :fln_base, h[:flnb] if h.has_key? :flnb - s.add :french_troops, h[:ft] if h.has_key? :ft - s.add :french_police, h[:fp] if h.has_key? :fp - s.add :algerian_troops, h[:at] if h.has_key? :at - s.add :algerian_police, h[:ap] if h.has_key? :ap - s.add :fln_underground, h[:fln] if h.has_key? :fln + %i[gov_base fln_base french_troops french_police algerian_troops algerian_police + fln_underground].each { |sym| s.add(sym, opts[sym]) if opts.key? sym } + # s.add :gov_base, opts[:govb] if opts.key? :govb + # s.add :fln_base, opts[:flnb] if opts.key? :flnb + # s.add :french_troops, opts[:ft] if opts.key? :ft + # s.add :french_police, opts[:fp] if opts.key? :fp + # s.add :algerian_troops, opts[:at] if opts.key? :at + # s.add :algerian_police, opts[:ap] if opts.key? :ap + # s.add :fln_underground, opts[:fln] if opts.key? :fln # puts s end @@ -513,35 +631,36 @@ module ColonialTwilight resettle 'Setif' resettle 'Tlemcen' resettle 'Bordj Bou Arreridj' - raise "resettled sectors not counted" if @resettled_sectors != 3 - set_sector 0, {:ap=>1, :fln=>1}, :oppose - set_sector 2, {:fp=>1} - set_sector 4, {:ap=>1, :fln=>1}, :oppose - set_sector 5, {:fp=>1} - set_sector 6, {:fp=>1}, :support - set_sector 7, {:fln=>1} - set_sector 8, {:ft=>4, :ap=>1, :govb=>1} - set_sector 9, {:ft=>1, :ap=>1, :govb=>1, :fln=>1, :flnb=>1}, :oppose - set_sector 10, {:fp=>1, :fln=>1, :flnb=>1}, :oppose - set_sector 11, {:fp=>1} - set_sector 12, {:fp=>1, :fln=>1, :flnb=>1}, :oppose - set_sector 13, {:ft=>4, :at=>1, :fp=>1}, :support - set_sector 14, {:at=>1, :govb=>1} - set_sector 15, {:fp=>1, :ap=>1, :fln=>1, :flnb=>1}, :oppose - set_sector 16, {:at=>1, :fp=>1, :ap=>1}, :support - set_sector 17, {:fp=>1, :ap=>1} - set_sector 18, {:fp=>2, :fln=>1} - set_sector 19, {:fp=>1, :govb=>1} - set_sector 20, {:fp=>1} - set_sector 22, {:fp=>1} - set_sector 23, {:fp=>1} - set_sector 24, {:fp=>1} + raise 'resettled sectors not counted' if @resettled_sectors != 3 + + set_sector 0, { algerian_police: 1, fln_underground: 1 }, :oppose + set_sector 2, { french_police: 1 } + set_sector 4, { algerian_police: 1, fln_underground: 1 }, :oppose + set_sector 5, { french_police: 1 } + set_sector 6, { french_police: 1 }, :support + set_sector 7, { fln_underground: 1 } + set_sector 8, { french_troops: 4, algerian_police: 1, gov_base: 1 } + set_sector 9, { french_troops: 1, algerian_police: 1, gov_base: 1, fln_underground: 1, fln_base: 1 }, :oppose + set_sector 10, { french_police: 1, fln_underground: 1, fln_base: 1 }, :oppose + set_sector 11, { french_police: 1 } + set_sector 12, { french_police: 1, fln_underground: 1, fln_base: 1 }, :oppose + set_sector 13, { french_troops: 4, algerian_troops: 1, french_police: 1 }, :support + set_sector 14, { algerian_troops: 1, gov_base: 1 } + set_sector 15, { french_police: 1, algerian_police: 1, fln_underground: 1, fln_base: 1 }, :oppose + set_sector 16, { algerian_troops: 1, french_police: 1, algerian_police: 1 }, :support + set_sector 17, { french_police: 1, algerian_police: 1 } + set_sector 18, { french_police: 2, fln_underground: 1 } + set_sector 19, { french_police: 1, gov_base: 1 } + set_sector 20, { french_police: 1 } + set_sector 22, { french_police: 1 } + set_sector 23, { french_police: 1 } + set_sector 24, { french_police: 1 } set_sector 27, {}, :oppose - set_sector 28, {:fln=>4, :flnb=>2} - set_sector 29, {:fln=>5, :flnb=>2} + set_sector 28, { fln_underground: 4, fln_base: 2 } + set_sector 29, { fln_underground: 5, fln_base: 2 } compute_victory_points - raise "wrong opposition + bases" if @opposition_bases.v != 19 - raise "wrong support + commitment" if @support_commitment.v != 22 + raise "wrong opposition + bases #{@opposition_bases.v} != 19" if @opposition_bases.v != 19 + raise "wrong support + commitment : #{@support_commitment.v} != 22" if @support_commitment.v != 22 end def medium @@ -551,9 +670,7 @@ module ColonialTwilight def full raise 'FULL scenario net implemented yet' end - end - end # class ColonialTwilight::Sector @@ -561,55 +678,58 @@ end # end if $PROGRAM_NAME == __FILE__ - def check b + def check(board) # puts '--- Coastal' - # b.spaces.select{ |s| s.coastal? }.each { |s| puts s.name } - raise "coastal sectors error" if b.spaces.select{ |s| s.coastal? }.size != 14 + # board.spaces.select{ |s| s.coastal? }.each { |s| puts s.name } + raise 'coastal sectors error' if board.spaces.select(&:coastal?).size != 14 # puts '--- not Mountain' - # b.spaces.select{ |s| not s.mountain? }.each { |s| puts s.name } - raise "not moauntain sectors error" if b.spaces.select{ |s| not s.mountain? }.size != 9 + # board.spaces.select{ |s| not s.mountain? }.each { |s| puts s.name } + raise 'not moauntain sectors error' if board.spaces.reject(&:mountain?).size != 9 # puts '--- Border' - # b.spaces.select{ |s| s.border? }.each { |s| puts s.name } - raise "border sectors error" if b.spaces.select{ |s| s.border? }.size != 9 + # board.spaces.select{ |s| s.border? }.each { |s| puts s.name } + raise 'border sectors error' if board.spaces.select(&:border?).size != 9 # puts '--- City' - # b.spaces.select{ |s| s.city? }.each { |s| puts s.name } - raise "city sectors error" if b.spaces.select{ |s| s.city? }.size != 3 - [[0,11],[1,9],[2,9],[3,1]].each do |p,n| + # board.spaces.select{ |s| s.city? }.each { |s| puts s.name } + raise 'city sectors error' if board.spaces.select(&:city?).size != 3 + + [[0, 11], [1, 9], [2, 9], [3, 1]].each do |p, n| # puts "--- Population #{p}" - # b.spaces.select{ |s| s.pop==p }.each { |s| puts s.name } - raise "population #{p} error" if b.spaces.select{ |s| s.pop==p}.size != n + # board.spaces.select{ |s| s.pop==p }.each { |s| puts s.name } + raise "population #{p} error" if board.spaces.select { |s| s.pop == p }.size != n end - raise "sectors count wrong" if b.sectors.size != 28 + raise 'sectors count wrong' if board.sectors.size != 28 end - def check_forces what, b, v + def check_forces what, board, vals sup, opp, gov, fln = 0, 0, 0, 0 ft, fp, at, ap, g = 0, 0, 0, 0, 0 gb, fb = 0, 0 - b.spaces.each do |s| + board.spaces.each do |s| sup += 1 if s.alignment == :support opp += 1 if s.alignment == :oppose gov += 1 if s.control == :GOV fln += 1 if s.control == :FLN - ft += s.french_troops unless s.french_troops.nil? - fp += s.french_police unless s.french_police.nil? - at += s.algerian_troops unless s.algerian_troops.nil? - ap += s.algerian_police unless s.algerian_police.nil? + unless s.country? + ft += s.french_troops + fp += s.french_police + at += s.algerian_troops + ap += s.algerian_police + gb += s.gov_bases + end g += s.fln_underground - gb += s.gov_bases unless s.gov_bases.nil? fb += s.fln_bases end - raise "wrong support #{sup} != #{v[0]}" if sup != v[0] - raise "wrong oppose #{opp} != #{v[1]}" if opp != v[1] - raise "wrong GOV control #{gov} != #{v[2]}" if gov != v[2] - raise "wrong FLN control #{fln} != #{v[3]}" if fln != v[3] - raise "wrong french troops #{ft} != #{v[4]}" if ft != v[4] - raise "wrong french police #{fp} != #{v[5]}" if fp != v[5] - raise "wrong algerian troops #{at} != #{v[6]}" if at != v[6] - raise "wrong algerian police #{ap} != #{v[7]}" if ap != v[7] - raise "wrong Guerrillas #{g} != #{v[8]}" if g != v[8] - raise "wrong GOV bases #{gb} != #{v[9]}" if gb != v[9] - raise "wrong FLN bases #{fb} != #{v[10]}" if fb != v[10] + raise "wrong support #{sup} != #{vals[0]}" if sup != vals[0] + raise "wrong oppose #{opp} != #{vals[1]}" if opp != vals[1] + raise "wrong GOV control #{gov} != #{vals[2]}" if gov != vals[2] + raise "wrong FLN control #{fln} != #{vals[3]}" if fln != vals[3] + raise "wrong french troops #{ft} != #{vals[4]}" if ft != vals[4] + raise "wrong french police #{fp} != #{vals[5]}" if fp != vals[5] + raise "wrong algerian troops #{at} != #{vals[6]}" if at != vals[6] + raise "wrong algerian police #{ap} != #{vals[7]}" if ap != vals[7] + raise "wrong Guerrillas #{g} != #{vals[8]}" if g != vals[8] + raise "wrong GOV bases #{gb} != #{vals[9]}" if gb != vals[9] + raise "wrong FLN bases #{fb} != #{vals[10]}" if fb != vals[10] end b = ColonialTwilight::Board.new |