扫雷求解器


34

我们已经生成了扫雷场,但是在PCG炸毁之前,确实有人必须清除这些生成的地雷!

您的任务是写一个Minesweeper解算器,该解算器与“ Working Minesweeper”的公认解决方案的稍作修改的版本兼容(动作之间用空格隔开,以允许更大的字段)。

输入:扫雷字段,字段之间用空格分隔。第一行表示地雷总数。

  • x:不变
  • !:标志
  • 数字:该区域周围的地雷数量

例:

10
0 0 1 x x x x x
0 0 2 x x x x x
0 0 2 ! x x x x
0 0 1 2 x x x x
0 0 0 1 x x x x
1 1 0 2 x x x x
x 1 0 2 x x x x
1 1 0 1 x x x x

输出:格式为您的下一步action row column(从零开始)

有效动作:

  • 0: 打开它
  • 1:放置标志

例:

0 1 2

规则:

  • 您编写了一个完整的程序,该程序将单个字段作为输入(STDIN或命令行参数)并输出单个操作(STDOUT)。因此,除之外,您无法保存状态!
  • 您的选择必须遵循最大的生存几率。(即,如果有100%安全的举动,请采取)
  • 这是;最短的解决方案(以UTF-8字节为单位)获胜

测试:

这些测试用于测试常见的清晰情况;您的程序必须适用于每个测试领域。

在:

4
x x x x
1 2 x x
0 1 2 x
0 0 1 x

出(以下任何一项):

1 1 2
0 0 2
0 1 3

在:

2
x x x
1 ! x
1 1 x

出(以下任何一项):

0 0 0
0 0 1
0 1 2
0 2 2
1 0 2

在:

10
x x x x x x x x
1 3 3 x x x x x
0 1 ! 3 3 4 x x
0 2 3 ! 2 3 x x
0 1 ! 2 2 ! x x

出(以下任何一项):

1 1 5
1 0 2

在:

2
x x x
2 3 1
! 1 0

出(以下任何一项):

0 0 1
1 0 0
1 0 2

真好!1)也许为了进行测试,某人应该编写一个测试工具:给定一个字段,它会打印出所采取的每个步骤以及该程序是否获胜。该程序应在地图上毫无歧义地获胜。2)我想知道是否有人会使用标志动作。似乎永远都没有必要。
Claudiu 2014年

对于第一次测试。为什么您可以搬到0 0 20 1 3。我看不到其中任何一个怎么被认为是安全的。(我不能在扫雷机上做得不够好...)
FDinoff 2014年

1
可能F还是P比较好看的标志不是!:)
VISION

1
@JonathanVanMatre该字段是空白的,但可以保证您的第一个空缺不是地雷,因为第一次单击后就放置了地雷:)
TimWolla 2014年

2
有趣的事实:只有有限数量的主板可用(至少在XP版本中,这是竞争激烈的典范)。当您单击第一个点时,木板会四处移动,以确保您没有单击地雷,但除此之外,它已经决定了要使用哪个木板。
Undergroundmonorail

Answers:


17

Mathematica

还是不打高尔夫球。需要更多有关I / O格式的工作。

t = {{0, 0, 1, x, x, x, x, x}, {0, 0, 2, x, x, x, x, x}, {0, 0, 2, F, x, x, x, x}, 
     {0, 0, 1, 2, x, x, x, x}, {0, 0, 0, 1, x, x, x, x}, {1, 1, 0, 2, x, x, x, x}, 
     {x, 1, 0, 2, x, x, x, x}, {1, 1, 0, 1, x, x, x, x}};
(*Sqrt[2] is  1.5*)
c = Sequence; p = Position;
nums = p[t, _?NumberQ];
fx = Nearest[p[t, x]];
flagMinus[flag_] := If[Norm[# - flag] < 1.5, t[[c @@ #]]--] & /@ nums
flagMinus /@ p[t, F];
g@x_List := Tr[q[#] & /@ x]
eqs = MapIndexed[t[[c @@ (nums[[#2]][[1]])]] == g[#1] &, (fx[#, {8, 1.5}] & /@nums)];
vars = Union@Cases[eqs, _q, 4];
s = Solve[Join[eqs, Thread[0 <= vars < 2]], vars, Integers];
res = (Transpose@s)[[All, All, 2]];
i = 1; plays = Select[{i++, #[[1]], Equal @@ #} & /@ res, #[[3]] &];
Flatten /@ ({#[[2]] /. 1 -> F, List @@ vars[[#[[1]]]] - 1} & /@ plays)

(*
{{0, 0, 3}, {F, 1, 3}, {F, 2, 4}, {0, 3, 4}, {0, 4, 4}, 
 {F, 5, 4}, {F, 6, 0}, {F, 6, 4}, {0, 7, 4}}
*)

编辑:奖金轨道

我建立了一个交互式游乐场,通过计算给定配置的所有可能解决方案来计算炸弹概率:

Mathematica图形

未安装Mathematica的测试说明:

  1. 下载http://pastebin.com/asLC47BW并将其另存为* .CDF
  2. 从Wolfram Research在https://www.wolfram.com/cdf-player/下载免费的CDF环境 (不是小文件)

滑块更改电路板尺寸。这只是一个粗略的程序,未经充分测试,请报告所有错误。我尚未实现“机上可用炸弹总数”功能。假定是无限的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.