def _get_split_city_stations(coord, tile_id, orientation): game = get_game(g.game_name) board = get_board(game) cell = board.cell(coord) if tile_id and orientation: split_city_space = placedtile.SplitCity.place(cell, game.tiles[tile_id], orientation) else: split_city_space = board.get_space(cell) split_city_station_coords = set() for branch in split_city_space.capacity.keys(): unique_exit_coords = [ branch_key for branch_key in branch if len(branch_key) == 1 ] if unique_exit_coords: # A unique exit coord is a sequence of length 1, so we need to extract it split_city_station_coords.add(str( sorted(unique_exit_coords)[0][0])) else: split_city_station_coords.add(str(sorted(branch)[0])) return split_city_station_coords
def _get_board_layout_info(): board = get_board(g.game_name) board_layout = get_board_layout(g.game_name) first_coord = str(min(list(board.cells))) row, col = first_coord[0], int(first_coord[1:]) board_layout.update({ # Determine the parity of the first row's columns. 0 for even, 1 for odd. # If the first cell's row is not A, adjust the parity to what it would be # if it was A. "parity": (col + (0 if ord(row) % 2 == 1 else 1)) % 2, # Convert the max row, expressed as a letter, into an int. "max-row": ord(board_layout["max-row"].lower()) - 97 }) return board_layout
def legal_tile_coords(): LOG.info("Legal tile coordinates request.") current_coord = request.args.get("coord") existing_tile_coords = { coord for coord in json.loads(request.args.get("tile_coords")) if coord } legal_tile_coordinates = set(get_tile_coords(get_board( g.game_name))) - existing_tile_coords if current_coord: legal_tile_coordinates.add(current_coord) LOG.info(f"Legal tile coordinates response: {legal_tile_coordinates}") return jsonify({"tile-coords": list(sorted(legal_tile_coordinates))})
def cities(): LOG.info("Cities request.") board = get_board(g.game_name) # all_cities = [str(cell) for cell in sorted(board.cells) if board.get_space(cell) and board.get_space(cell).is_city] all_cities = [] split_cities = [] for cell in sorted(board.cells): space = board.get_space(cell) if space and space.is_city: coord = str(cell) all_cities.append(coord) if isinstance(space, (boardtile.SplitCity, placedtile.SplitCity)): split_cities.append(coord) LOG.info(f"Cities response: {all_cities}") return jsonify({"cities": all_cities, "split-cities": split_cities})
def _legal_tile_ids_by_coord(game, coord): board = get_board(game) space = board.get_space(board.cell(coord)) # If the coord is a built-in upgrade level 4 tile if space and space.upgrade_level is None: return [] legal_tile_ids = [] for tile in game.tiles.values(): if not space: if tile.is_stop: continue elif tile.upgrade_level <= space.upgrade_level: continue elif space.is_city != tile.is_city or space.is_town != tile.is_town or tile.upgrade_attrs not in space.upgrade_attrs: continue legal_orientations, _ = _get_orientations(game, coord, tile.id) if legal_orientations: legal_tile_ids.append(tile.id) return legal_tile_ids
def main(): migration_data = migrate.process_migrate_data() game = get_game(g.game_name) board = get_board(game) stop_names = {} for cell in board.cells: space = board.get_space(cell) if space and space.is_stop: stop_names[str(cell)] = space.nickname termini_boundaries = { name: info["boundaries"] for name, info in get_termini_boundaries(game).items() } private_companies = game.get_game_submodule("private_companies") private_company_names = private_companies.COMPANIES.keys( ) if private_companies else [] private_company_column_names = [ PRIVATE_COMPANY_COLUMN_MAP[colname] for colname in private_companies.FIELDNAMES ] if private_companies else [] return render_template( "index.html", private_company_default_token_coords=private_companies. PRIVATE_COMPANY_DEFAULT_COORDS if private_companies else {}, private_company_rownames=private_company_names, placed_tiles_colnames=PLACED_TILES_COLUMN_NAMES, tile_coords=get_tile_coords(board), stop_names=stop_names, termini_boundaries=termini_boundaries, removable_railroads=_get_removable_railroads(), closable_railroads=_get_closable_railroads(game), board_layout=_get_board_layout_info(), migration_data=migration_data)
def _get_orientations(game, coord, tile_id): if not coord or not tile_id: return None, None board = get_board(game) try: cell = board.cell(coord) except ValueError: return None, None tile = game.tiles.get(tile_id) if not tile: return None, None all_paths = {} orientations = [] translations = {} for orientation in range(0, 6): try: board._validate_place_tile_neighbors(cell, tile, orientation) board._validate_place_tile_upgrade(board.get_space(cell), cell, tile, orientation) except ValueError: continue tile_paths = tuple( sorted((key, tuple(sorted(val))) for key, val in placedtile.PlacedTile.get_paths( cell, tile, orientation).items())) if tile_paths in all_paths: translations[orientation] = all_paths[tile_paths] continue orientations.append(orientation) all_paths[tile_paths] = orientation return orientations, translations
def board_space_info(): coord = request.args["coord"].strip() tile_id = request.args.get("tileId", "").strip() orientation = request.args.get("orientation", "").strip() phase = request.args.get("phase") game = get_game(g.game_name) board = get_board(game) railroad_info = get_railroad_info(game) cell = board.cell(coord) station_offsets = get_station_offsets(game) if tile_id and orientation: offset_data = station_offsets.get("tile", {}) offset = _get_station_offset(offset_data, tile_id) space = placedtile.PlacedTile.place(cell, game.tiles[tile_id], orientation, board.get_space(cell)) if isinstance(space, placedtile.SplitCity): # In the offset file, branches are indicated by side. To translate # into cells, add the orientation, and modulo by 6 to retrieve its # neighbor given the orientation. offset = { str(cell.neighbors[(int(exit) + int(orientation)) % 6]): offsetCoords for exit, offsetCoords in offset.items() } if "rotation" in offset: offset["rotation"] = math.radians(offset["rotation"]) else: offset_data = station_offsets.get("board", {}) offset = _get_station_offset(offset_data, coord) space = board.get_space(cell) if "rotation" in offset: offset["rotation"] = math.radians(offset["rotation"]) if hasattr(space, "capacity"): # Stop-gap. I need to figure out what to actually do with capacity keys. capacity = sum(space.capacity.values()) if isinstance( space.capacity, dict) else space.capacity else: capacity = 0 home = [ railroad for railroad, info_dict in railroad_info.items() if info_dict.get("home") == coord ] if not phase or (game.rules.stations_reserved_until and game.compare_phases( game.rules.stations_reserved_until, phase) < 0): reserved = [ railroad for railroad, info_dict in railroad_info.items() if coord in info_dict.get("reserved", []) ] else: reserved = [] info = { "capacity": capacity, "offset": offset, "phase": getattr(space, "upgrade_level", 0), "is-split-city": isinstance(space, (boardtile.SplitCity, placedtile.SplitCity)), "home-to": home, "reserved-for": reserved } return jsonify({"info": info})