summaryrefslogtreecommitdiffstats
path: root/lib/colonial_twilight/forces.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/colonial_twilight/forces.rb')
-rw-r--r--lib/colonial_twilight/forces.rb144
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/colonial_twilight/forces.rb b/lib/colonial_twilight/forces.rb
new file mode 100644
index 0000000..2048a00
--- /dev/null
+++ b/lib/colonial_twilight/forces.rb
@@ -0,0 +1,144 @@
+#! /usr/bin/env ruby
+# frozen_string_literal: true
+
+# rubocop:disable Style/AccessorGrouping
+# rubocop:disable Style/ParallelAssignment
+
+module ColonialTwilight
+ class Forces
+ attr_reader :name
+ attr_reader :algerian_troops, :algerian_police
+ attr_reader :french_troops, :french_police
+ attr_reader :fln_underground, :fln_active
+ attr_reader :fln_bases, :gov_bases
+ attr_reader :max_bases, :control
+
+ def initialize(sym)
+ @name = sym
+ @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
+ @max_bases = 2 if %i[Country Sector].include? sym
+ _variables_to_remove(sym)&.each do |s|
+ instance_variable_set(s, nil)
+ end
+ end
+
+ def init(data)
+ data.each { |k, v| add(k, v) }
+ end
+
+ private
+
+ def _variables_to_remove(sym)
+ case sym
+ 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]
+ when :City then nil
+ when :Sector then nil
+ end
+ end
+
+ public
+
+ def inspect
+ "GOV bases: #{gov_bases}
+ french troops: #{french_troops}
+ french police: #{french_police}
+ algerian troops: #{algerian_troops}
+ algerian police: #{algerian_police}
+ FLN bases: #{fln_bases}
+ underground Guerrillas: #{fln_underground}
+ active Guerrillas: #{fln_active}"
+ end
+ alias to_s inspect
+
+ def data
+ h = {}
+ %i[algerian_troops algerian_police french_troops french_police gov_bases
+ fln_underground fln_active fln_bases control].each do |sym|
+ h[sym] = send(sym) unless send(sym).nil?
+ end
+ h
+ end
+
+ def bases
+ (@gov_bases || 0) + (@fln_bases || 0)
+ end
+
+ def fln
+ fln_cubes + (@fln_bases || 0)
+ end
+
+ def fln_cubes
+ (@fln_underground || 0) + (@fln_active || 0)
+ end
+
+ def gov
+ gov_cubes + (@gov_bases || 0)
+ end
+
+ def gov_cubes
+ french_cubes + algerian_cubes
+ end
+
+ def french_cubes
+ (@french_troops || 0) + (@french_police || 0)
+ end
+
+ def algerian_cubes
+ (@algerian_troops || 0) + (@algerian_police || 0)
+ end
+
+ def troops
+ (@french_troops || 0) + (@algerian_troops || 0)
+ end
+
+ def police
+ (@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.nil? ? @fln_underground += num : @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 : #{type}"
+ end
+ update_control
+ end
+
+ private
+
+ 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 then :uncontrolled
+ when 1 then :GOV
+ when -1 then :FLN
+ end
+ )
+ end
+ end
+end