扫雷就像在Haskell中生成的板 - 想法

时间:2015-05-15 22:53:43

标签: haskell

首先,我想描述一个问题(它与Minesweeper非常相似)。我们给出了一个 n × m 板和一个特殊点列表( x y ž)。每个点都表示围绕字段( x y ),我们需要准确放置 z 地雷。

您还可以在此找到更好的问题描述:Prolog: where to begin solving Minesweeper-like puzzel? (它在prolog中,但不关心编程语言)

我们的任务是生成满足任务条件的所有可能的板。 例如: 让n = 3m = 3L = [(2,2,1)]列为特殊点,因此可能的解决方案是:

[[' ', ' ', ' '], [' ', 1, ' '], [' ', ' ', *]]

其中''是空格,'*'是我的。

我想在Haskell中找到一些有用的想法来编写这个问题。我唯一的想法是生成所有可能的设置地雷组合或使用回溯,但我发现很难在haskell中实现。

任何想法怎么做?

1 个答案:

答案 0 :(得分:5)

使用list monad在Haskell中回溯非常简单。这是一个例子:

import Control.Monad (guard)

pairs :: [(Int,Int)]
pairs = do
    x <- [1..10]
    y <- [1..x]
    guard (even (x + y))
    return (x,y)

将为您提供所有(x,y)对,y <= xx + y为偶数。

所以你会想要像

这样的东西
type Board = ...

insertMine :: (Int,Int) -> Board -> [Board]
-- return all ways of inserting a mine adjacent to the given coordinate

insertMines :: (Int,Int) -> Board -> [Board]
insertMines p board = do
    b1 <- insertMine p board
    b2 <- insertMine p b1
    b3 <- insertMine p b2
    return b3

有很多方法可以使这更简单,更抽象,但我试图在我认为是你的水平附近举一个例子。通过列表monad回溯是一个很好的方式来适应monad!