智力扫雷小游戏辅助工具
最近比较无聊又四处找题做,看到百度智力扫雷贴吧的小游戏很有意思(http://tieba.baidu.com/f?kw=%D6%C7%C1%A6%C9%A8%C0%D7&pn=50)于是编写了一个解决的工具。
简单说明:数字表示这一行或者这一列有多少空格,注意是空格。比如: 1 1 2表示这一行可能是如下形式
“空 雷 雷 空 雷 雷 空 空 雷 雷” 或者 “空 雷 雷 空 雷 雷 雷 雷 空 空” 但绝对不能是
“空 空 雷 雷 雷 雷 空 空 雷 雷” 。更多介绍请参考 http://tieba.baidu.com/f?kz=1071746700
本程序能够求解这个问题。
附件包括Source(源程序),Bin(编译结果),zhilisaoleixyx.swf本地版的游戏。
这个版本输入时,需要加入空格。
不足:
1.某些模式运算时间还是挺长的,比如下面这个:
横向的模式
5
1 2
2 2
1 1
2 5
8
1 1 1
1 4 1 1
1 3 3
2 1
垂直方向(就是上面的数字)
1 3
2 1 1
1 2 1 1
6
1 1 2
2 2 2
3 2
1 1 5
1 2 1
1 3
运算结果是有6种方案的
2.因为有多种方案存在的情况,所以还无法完全实现自动化,还需要手工点
可以改进的地方:
1.其实可以再化简一下数据结构的,现在的比较复杂,重复的也多
2.最好的入手地点应该是模式中对应的最少的序列的,比如,如果有 1 1 1 4这样的模式,将这个作为
第一行应该是最好的
下面是程序结构介绍
主要算法:
1.从第1行开始,生成一个满足i行的分布行k[i]
2.按照这个方法生成1 到 10行的分布图 k[1] k[2]...k[10]
3.上述分布图组成一个矩阵,再使用列的条件检查每一列
4.如果出现不满足的条件就回溯,
例如:我们需要 1 1 2模式,表示 1空格 炸弹*N1 1空格 炸弹*N2 2空格 炸弹*N3 的序列
生成的第一个序列即 [] X [] X [] [] X X X X ([]为空格,X为炸弹)
第二个序列即 [] X [] X X [][] X X X
最后一个序列 X X X X [] X [] X [][]
我们定义 0表示空格 [] , 1表示炸弹。上述,
生成的第一个序列即 0 1 0 1 0 0 1 1 1 1
第二个序列即 0 1 0 1 1 0 0 1 1 1
最后一个序列 1 1 1 1 0 1 0 1 0 0
模式的数据结构:
TMode=record
n:integer; //一共有多少空格
a:array[1..5] of integer; //各个模式
end;
序列的数据结构:
TSerial=record
b:integer; //序列对应的二进制
p:array[1..10] of integer; //具体序列值
end;
//对于给定的模式和一个目前的序列,生成下一个序列
function GenerateNext(m:TMode;s:Serial):TSerial;
//检查一个序列是否满足给定的模式
function TestSerial(m:TMode;s:TSerial):Boolean;
//生成满足模式的第一个序列
function GenerateFirst(m:TMode):TSerial;
//如果等待完全生成完再进行检测会出现运算量极大的问题,因此,设计一个提前
//检测的函数,相当于剪枝.表示当前已经填充了第l层,然后测试这样的填写方法是否合适
function preTest(l:integer):boolean;
一个完整的例子(来自http://tieba.baidu.com/f?z=1070492426&ct=335544320&lm=0&sc=0&rn=30&tn=baiduPostBrowser&word=%D6%C7%C1%A6%C9%A8%C0%D7&pn=30)
1 2 3 4 5 6 7 8 9 10
1 2 2 2 2
1 1 2 4 2 2 3 3 2
1 1 2 5 1 1 1 2 1 4
2 X X X X X X X X O O 1->10
1 1 1 4 O X O X O X O O O O
2 2 X O O X X X O O X X
1 2 X X X X O X X X O O
2 3 X X X O O X X O O O
2 6 O O X O O O O O O X
5 1 X X X O O O O O X O
2 1 X X O O X X X X X O
3 4 X X O O O X O O O O
1 1 1 X X X X X O X O X O
源程序和demo下载:http://www.lab-z.com/delphi/szminer.zip