Skip to content

Commit

Permalink
[1822CA] compute small mail contracts with large, limit one contract …
Browse files Browse the repository at this point in the history
…per train

Fixes issue where a company could have one train but collect bonuses from both
the small and large mail contracts. #9376
  • Loading branch information
michaeljb committed Dec 30, 2023
1 parent 6d3f8c7 commit 26be1c7
Showing 1 changed file with 73 additions and 17 deletions.
90 changes: 73 additions & 17 deletions lib/engine/game/g_1822_ca/game.rb
Original file line number Diff line number Diff line change
Expand Up @@ -367,30 +367,86 @@ def sell_movement
@sell_movement ||= @players.size == 2 ? :left_share_pres : :left_per_10_if_pres_else_left_one
end

def routes_subsidy(routes)
super + small_mail_contract_subsidy(routes)
end

def upgrades_to_correct_label?(from, to)
super || (MOUNTAIN_PASS_HEXES.include?(from.hex&.id) && MOUNTAIN_PASS_TILES.include?(to.name))
end

def small_mail_contract_subsidy(routes)
return 0 if routes.empty?
def mail_contract_bonus(entity, routes)
mail_contracts = entity.companies.count { |c| self.class::PRIVATE_MAIL_CONTRACTS.include?(c.id) }
small_contracts = entity.companies.count { |c| self.class::PRIVATE_SMALL_MAIL_CONTRACTS.include?(c.id) }
all_contracts = mail_contracts + small_contracts
return [] unless all_contracts.positive?

mail_bonuses =
if mail_contracts.positive?
bonuses = routes.map do |r|
stops = r.visited_stops
next if stops.size < 2

entity = routes.first.train.owner
contract_count = entity.companies.count { |c| self.class::PRIVATE_SMALL_MAIL_CONTRACTS.include?(c.id) }
contract_count *
case @phase.name.to_i
when (3..4)
20
when (5..6)
30
when 7
40
first = stops.first.route_base_revenue(r.phase, r.train)
last = stops.last.route_base_revenue(r.phase, r.train)
{ route: r, subsidy: (first + last) / 2 }
end
bonuses.compact.sort_by { |v| -v[:subsidy] }.take(mail_contracts)
else
0
[]
end

small_bonuses =
if small_contracts.positive?
subsidy = small_mail_subsidy

routes.map do |r|
next if r.visited_stops.size < 2

{ route: r, subsidy: subsidy }
end.compact.take(small_contracts)
else
[]
end

if routes.size >= all_contracts || mail_bonuses.empty? || small_bonuses.empty?
mail_bonuses + small_bonuses
else
mail_index = 0
small_index = 0
routes.map do
mail = mail_bonuses[mail_index] || { subsidy: 0 }
small = small_bonuses[small_index] || { subsidy: 0 }
if small[:subsidy] > mail[:subsidy]
small_index += 1
small
else
mail_index += 1
mail
end
end
end
end

def small_mail_subsidy
case @phase.name.to_i
when (3..4)
20
when (5..6)
30
when 7
40
else
0
end
end

def train_help(entity, runnable_trains, _routes)
return [] if runnable_trains.empty?

help = super

if entity.companies.any? { |c| self.class::PRIVATE_SMALL_MAIL_CONTRACTS.include?(c.id) }
help << 'Small mail contract(s) gives a phase-based subsidy for one of the trains operated.'
end

help
end

def revenue_for(route, stops)
Expand Down

0 comments on commit 26be1c7

Please sign in to comment.