2012-10-28 14 views
12

私は、ゲーム「Minesweeper」を解決するためのアルゴリズムをPythonで実装しました。プログラムは次のように動作します。私の掃海艇の解決アルゴリズムを改善する

ソルバーが 'a'という名前の四角形をクリックしたとします。例のために、こうして明らかにされた数を2とする。未だにクリックされていない四角形の隣人は、(やはり一例として)「b」および「c」と名付けられている。次に、プログラムは、正方形を式[2、{'b'、 'c'}]に関連付け、他のすべての式から 'a'を取り除きます。どちらの四角形が鉱山であり、2つの状況下でそのような表現をペアごとに単純化することによって進められないものであるかの控除。

  • 一つの発現における四角は、他の発現の正方形のサブセットである場合:

    [2, {'a', 'b'}], [1, {'b', 'c'}] -> [2, {'a', 'b'}], [0, {'c'}] 
    
  • :一つの式中のすべての正方形が鉱山であることが確立されている場合

    [2, {'a', 'b', 'c'}], [1, {'a', 'b'}] -> [1, {'c'}], [1, {'a', 'b'}] 
    

Xの場合、X[0] == 0の場合、私たちは無料ですX[1]という名前のすべての四角形をickし、X[0] == len(X[1])ならば、それらのフラグを付けることができます。

しかし、を特定するのに苦労していますが、という表現のペアを簡素化しようとしています。私の現在のアプローチは、四角形のスタックを維持することです。正方形がクリックされるたびに、またはその式がうまく簡略化されるたびに、スタックに追加されます(まだ存在していない場合)。四角形がスタックからポップされると、その式(X)と他の式Yとの間で簡略化が試され、X[1] & Y[1] != set()となります。アルゴリズムは、スタックがなくなると終了します。しかし、現在のところ、これは非常にうまく機能しますが、明確な設定を正しく解決することはできません。また、スタックをキューに置き換えたり、アルゴリズムを使用してどのスクエアをポップするか!

私のアプローチの前例、または潜在的な探査の道のりに関して、私は非常に感謝しています。

+0

a、b、cは潜在的な鉱山や近隣の四角形を参照しています。 8人の隣人が、安全に何が危険なのかをゆっくりと吹き飛ばしますか? –

+0

式は、式が生成された時点(式が所属する四角形をクリックしたとき)にクリックされなかった各ネイバーへの参照で開始します(第2段落で説明)。 – user1502040

答えて

0

これは頭に浮かんだもので、私はあなたの方法が正確であることを完全に視覚化することができませんでした。
私はグラフィカルな形で私の提示がその努力を救うのに役立つことを願っています。

画像は「読み取り順」で処理されます。

私が未知のタイルに指定された値に加算し、それから一時値だ増している既知のタイルの数はさらに可能性を高めることができると、これを掲示以来行っている作業に合うように思われますリスクを正しくモデル化する
(この第1の方法と16(または8の一時値を使用して)、それはナンバーワン鉱山自体によって達成することができているように重要である)


私は早くこれを見ていないために少しブラインドを感じます。

値が100%に正規化されているものはすべて、鉱山を見つけることができます。

5

数年前、私は地雷探偵ソルバーを書いたが、悲しいかな、私はそのコードを紛失したようだ。私が覚えているのは、あなたがやっているようにパックされた組み合わせを残すのではなく、潜在的な鉱山のセットを集めた、ブルートフォースの方法だということです。

私はそれがあなたと働いているアルゴリズムがもう少し能力があったと信じています。あなたのアプローチは、完全に鉱山が満杯または空である場合、またはそれが別の条件のサブセットである場合、条件を "解決"することができます。しかし、これが処理できない控除がいくつかあります。

a 2 1 2 1 2 i 
b c d e f g h 

あなたの条件は次のようになります:たとえば、ah通じタイルは不明であるこの小さな7X2ボードを、考える私はそれを正しく理解している場合

[2, {a, b, c, d}], 
[1, {c, d, e}], 
[2, {d, e, f}], 
[1, {e, f, g}], 
[2, {f, g, h, i}] 

、あなたのアルゴリズムはできませんこれについて何らかの控除をする。

a 2 1 2 1 2 i 
b 2 * 2 * 2 h 

、まだいくつかの未知数あります鉱山を持つ:あなたが経験豊富なマインスイーパ選手ならしかし、あなたは中央に1 2 1パターンが1 s未満の鉱山を持つ唯一の単一のソリューションを持っていることを認識しますaまたはbの下にもう1つ、hまたはiのいずれかですが、これが大きなパズルの一部だった場合は、後でそれを理解することができます(または推測する必要があるかもしれません)。

私は鉱山のアプローチの私のセットは、このように働いたと考えている:拡張されている各タイルについて

、1つのそのすべての拡張されていない隣人(「地域」)のセット、およびすべてのセットを含むリストを収集その地域で発生する可能性のある鉱山。 (左から右へ)だから、例えば、例の5つの知られているタイルは、上記生成されます。

({a, b, c, d}, [{a, b}, {a, c}, {a, d}, {b, c}, {b, d}, {c, d}]) 
({c, d, e}, [{c}, {d}, {e}]) 
({d, e, f}, [{d, e}, {d, f}, {e, f}]) 
({e, f, g}, [{e}, {f}, {g}]) 
({f, g, h, i}, [{f, g}, {f, h}, {f, i}, {g, h}, {g, i}, {h, i}]) 

をとにかく、エリアセットを交差させ、私が最初に彼らが重複していることを確認したい二つの条件を組み合わせること。重複がない場合、条件を有効に組み合わせることはできません。

重複があった場合、新しい条件はその領域の和集合にまたがります。鉱山のセットについては、内側のセットのペアを取得するために外側のセットのデカルト積を行い、次に矛盾があるかどうかを確認します。矛盾は、エリアの交差点内で、2つのセットがまったく同じ鉱山を持たない場合です。矛盾がなければ、鉱山の組合から新しい組合が形成されるだろう。上記の最初の2つの行が結合する方法をここにあります:

Intersection of areas: {a, b, c, d} & {c, d, e} = {c, d} 
New combined area: {a, b, c, d} | {c, d, e} = {a, b, c, d, e} 
Cartesian product of mine sets (with X marking contradictions): 
    | {a, b} {a, c} {a, d} {b, c} {b, d} {c, d} 
---+------------------------------------------------- 
{c}|  X  {a, c} X  {b, c} X  X 
{d}|  X  X  {a, d} X  {b, d} X 
{e}| {a, b, e} X  X  X  X  X 

New condition: ({a, b, c, d, e}, [{a, b, e}, {a, c}, {b, c}, {a, d}, {b, d}]) 

あなたはどのように多くのセットに比べて、単にそれはの一部であり、どのように多くのセットのカウントすることにより、鉱山されている状態の領域内の任意のタイルのオッズを計算することができます合計があります。したがって、上記の組み合わせ条件を考えると、は時間の3分の1の時間であり、eは時間のわずか5分の1であることが分かります。この情報は、保証された安全なタイルがないときに展開する場所を推測する必要がある場合に重要です。私は、(私は3つの鉱山を2つではなく使用しているので、上記の{a、b、e}の場合は、他の場合と少し違って重み付けされるように)使用されている鉱山の数を考慮して、しかし、私は詳細を覚えていないのが怖いです。

Minesweeperはかなり挑戦的なゲームです。私は自分のプログラムが「ハード」の難しさに相当するボードを50〜60%の時間で解くことができたと信じていますが、ほとんどの損失は最初から(仕事のために少しの情報で推測しなければならない)終わり(推測する必要のある解決できない領域がしばしばある)。通常は非常に高速でしたが、次回の移動を行う前にタイルが10秒または15秒間停止するパターンがあることもありました。 (Minesweeper is NP-completeなので、一部の入力がすぐには解決できないことは驚くことではありません)。

関連する問題