正好是个周末,想着这两日玩长生劫的八宝盒实在是麻烦,就算有了网上的辅助工具 (http://www.cockleshell.org/static/TheLongevitySeal/treasure.html),还是觉得很蛋疼,遂用按键精灵写了一个自动解盒的脚本,基本算法就是广度优先算法,其实就是在所有的可能性里找寻答案。弄完用了两小时之后,国家队全到手了,然后便弃置一边,想想实在可惜,还是网上分享一下吧,希望能帮到有缘人。基本上你得懂一些编程知识,然后一些javascript就行了。我电脑分辨率是 1920*1080的来着。
演示视频
我这里装的东西有,
蓝叠模拟器(运行游戏用)
按键精灵(运行模拟按键算法)
nodejs(运行解题算法)
都是能百度下载啦,这里就不详细写了。
按键精灵代码:
Dim startx
Dim starty
Dim map(5, 5)
Dim flexible
flexible = 0.7
For i = 0 To 5
For j = 0 To 5
map(i,j) = 0
Next
Next
//这里是八宝盒左上角的坐标点
startx = 71
starty = 232
//这是八宝盒的基本块大小
block_size = 66
block_num = 1
//识别八宝盒中的木条,这里用的是按键精灵的图片搜索功能,还不错,自己截图放到脚本附件里即可
For i = 0 To 5
For j = 0 To 5
If map(i, j) = 0 Then
TracePrint i & "," & j
TracePrint startx + j * block_size & "," & starty + i * block_size & "," & startx + block_size + j * block_size & "," & starty + block_size + i * block_size
//识别纵向长木条
FindPic startx+j*block_size,starty+i*block_size,startx+block_size+j*block_size,starty+block_size+i*block_size,"Attachment:\column-long.bmp",flexible,intX,intY
If intX > 0 And intY > 0 Then
TracePrint i & "," & j & ",Found"
map(i, j) = block_num
map(i+1, j) = block_num
map(i + 2, j) = block_num
Goto continue
End If
//识别横向长木条
FindPic startx+j*block_size,starty+i*block_size,startx+block_size+j*block_size,starty+block_size+i*block_size,"Attachment:\row-long.bmp",flexible,intX,intY
If intX > 0 And intY > 0 Then
TracePrint i&","&j& ",Found"
map(i, j) = block_num
map(i, j+1) = block_num
map(i, j + 2) = block_num
Goto continue
End If
//识别纵向短木条
FindPic startx+j*block_size,starty+i*block_size,startx+block_size+j*block_size,starty+block_size+i*block_size,"Attachment:\column-short.bmp",flexible,intX,intY
If intX > 0 And intY > 0 Then
TracePrint i&","&j& ",Found"
map(i, j) = block_num
map(i + 1, j) = block_num
Goto continue
End If
//识别横向短木条
FindPic startx+j*block_size,starty+i*block_size,startx+block_size+j*block_size,starty+block_size+i*block_size,"Attachment:\row-short.bmp",flexible,intX,intY
If intX > 0 And intY > 0 Then
TracePrint i&","&j& ",Found"
map(i, j) = block_num
map(i, j + 1) = block_num
Goto continue
End If
//识别目标木条
FindPic startx+j*block_size,starty+i*block_size,startx+block_size+j*block_size,starty+block_size+i*block_size,"Attachment:\target.bmp",flexible,intX,intY
If intX > 0 And intY > 0 Then
TracePrint i&","&j& ",Found"
map(i, j) = 99
map(i + 1, j) = 99
Goto continue
End If
End If
Rem continue
block_num = block_num + 1
Next
Next
//这里主要是跟其他程序通信所以写一个文件,主要还是按键精灵跟其他程序通信没啥好方法,
//所以用文件的方式传递数据,可以自行替换路径,但记住下面读取文件的路径也要一同替换
TracePrint "script start"
Set fso = CreateObject("Scripting.FileSystemObject")
Set puzzle = fso.CreateTextFile("c:\Users\Administrator\Desktop\puzzle.txt", True)
For i = 0 To 5
For j = 0 To 5
puzzle.Write map(i, j) & ","
Next
Next
puzzle.Close
//因为懒,所以核心解题的方法是用javascript写的,解完题后会在桌面生成一个 solve.txt,命令前者为nodejs 的程序地址,后者为解题脚本地址
RunApp "C:\Program Files\nodejs\node.exe C:\Users\Administrator\Desktop\test.js"
//这里也是因为懒,哈哈,其实合适的办法应该是用轮询的方法查看node 的解题答案文件生成没,
Delay 4000
//好了回到这里就是就行八宝盒操作啦,读取解题数据,然后操作就行了
Set solve = fso.OpenTextFile("c:\Users\Administrator\Desktop\solve.txt", 1)
solve_content = solve.ReadLine
solve_array = Split(solve_content,",")
TracePrint UBound(solve_array)
For i = 0 To (UBound(solve_array)+1)/4 -1
TracePrint solve_array(i * 4) & solve_array(i * 4 + 1) & solve_array(i * 4 + 2) & solve_array(i * 4 + 3)
MoveTo startx + solve_array(i * 4) * block_size + block_size/2, starty + solve_array(i * 4 + 1) * block_size + block_size/2
LeftDown 1
Delay 300
MoveTo startx + solve_array(i * 4) * block_size + block_size/2 + solve_array(i * 4 + 2)*block_size, starty + solve_array(i * 4 + 1) * block_size + block_size/2+ solve_array(i * 4 + 3)*block_size
LeftUp 1
Delay 300
Next
//就是最后那两下,把目标块拉出来的操作,然而不稳定,自己改进吧
MoveTo startx + 3 * block_size + block_size/2, starty + 5 * block_size + block_size/2
LeftDown 1
Delay 300
MoveTo startx + 3 * block_size + block_size/2, starty + 7 * block_size + block_size/2
LeftUp 1
Delay 300
MoveTo 130,698
LeftDown 1
Delay 600
MoveTo 230, 696
Delay 600
MoveTo 340, 696
Delay 600
MoveTo 452,696
LeftUp 1
Delay 600
solve.Close
TracePrint "script end"
这是我这边弄得识别木条的特征图片,自己截图放进去就好
核心解题方法:
var fs = require("fs");
//Not happy with Plain JS? Use JS/HTML/CSS option for using your own librari
var data = fs.readFileSync('c:\\Users\\Administrator\\Desktop\\puzzle.txt', 'utf8');
array_one_dim = data.split(",");
var puzzle = [];
for (var i = 0; i<6; i++){
puzzle[i] = [];
for (var j = 0; j<6; j++){
puzzle[i][j] = parseInt(array_one_dim[i*6+j]);
}
}
console.log(puzzle);
// var array = [
// [0,0,0,0,0,0],
// [0,0,0,99,0,0],
// [0,0,0,99,0,0],
// [0,0,0,0,0,0],
// [0,0,0,0,0,0],
// [0,0,0,0,0,0]];
log_array(puzzle);
console.log("Start");
function log_array(array){
array.forEach(function (index,element) {
console.log(index+":"+element.toString());
});
}
// find_leaf(array).forEach(function (ele) {
// log_array(ele);
// });
seeds = [puzzle];
history_seeds = {};
history_seeds[JSON.stringify(puzzle)] = null;
var final_result;
while(seeds.length != 0){
var succeed = 0;
next_seeds = [];
seeds.forEach(function (seed) {
aleaves = find_leaf(seed).leaves;
aleaves_movements = find_leaf(seed).leaf_movements;
aleaves.forEach(function (leaf, index) {
if (!(JSON.stringify(leaf) in history_seeds)){
history_seeds[JSON.stringify(leaf)] = {parent:JSON.stringify(seed), movement:aleaves_movements[index]};
//当目标木条到达出口时,停止算法,并输出
if (leaf[4][3]===99 && leaf[5][3]===99) {
final_result = JSON.stringify(leaf);
succeed = 1;
}
next_seeds.push(leaf);
}
});
});
if (succeed === 1) break;
seeds = next_seeds;
}
before_step = history_seeds[final_result];
right_steps = [];
while(before_step !== null && typeof before_step !== 'undefined'){
right_steps.unshift(before_step.movement);
before_step = history_seeds[before_step.parent];
}
fs.writeFile('c:\\Users\\Administrator\\Desktop\\solve.txt', right_steps, 'utf8', function(err){
if(err){
console.log('写入文件失败');
}else{
console.log('保存成功');
}
})
function find_leaf(seed){
leaves_movements = [];
leaves = [];
//down
for(i=0;i<6;i++)
for(j=0;j<6;j++)
{
if ( seed[i][j]!=0 && i!= 0 && i<5 && seed[i-1][j]==seed[i][j] && seed[i+1][j]==0){
child_seed= JSON.parse(JSON.stringify(seed));
child_seed[i+1][j] = seed[i][j];
i>1 && seed[i-2][j]==seed[i][j]?child_seed[i-2][j]=0:child_seed[i-1][j]=0;
// console.log("...................");
// log_array(child_seed);
leaves.push(child_seed);
leaves_movements.push([j,i,0,1]);
}
}
//right
for(i=0;i<6;i++)
for(j=0;j<6;j++)
{
if (seed[i][j]!=0 && j!= 0 && j<5 && seed[i][j-1]==seed[i][j] && seed[i][j+1]==0){
child_seed= JSON.parse(JSON.stringify(seed));
child_seed[i][j+1] = seed[i][j];
j>1&&seed[i][j-2]==seed[i][j]?child_seed[i][j-2]=0:child_seed[i][j-1]=0;
// console.log("...................");
// log_array(child_seed);
leaves.push(child_seed);
leaves_movements.push([j,i,1,0]);
}
}
//up
for(i=5;i>=0;i--)
for(j=5;j>=0;j--)
{
if (seed[i][j]!=0 && i!= 5 && i>0 && seed[i+1][j]==seed[i][j] && seed[i-1][j]==0){
child_seed= JSON.parse(JSON.stringify(seed));
child_seed[i-1][j] = seed[i][j];
i<4&&seed[i+2][j]==seed[i][j]?child_seed[i+2][j]=0:child_seed[i+1][j]=0;
// console.log("...................");
// log_array(child_seed);
leaves.push(child_seed);
leaves_movements.push([j,i,0,-1]);
}
}
//left
for(i=5;i>=0;i--)
for(j=5;j>=0;j--)
{
if (seed[i][j]!=0 && j!= 5 && j>0 && seed[i][j+1]==seed[i][j] && seed[i][j-1]==0){
child_seed= JSON.parse(JSON.stringify(seed));
child_seed[i][j-1] = seed[i][j];
j<4&&seed[i][j+2]==seed[i][j]?child_seed[i][j+2]=0:child_seed[i][j+1]=0;
// console.log("...................");
// log_array(child_seed);
leaves.push(child_seed);
leaves_movements.push([j,i,-1,0]);
}
}
return {"leaves":leaves, "leaf_movements":leaves_movements};
}
如果使用过程中遇到问题,可以联系我哦,当然我不一定随时在线。。。