私はTickettoRideを楽しんでいるので、サイドプログラミングプロジェクトとしてPythonでゲームロジックの一部を実装することを試してみることにしました。ゲームボードは基本的に加重マルチグラフであるため、NetworkXを使用してゲームの基本構造を複製するのは簡単でした。
私が問題を抱えているのは、プレイヤーが所有している列車カードの在庫を考慮して、ボードを通る特定のパスが可能かどうかを分析することです。プログラミングの問題というよりは数学の問題だと思います。おそらく力ずくの方法で物事を理解することができますが、もっと効率的な方法があるはずだと思いました。
ゲームを知らない人のために:いつでも、各プレイヤーは8色のいずれかの列車カードの数に加えて、ワイルドカードとして機能する特別な「機関車」カテゴリを持っています。これらの色は、セグメント内のすべての車が同じ色である限り、任意の色を使用できる灰色の線を除いて、ゲームボード(ここに表示)の列車の線の色に対応しています。(トンネルやフェリーが関係するエッジケースがありますが、今はそれらを脇に置いておきます。)
現在のコードを使用すると、特定の2つの都市間のすべてのパスを見つけて、パスに灰色のセグメントが含まれていない限り、その特定のパスをたどるのに必要な各色の列車カードの数を取得できます。灰色以外のセグメントはより単純なので、最初に実行します。パス内の各赤/緑/青のセグメントに十分な赤/緑/青のカードがあるか、ないかのどちらかです。グレーの場合、各セグメントに使用する色を選択できるため、少し複雑になります。
灰色のセグメントが1つしかないパスの場合でも、それは簡単です。1つの色のカードが十分にあるかどうかにかかわらず、それを埋めることができます。ただし、複数の灰色のセグメントがあると、最初のセグメントに選択された色によって2番目または3番目のセグメントを完成させることが不可能になる状況に遭遇する可能性があります。
例として、プレーヤーのカードの在庫が赤4、緑2、青3であり、彼がパリからウィーンに行くことができるかどうかを調べようとしているとします。ボードを見ると、このカードの組み合わせで可能な唯一のルートは、パリ-(3グレー)->チューリッヒ-(2グリーン)->ウィーン-(2グレー)-に行くことであることがわかります。 >チューリッヒ-(2グレー)->ウィーン。これを理解するための私のアルゴリズムは、緑のセグメントから始まり、そこに2枚の緑のカードを割り当てます。次に、残りの4枚の赤と3枚の青のカードを使用して、長さ3、2、および2の灰色のセグメントをカバーする方法を決定する必要があります。
もちろん、答えは、パリとチューリッヒの間で3枚の青いカードを使用し、ヴェネツィアからザグラード、ザグラードからウィーンまでそれぞれ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
(「重量」は、鉄道車両のセグメントの長さです。)
ここには本当に些細な解決策が潜んでいて、指を置くことができないような気がします。何か案は?