Я реализовал в Python алгоритм для решения игры "Minesweeper". Программа работает следующим образом:
Скажите, что решатель нажимает квадрат с именем 'a'. Для примера пусть число, показанное таким образом, равно 2. Соседи квадрата, которые еще не отброшены, являются (опять же в качестве примера) с именем "b" и "c". Затем программа связывает квадрат с выражением [2, {'b', 'c'}] и вырезает 'a' из всех других выражений. Вычисление тех квадратов, которые являются минами и которые не исчисляются путем простого упрощения таких выражений при двух обстоятельствах.
-
Если квадраты в одном выражении являются подмножеством квадратов другого выражения:
[2, {'a', 'b', 'c'}], [1, {'a', 'b'}] -> [1, {'c'}], [1, {'a', 'b'}]
-
Если все квадраты в одном выражении установлены как мины:
[2, {'a', 'b'}], [1, {'b', 'c'}] -> [2, {'a', 'b'}], [0, {'c'}]
Затем для некоторого выражения X
, если X[0] == 0
, мы можем щелкнуть все квадраты, названные в X[1]
, и если X[0] == len(X[1])
, тогда мы можем их обозначить.
Я, однако, изо всех сил пытаюсь определить, какие пары выражений пытаются упростить. Мой текущий подход состоит в том, чтобы поддерживать стек квадратов; всякий раз, когда щелкнут квадрат или его выражение успешно упрощено, оно добавляется в стек (если его еще нет). Когда квадрат выталкивается из стека, делается попытка упрощения между его выражением (X
) и любыми другими выражениями Y
такими, что X[1] & Y[1] != set()
. Алгоритм завершается, когда стек исчерпан. В настоящее время, однако, хотя это работает достаточно хорошо, оно не способно правильно решать все однозначные конфигурации и насколько хорошо оно выполняется на данной доске, значительно меняется, если я заменяю стек очередью или использую какой-то алгоритм, чтобы определить, какой квадрат для pop
Я был бы очень благодарен за любые примеры прецедента моего подхода или возможности потенциального исследования.