Skip to content

Commit

Permalink
Merge pull request tobymao#10254 from roseundy/moon_more_post_playtes…
Browse files Browse the repository at this point in the history
…t_fixes

21Moon: rules updates
  • Loading branch information
michaeljb authored Feb 3, 2024
2 parents 8616efb + 7455518 commit 126f241
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 10,095 deletions.
2 changes: 1 addition & 1 deletion lib/engine/game/g_21_moon/entities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ module Entities
max_price: 60,
desc: 'The corporation owning the SBC can build and upgrade road tiles crossing the rift. '\
'The owning company receives a bonus of 60 credits after the connection across the rift is '\
'made for the first time. Can be sold to a corporation for ₡1-₡60.',
'made and the SBC will close. Can be sold to a corporation for ₡1-₡60.',
abilities: [],
color: nil,
},
Expand Down
44 changes: 33 additions & 11 deletions lib/engine/game/g_21_moon/game.rb
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,6 @@ def setup
'SE' => END_BONUS_COUNT,
'SW' => END_BONUS_COUNT,
}
@crossed_rift = false
@sp_tiles = SP_TILES.map { |tn| @tiles.find { |t| t.name == tn } }

update_bonus_locations
Expand Down Expand Up @@ -396,11 +395,10 @@ def ols_start(player)
ols_minor = minor_by_id('OLS')
ols_minor.owner = player

@log << "#{player.name} must choose city for OLS token"
@round.pending_tokens << {
@log << "#{player.name} must place tile for OLS"
@round.pending_tracks << {
entity: ols_minor,
hexes: MINERAL_HEXES.map { |h| hex_by_id(h) },
token: ols_minor.find_token_by_type,
}
@round.clear_cache!
end
Expand Down Expand Up @@ -447,12 +445,13 @@ def remove_from_depot(name, corp)
end

def crossing_border(entity, _tile)
raise GameError, 'Cannot cross Rift' unless entity.companies.find { |c| c.sym == 'SBC' }
return if @crossed_rift
sbc = entity.companies.find { |c| c.sym == 'SBC' }
raise GameError, 'Cannot cross Rift' unless sbc

@log << "#{entity.name} earns #{format_currency(self.class::RIFT_BONUS)} for crossing Rift"
@bank.spend(self.class::RIFT_BONUS, entity)
@crossed_rift = true
sbc.close!
@log << "#{sbc.name} closes"
end

def tile_valid_for_phase?(tile, hex: nil, phase_color_cache: nil)
Expand All @@ -463,7 +462,7 @@ def tile_valid_for_phase?(tile, hex: nil, phase_color_cache: nil)
end

def upgrades_to?(from, to, special = false, selected_company: nil)
return false if to.name == T_TILE && !selected_company
return false if to.name == T_TILE && !selected_company && block_terminal_hex?

# not needed for laying tiles, but keeps the tiles tab from lying to the player
return false if X_RESTRICTED_UPGRADES.key?(from.name) && !X_RESTRICTED_UPGRADES[from.name].include?(to.name)
Expand All @@ -484,6 +483,7 @@ def upgrades_to_correct_color?(from, to, selected_company: nil)

def new_auction_round
Engine::Round::Auction.new(self, [
G21Moon::Step::OLSTrack,
G21Moon::Step::OLSToken,
G21Moon::Step::WaterfallAuction,
])
Expand Down Expand Up @@ -640,14 +640,22 @@ def operated_operators
@corporations.select(&:operated?)
end

def east_stop?(stops)
stops.find { |stop| (stop.groups.include?('E0') || stop.groups.include?('E1')) }
end

def west_stop?(stops)
stops.find { |stop| (stop.groups.include?('W0') || stop.groups.include?('W1')) }
end

def check_distance(route, visits, train = nil)
train ||= route.train
distance = train.distance

route_distance = visits.sum(&:visit_cost)

# Getting terminal bonus also allow visiting one additional stop
east = visits.find { |stop| stop.groups.include?('E') }
east = east_stop?(visits)
terminal = visits.find { |stop| stop.hex.id == T_HEX }
route_distance -= 1 if east && terminal

Expand All @@ -657,8 +665,8 @@ def check_distance(route, visits, train = nil)
def route_bonus(stops)
bonus = { revenue: 0 }

east = stops.find { |stop| stop.groups.include?('E') }
west = stops.find { |stop| stop.groups.include?('W') }
east = east_stop?(stops)
west = west_stop?(stops)
terminal = stops.find { |stop| stop.hex.id == T_HEX }

if east && west
Expand Down Expand Up @@ -1096,6 +1104,20 @@ def share_flags(shares)
step = @round.active_step
step.share_flags(shares) if step.respond_to?(:share_flags)
end

def legal_tile_rotation?(entity, hex, tile)
return true if entity.corporation? && entity.companies.find { |c| c.sym == 'SBC' }

tile.exits.none? { |edge| hex.tile.borders.any? { |border| border.edge == edge } }
end

def terminal_company
@terminal_company ||= @companies.find { |c| c.sym == 'T' }
end

def block_terminal_hex?
!terminal_company.closed?
end
end
end
end
Expand Down
22 changes: 11 additions & 11 deletions lib/engine/game/g_21_moon/map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,19 +306,19 @@ module Map
%w[E5 G13] => 'city=revenue:0;city=revenue:0;upgrade=cost:20,terrain:mountain;label=OO',
},
purple: {
%w[B2] => 'offboard=revenue:20,groups:W;path=a:0,b:_0',
%w[A3] => 'offboard=revenue:20,groups:W;path=a:5,b:_0',
%w[A5] => 'offboard=revenue:20,groups:W;path=a:0,b:_0;path=a:4,b:_0;path=a:5,b:_0',
%w[B14] => 'offboard=revenue:20,groups:W;path=a:4,b:_0',
%w[C15] => 'offboard=revenue:20,groups:W;path=a:3,b:_0;path=a:4,b:_0',
%w[B2] => 'offboard=revenue:20,groups:W0;path=a:0,b:_0',
%w[A3] => 'offboard=revenue:20,groups:W0;path=a:5,b:_0',
%w[A5] => 'offboard=revenue:20,groups:W0;path=a:0,b:_0;path=a:4,b:_0;path=a:5,b:_0',
%w[B14] => 'offboard=revenue:20,groups:W1;path=a:4,b:_0',
%w[C15] => 'offboard=revenue:20,groups:W1;path=a:3,b:_0;path=a:4,b:_0',
},
orange: {
%w[K1] => 'offboard=revenue:20,groups:E;path=a:0,b:_0',
%w[L2] => 'offboard=revenue:20,groups:E;path=a:1,b:_0',
%w[L4] => 'offboard=revenue:20,groups:E;path=a:2,b:_0',
%w[M11] => 'offboard=revenue:20,groups:E;path=a:1,b:_0',
%w[M13] => 'offboard=revenue:20,groups:E;path=a:2,b:_0',
%w[L14] => 'offboard=revenue:20,groups:E;path=a:2,b:_0;path=a:3,b:_0',
%w[K1] => 'offboard=revenue:20,groups:E0;path=a:0,b:_0',
%w[L2] => 'offboard=revenue:20,groups:E0;path=a:1,b:_0',
%w[L4] => 'offboard=revenue:20,groups:E0;path=a:2,b:_0',
%w[M11] => 'offboard=revenue:20,groups:E1;path=a:1,b:_0',
%w[M13] => 'offboard=revenue:20,groups:E1;path=a:2,b:_0',
%w[L14] => 'offboard=revenue:20,groups:E1;path=a:2,b:_0;path=a:3,b:_0',
},
}.freeze
# rubocop:enable Layout/LineLength
Expand Down
134 changes: 134 additions & 0 deletions lib/engine/game/g_21_moon/step/ols_track.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# frozen_string_literal: true

require_relative '../../../step/base'
require_relative '../../../step/tracker'

module Engine
module Game
module G21Moon
module Step
class OLSTrack < Engine::Step::Base
include Engine::Step::Tracker
ACTIONS = %w[lay_tile].freeze

def actions(entity)
return [] unless entity == pending_entity

ACTIONS
end

def visible?
true
end

def players_visible?
true
end

def available
[]
end

def show_map
true
end

def active_entities
[pending_entity]
end

def round_state
super.merge(
{
pending_tracks: [],
}
)
end

def active?
pending_entity
end

def current_entity
pending_entity
end

def pending_entity
pending_track[:entity]
end

def pending_track
@round.pending_tracks&.first || {}
end

def description
'Lay OLS track'
end

def process_pass(action)
log_pass(action.entity)
@round.pending_tracks.shift
pass!
end

def get_tile_lay(_entity)
{ lay: true, upgrade: true, cost: 0, upgrade_cost: 0, cannot_reuse_same_hex: false }
end

def update_tile_lists(tile, old_tile)
old_tile.icons.dup.each do |old_icon|
old_tile.icons.delete(old_icon)
new_icon = @game.update_icon(old_icon, tile)
tile.icons << new_icon if new_icon
end
super
end

def process_lay_tile(action)
ols_minor = pending_entity
ols_hex = action.hex
ols_tile = action.tile
@round.num_laid_track = 0
lay_tile_action(action)
@round.pending_tracks.shift

ols_token = ols_minor.find_token_by_type
if ols_tile.cities.one?
@log << "OLS places a token on #{ols_hex.name}"
city = ols_tile.cities.first
city.place_token(ols_minor, ols_token)
else
@log << "#{ols_minor.owner.name} must choose city for OLS token"
@round.pending_tokens << {
entity: ols_minor,
hexes: [ols_hex],
token: ols_token,
}
@round.clear_cache!
end
end

def reachable_node?(_entity, _node)
true
end

def reachable_hex?(_entity, _hex)
true
end

def available_hex(_entity, hex)
pending_track[:hexes].include?(hex)
end

def hex_neighbors(_entity, hex)
edges = {}
hex.neighbors.each { |e, _| edges[e] = true }
edges.keys
end

def pay_tile_cost!(_entity_or_entities, _tile, _rotation, _hex, _spender, _cost, _extra_cost); end
end
end
end
end
end
4 changes: 2 additions & 2 deletions lib/engine/game/g_21_moon/step/track.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def check_border_crossing(entity, tile)

@game.crossing_border(entity, tile) # check and potentially pay bonus

# remove border
# remove borders
tile.borders.delete(border)
neighbor.tile.borders.map! { |nb| nb.edge == hex.invert(edge) ? nil : nb }.compact!
end
Expand All @@ -124,7 +124,7 @@ def check_border_crossing(entity, tile)
def tracker_available_hex(entity, hex)
connected = hex_neighbors(entity, hex)
return nil unless connected
return nil if hex.id == @game.class::T_HEX
return nil if hex.id == @game.class::T_HEX && @game.block_terminal_hex?

tile_lay = get_tile_lay(entity)
return nil unless tile_lay
Expand Down
Loading

0 comments on commit 126f241

Please sign in to comment.