Skip to content

Commit

Permalink
Adding ability to remove railroads.
Browse files Browse the repository at this point in the history
By marking a railroad row in the CSV with "removed", the railroad cannot
own private companies and cannot run routes. Only the railroads
designated as removable by the rules may be removed, although all 3 may
be removed.
  • Loading branch information
Austin committed Jun 25, 2019
1 parent c83f425 commit 891de95
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 7 deletions.
6 changes: 5 additions & 1 deletion bin/calc-route.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ def parse_args():
private_companies.load_from_csv(board, railroads, args.get("private_companies_file"))
board.validate()

best_routes = find_best_routes(board, railroads, railroads[args["active-railroad"]])
active_railroad = railroads[args["active-railroad"]]
if active_railroad.is_removed:
raise ValueError("Cannot calculate routes for a removed railroad: {}".format(active_railroad.name))

best_routes = find_best_routes(board, railroads, active_railroad)
print("RESULT")
for route in best_routes:
city_path = " -> ".join("{} [{}]".format(city.name, route.city_values[city]) for city in route.visited_cities)
Expand Down
6 changes: 6 additions & 0 deletions routes1846/board.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def place_chicago_station(self, railroad, exit_side):
chicago.add_station(railroad, exit_cell)

def place_seaport_token(self, coord, railroad):
if railroad.is_removed:
raise ValueError("A removed railroad cannot place Steamboat Company's token: {}".format(railroad.name))

current_cell = Cell.from_coord(coord)
for cell in board_cells():
space = self.get_space(cell)
Expand All @@ -68,6 +71,9 @@ def place_seaport_token(self, coord, railroad):
self.get_space(current_cell).place_seaport_token(railroad)

def place_meat_packing_token(self, coord, railroad):
if railroad.is_removed:
raise ValueError("A removed railroad cannot place Meat Packing Company's token: {}".format(railroad.name))

current_cell = Cell.from_coord(coord)
for cell in board_cells():
space = self.get_space(cell)
Expand Down
9 changes: 9 additions & 0 deletions routes1846/boardtile.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,27 @@ def __init__(self, name, cell, phase, paths, is_city=False, is_z=False, is_chica
self.is_terminal_city = is_terminal_city

def paths(self, enter_from=None, railroad=None):
if railroad and railroad.is_removed:
raise ValueError("A removed railroad cannot run routes: {}".format(railroad.name))

if enter_from:
return self._paths[enter_from]
else:
return tuple(self._paths.keys())

def place_seaport_token(self, railroad):
if railroad.is_removed:
raise ValueError("A removed railroad cannot place Steamboat Company's token: {}".format(railroad.name))

if self.port_value == 0:
raise ValueError("It is not legal to place the seaport token on this space ({}).".format(self.cell))

self.port_token = SeaportToken(self.cell, railroad)

def place_meat_packing_token(self, railroad):
if railroad.is_removed:
raise ValueError("A removed railroad cannot place Meat Packing Company's token: {}".format(railroad.name))

if self.meat_value == 0:
raise ValueError("It is not legal to place the meat packing token on this space ({}).".format(self.cell))

Expand Down
3 changes: 3 additions & 0 deletions routes1846/find_best_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,9 @@ def _detect_phase(railroads):
return max(all_train_phases) if all_train_phases else 1

def find_best_routes(board, railroads, active_railroad):
if active_railroad.is_removed:
raise ValueError("Cannot calculate routes for a removed railroad: {}".format(active_railroad.name))

LOG.info("Finding the best route for %s.", active_railroad.name)

routes = _find_all_routes(board, active_railroad)
Expand Down
9 changes: 9 additions & 0 deletions routes1846/placedtile.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,18 @@ def has_station(self, railroad_name):
return bool(self.get_station(railroad_name))

def place_seaport_token(self, railroad):
if railroad.is_removed:
raise ValueError("A removed railroad cannot place Steamboat Company's token: {}".format(railroad.name))

if self.port_value == 0:
raise ValueError("It is not legal to place the seaport token on this space ({}).".format(self.cell))

self.port_token = SeaportToken(self.cell, railroad)

def place_meat_packing_token(self, railroad):
if railroad.is_removed:
raise ValueError("A removed railroad cannot place Meat Packing Company's token: {}".format(railroad.name))

if self.meat_value == 0:
raise ValueError("It is not legal to place the meat packing token on this space ({}).".format(self.cell))

Expand All @@ -92,6 +98,9 @@ def meat_bonus(self, railroad, phase):
return self.meat_value if phase != 4 and self.meat_token and self.meat_token.railroad == railroad else 0

def paths(self, enter_from=None, railroad=None):
if railroad and railroad.is_removed:
raise ValueError("A removed railroad cannot run routes: {}".format(railroad.name))

if enter_from:
return self._paths[enter_from]
else:
Expand Down
6 changes: 5 additions & 1 deletion routes1846/private_companies.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,15 @@ def _handle_independent_railroad(board, railroads, name, kwargs):
if owner not in railroads:
raise ValueError("Assigned {} to an unrecognized or unfounded railroad: {}".format(name, owner))

owner_railroad = railroads[owner]
if owner_railroad.is_removed:
raise ValueError("Cannot assign {} to a removed railroad: {}".format(name, owner_railroad.name))

railroad_station_coords = [str(station.cell) for station in board.stations(owner)]
if home_city in railroad_station_coords:
return

board.place_station(home_city, railroads[owner])
board.place_station(home_city, owner_railroad)
else:
phase = max([train.phase for railroad in railroads.values() for train in railroad.trains])
if phase < 3:
Expand Down
43 changes: 41 additions & 2 deletions routes1846/railroads.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
"Pennsylvania": "F20"
}

REMOVABLE_RAILROADS = {
"Chesapeake & Ohio",
"Erie",
"Pennsylvania"
}

class Train(object):
@staticmethod
def create(train_str):
Expand Down Expand Up @@ -74,6 +80,27 @@ def __init__(self, name, trains):
def assign_mail_contract(self):
self.has_mail_contract = True

@property
def is_removed(self):
return False

class RemovedRailroad(Railroad):
@staticmethod
def create(name):
return RemovedRailroad(name)

def __init__(self, name):
super().__init__(name, [])

self.has_mail_contract = False

def assign_mail_contract(self):
raise ValueError("Cannot assign Mail Contract to a removed railroad: {}".format(self.name))

@property
def is_removed(self):
return True


def load_from_csv(board, railroads_filepath):
with open(railroads_filepath, newline='') as railroads_file:
Expand All @@ -82,7 +109,19 @@ def load_from_csv(board, railroads_filepath):
def load(board, railroads_rows):
railroads = {}
for railroad_args in railroads_rows:
railroad = Railroad.create(railroad_args["name"], railroad_args.get("trains"))
trains_str = railroad_args.get("trains")
if trains_str and trains_str.lower() == "removed":
name = railroad_args["name"]
if name not in REMOVABLE_RAILROADS:
raise ValueError("Attempted to remove a non-removable railroad.")

railroad = RemovedRailroad.create(name)
else:
railroad = Railroad.create(railroad_args["name"], trains_str)

if railroad.name in railroads:
raise ValueError(f"Found multiple {railroad.name} definitions.")

railroads[railroad.name] = railroad

if railroad.name not in RAILROAD_HOME_CITIES:
Expand All @@ -102,7 +141,7 @@ def load(board, railroads_rows):
chicago_station_exit_coord = str(railroad_args.get("chicago_station_exit_coord", "")).strip()
if not chicago_station_exit_coord:
raise ValueError("Chicago is listed as a station for {}, but not exit side was specified.".format(railroad.name))

board.place_chicago_station(railroad, int(chicago_station_exit_coord))

return railroads
3 changes: 3 additions & 0 deletions routes1846/route.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ def __str__(self):
return ", ".join([str(tile.cell) for tile in self])

def run(self, board, train, railroad, phase):
if railroad.is_removed:
raise ValueError("Cannot run routes for a removed railroad: {}".format(railroad.name))

visited_cities = self.value(board, train, railroad, phase)
return _RunRoute(self, visited_cities, train)

Expand Down
11 changes: 9 additions & 2 deletions routes1846/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ def __init__(self, cell, railroad):
class Station(Token):
pass

class SeaportToken(Token):
class PrivateCompanyToken(Token):
def __init__(self, cell, railroad):
if railroad.is_removed:
raise ValueError("A removed railroad cannot place a private company's token: {}".format(railroad.name))

super().__init__(cell, railroad)

class SeaportToken(PrivateCompanyToken):
pass

class MeatPackingToken(Token):
class MeatPackingToken(PrivateCompanyToken):
pass
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='routes-1846',
version='0.19',
version='0.20',
author="Austin Noto-Moniz",
author_email="metalnut4@netscape.net",
description="Library for caluclating routes in 1846: The Race For The Midwest.",
Expand Down

0 comments on commit 891de95

Please sign in to comment.