diff options
| author | Jérémy Zurcher <jeremy@asynk.ch> | 2023-10-24 13:18:51 +0200 | 
|---|---|---|
| committer | Jérémy Zurcher <jeremy@asynk.ch> | 2023-10-24 13:18:51 +0200 | 
| commit | 3011fbf0561570c0962e169a2d62d327edf19771 (patch) | |
| tree | a3ddadfb9f6c514535df672b64f9141961c776bd | |
| parent | 15298b7b3bc8facb1f350b7ab4ce9ec2fae50599 (diff) | |
| download | colonial-twilight-3011fbf0561570c0962e169a2d62d327edf19771.zip colonial-twilight-3011fbf0561570c0962e169a2d62d327edf19771.tar.gz  | |
FLNBotRules : add #place_guerrillas_in, fix rally_7
| -rw-r--r-- | lib/colonial_twilight/fln_bot_rules.rb | 40 | ||||
| -rw-r--r-- | spec/fln_bot_rules_spec.rb | 55 | ||||
| -rw-r--r-- | spec/mock_board.rb | 18 | 
3 files changed, 79 insertions, 34 deletions
diff --git a/lib/colonial_twilight/fln_bot_rules.rb b/lib/colonial_twilight/fln_bot_rules.rb index 1049b82..78f06ba 100644 --- a/lib/colonial_twilight/fln_bot_rules.rb +++ b/lib/colonial_twilight/fln_bot_rules.rb @@ -6,10 +6,11 @@ module ColonialTwilight      def dbg(msg, ret)        return if @debug.zero? -      case @debug -      when 1 then puts "  #{msg} : YES" if ret -      else puts "  #{msg} : #{ret ? 'YES' : 'NO'}" -      end +      s = case @debug +          when 1 then "  #{msg} : YES" if ret +          else "  #{msg} : #{ret ? 'YES' : 'NO'}" +          end +      puts s unless @debug == 666      end      def pass?(board = @board) @@ -119,13 +120,11 @@ module ColonialTwilight      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?) +      # highest population -> gain FLN control -> remove Gov control -> city -> least terror +      f = _max(spaces, :pop) +      f = _filter(f) { |s| s.gov < s.fln + place_guerrillas_in(s).values.sum } +      f = _filter(f) { |s| s.gov == s.fln + place_guerrillas_in(s).values.sum } +      f = _filter(f, &:city?)        _min(f, :terror).shuffle      end @@ -170,6 +169,17 @@ module ColonialTwilight        max_placable_guerrillas(space).clamp(0, space.fln_bases.positive? ? (space.pop + 1 - space.guerrillas) : 666)      end +    def place_guerrillas_in(space, board = @board) +      n = max_placable_guerrillas_in?(space) +      h = { space: 0 } # do not select space +      n -= h[:available] = (a = board.available_fln_underground) >= n ? n : a +      while n.positive? && !(spaces = remove_guerrillas_priority(board.spaces, h)).empty? +        s = spaces.sample +        n -= h[s] = (g = removable_guerrillas(s)) >= n ? n : g +      end +      h +    end +      # 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 @@ -189,14 +199,14 @@ module ColonialTwilight        n.positive? ? n : 0      end -    def not_selected(spaces, steps) -      spaces.reject { |s| steps.key?(s) } +    def not_selected(spaces, selected) +      spaces.reject { |s| selected.key?(s) }      end      # FLNBot#_place_fln_in -    def remove_guerrillas_priority(spaces, steps) +    def remove_guerrillas_priority(spaces, selected)        # 5) #removable_guerrillas then most guerrillas first -      return [] if (l = not_selected(spaces, steps).select { |s| removable_guerrillas(s).positive? }).empty? +      return [] if (l = not_selected(spaces, selected).select { |s| removable_guerrillas(s).positive? }).empty?        _max(l, :guerrillas).shuffle      end diff --git a/spec/fln_bot_rules_spec.rb b/spec/fln_bot_rules_spec.rb index a841b67..8667a11 100644 --- a/spec/fln_bot_rules_spec.rb +++ b/spec/fln_bot_rules_spec.rb @@ -9,7 +9,7 @@ class FLNRulesImpl    attr_writer :limited_op_only, :first_eligible, :will_be_next_first_eligible    def initialize -    @debug = 0 +    @debug = 666      @board = Board.new      @limited_op_only = true      @first_eligible = true @@ -305,31 +305,42 @@ describe ColonialTwilight::FLNBotRules do        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 +    it 'rally_7_priority population' do +      a = Sector.new({ pop: 2 }) +      b = Sector.new({ pop: 1 }) +      c = Sector.new({ pop: 1 }) +      expect(@rules.rally_7_priority([a, b, c])[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 +    it 'rally_7_priority gain FLN control' do +      a = Sector.new({ gov_cubes: 2 }) +      b = Sector.new({ gov_cubes: 1, fln_active: 1 }) +      c = Sector.new({ gov_cubes: 1 }) +      @board.available_fln_underground = 1 +      expect(@rules.rally_7_priority([a, b, c])[0]).to be b      end -    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 +    it 'rally_7_priority remove GOV control' do +      a = Sector.new({ gov_cubes: 3 }) +      b = Sector.new({ gov_cubes: 1 }) +      c = Sector.new({ gov_cubes: 2 }) +      @board.available_fln_underground = 1 +      expect(@rules.rally_7_priority([a, b, c])[0]).to be b      end -    it 'rally_7_priority population' do -      a = Sector.new({ pop: 2 }) -      b = Sector.new({ pop: 1 }) +    it 'rally_7_priority city?' do +      a = Sector.new({ name: 'city' }) +      b = Sector.new        expect(@rules.rally_7_priority([a, b])[0]).to be a      end +    it 'rally_7_priority 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([a, b, c])[0]).to be b +    end +      it 'may_rally_8_in? no fln guerrillas' do        a = Sector.new        expect(@rules.may_rally_8_in?(a)).to be false @@ -417,6 +428,16 @@ describe ColonialTwilight::FLNBotRules do        expect(@rules.max_placable_guerrillas_in?(a)).to eq(1)      end +    it 'place_guerrillas_in' do +      a = Sector.new({ pop: 2, fln_bases: 1 }) +      @board.available_fln_underground = 1 +      @board.spaces << Sector.new({ name: 'a', fln_bases: 1, fln_active: 2, fln_underground: 1 }) +      h = @rules.place_guerrillas_in(a) +      expect(@rules.max_placable_guerrillas_in?(a)).to eq(3) +      expect(h[:available]).to eq(1) +      expect(h[@board.spaces[0]]).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) diff --git a/spec/mock_board.rb b/spec/mock_board.rb index e75ba73..34c5272 100644 --- a/spec/mock_board.rb +++ b/spec/mock_board.rb @@ -57,19 +57,33 @@ class Sector      @data[:fln_underground] || 0    end +  def fln +    fln_active + fln_underground + fln_bases +  end +    def gov_cubes      @data[:gov_cubes] || 0    end + +  def gov_bases +    @data[:gov_bases] || 0 +  end + +  def gov +    gov_cubes + gov_bases +  end  end  class Board -  attr_reader :sector -  attr_accessor :fln_resources, :available_fln_bases +  attr_reader :sector, :spaces +  attr_accessor :fln_resources, :available_fln_underground, :available_fln_bases    def initialize      @fln_resources = 0      @available_fln_bases = 1 +    @available_fln_underground = 0      @sector = Sector.new +    @spaces = []    end    def has(&block)  | 
