Мне нравится играть Ticket to Ride, поэтому я решил поиграть с реализацией частей игровой логики в Python в качестве побочного проекта программирования. Игровая доска - это, по сути, взвешенный мультиграф, поэтому репликация базовой структуры игры с NetworkX была сундуком.«Билет для езды» логика игровой логики для серых маршрутов
В одной части, с которой я столкнулся, анализируется, возможен ли конкретный путь через доску, учитывая инвентарь карт поезда, которыми обладает игрок. I думаю, это скорее математическая проблема, чем проблема программирования как таковая, и я могу, вероятно, объединить метод грубой силы для выяснения вещей, но думал, что должен быть более эффективный способ.
Для тех, кто не знает игры: в любой момент каждый игрок имеет несколько карт поезда в одном из восьми цветов, а также специальную категорию «локомотив», которая служит в качестве дикой карты. Эти цвета соответствуют цвету линий поезда на игровой доске (shown here), за исключением серых линий, где вы можете использовать любой цвет, если все автомобили в сегменте одного цвета. (Есть крайние случаи, связанные с туннелями и паромами, но мы оставим их в стороне на данный момент.)
С кодом, который сейчас находится, я могу найти все пути между двумя городами и получить обратно, сколько карт поезда каждый цвет необходим, чтобы принять этот конкретный путь, если только пути не связаны с серыми сегментами. Сначала я делаю несезонные сегменты, так как они более понятны - либо у вас достаточно красных/зеленых/синих карт для каждого красного/зеленого/синего сегмента на пути, иначе вы этого не сделаете. С серой, потому что вы можете выбрать любой цвет, который будет использоваться для каждого сегмента, он становится немного более привлекательным.
Для путей с одним серым сегментом все еще легко - либо у вас достаточно карт любого цвета, чтобы заполнить его, либо нет. Однако с несколькими сегментами серого можно столкнуться с ситуациями, когда цвет, выбранный для первого сегмента, делает невозможным завершение второго или третьего сегмента.
В качестве примера предположим, что инвентарь карты игрока 4 красных, 2 зеленых, 3 синих, и мы пытаемся выяснить, может ли он добраться из Парижа в Вену. Глядя на доску, довольно легко увидеть, что единственный возможный маршрут для этой комбинации карт - поездка в Париж - (3 серый) -> Цюрих - (2 зеленый) -> Венеция - (2 серый) - > Заград - (2 серый) -> Вена. Мой алгоритм для определения этого начинается с зеленого сегмента и выделяет две зеленые карты. Затем необходимо решить, как использовать оставшиеся 4 красные и 3 синие карты для покрытия серых сегментов длин 3, 2 и 2.
Ответ, конечно же, заключается в использовании трех синих карточек между Парижем и Цюрих и две красные карточки для Венеции в Заграде и Заграде в Вену. Но как написать обобщенный алгоритм, который решает эту проблему для менее очевидных случаев, связанных с большим количеством цветов и большим количеством сегментов?
Мой код это прямо сейчас выглядит следующим образом:
def can_afford(path, cards):
grays = list()
for segment in path:
if segment.color == 'Gray':
grays.append(segment)
else:
if cards.get(segment.color, 0) >= segment.weight:
cards[segment.color] -= segment.weight
else:
return False
for gray in grays:
# Halp!
pass
return True
(. «Вес» длина сегмента в вагонах)
Я чувствую, что есть на самом деле тривиальное решение скрываясь в здесь, на который я просто не могу положиться. Есть идеи?
[cs.se] может понравиться это. – AakashM
Вы намеренно игнорируете locamotives (wild cards)? – chepner
Да, на данный момент я за то, что хотел, чтобы серые маршруты разобрались, чтобы сохранить проблему проще. – tonycpsu