这是最后的效果
将win32连接运用起来,通过截取屏幕获取雷区分布,计算得出操作指令后调用鼠标完成扫雷
close
clear
clc
global gameover
global rect_in
global map
global blocks_x
global blocks_y
global block_width
global block_height
global left
global top
%% 扫雷游戏窗口
class_name = "TMain";
title_name = "Minesweeper Arbiter ";
rect = win.getWindowRect(class_name, title_name);
% 窗口坐标
left = rect(1);
top = rect(2);
right = rect(3) rect(1);
bottom = rect(4) rect(2);
if rect
disp("找到窗口")
disp("窗口坐标:")
disp([num2str(left) , ' ' , num2str(right) , ' ' ,...
num2str(top) , ' ' , num2str(bottom)])
else
disp("未找到窗口")
end
%% 锁定雷区坐标
left = left 15;
top = top 101;
right = right - 15;
bottom = bottom - 43;
% 抓取雷区图像
rect_in = [left, top, right-left, bottom-top];
img = win.screenCapture(rect_in);
% img = img/255;
% 每个方块16*16
block_width = 16;
block_height = 16;
% 横向有blocks_x个方块
blocks_x = floor((right - left) / block_width);
% 纵向有blocks_y个方块
blocks_y = floor((bottom - top) / block_height);
map = zeros(blocks_x,blocks_y);
% 是否游戏结束
gameover = 0;
%%
win.setMouse(left 5, top 5);
win.leftClick;
% 图像处理分析雷区
showmap();
% 扫描雷区图像
function showmap()
global gameover
global rect_in
global map
global blocks_x
global blocks_y
global block_width
global block_height
%%
img = win.screenCapture(rect_in);
for y=1:blocks_y
for x=1:blocks_x
block = [(x-1) * block_width 1, (y-1) * block_height 1, block_width-1, block_height-1];
this_image = imcrop(img,block);
%截取一个方块分析方块下的情况
map(x,y) = countColor(this_image);
if map(x,y)==9
gameover = 1;
break
end
end
end
% heatmap(map);
end
%直接粗暴地分析一个方块
function suit=countColor(rgb)
suit = 0;
% 数字1-8
% 0 未被打开
% -1 被打开 空白
% -4 红旗
goal = rgb;
image = imcrop(rgb,[3,3,11,11]);
if all(all(sum(abs(image-192),3)<eps))
if any(any(sum(abs(rgb-255),3)<eps))
suit = 0;%格子线和底色
return
else
suit = -1;没点开的方块有白色
return
end
end
goal(:,:,1)=0;
goal(:,:,2)=0;
goal(:,:,3)=255;
if any(any(sum(abs(rgb-goal),3)<eps))
suit = 1;%蓝色的1
return
end
goal(:,:,1)=0;
goal(:,:,2)=128;
goal(:,:,3)=0;
if any(any(sum(abs(rgb-goal),3)<eps))
suit = 2;%绿色的2
return
end
goal(:,:,1)=255;
goal(:,:,2)=0;
goal(:,:,3)=0;
if any(any(sum(abs(rgb-goal),3)<eps))
image = imcrop(rgb,[3,3,11,11]);
if any(any(sum(abs(image-255),3)<eps))
suit = 9;%雷
return
else
if any(any(sum(abs(rgb),3)<eps))
suit = -4;%红旗
return
else
suit = 3;%红色的3
return
end
end
end
goal(:,:,1)=0;
goal(:,:,2)=0;
goal(:,:,3)=128;
if any(any(sum(abs(rgb-goal),3)<eps))
suit = 4;%深蓝色4
return
end
goal(:,:,1)=128;
goal(:,:,2)=0;
goal(:,:,3)=0;
if any(any(sum(abs(rgb-goal),3)<eps))
suit = 5;%棕色的5
return
end
goal(:,:,1)=0;
goal(:,:,2)=128;
goal(:,:,3)=128;
if any(any(sum(abs(rgb-goal),3)<eps))
suit = 6;%青绿色的6
return
end
if any(any(sum(abs(rgb),3)<eps))
if any(any(sum(abs(rgb-255),3)<eps))
suit = 9;%还是雷
return
else
suit = 7;%黑色的7
return
end
end
if any(any(sum(abs(rgb-128),3)<eps))
image = imcrop(rgb,[3,3,11,11]);
if any(any(sum(abs(image-128),3)<eps))
suit = 8;%灰色的8
return
else
suit = 0;%没点过的方块
return
end
end
end