扫雷求解器是我解决扫雷游戏专家级问题的解决方案(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/minesweeper-solver-is-my-solution-to-solving-the-e-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 7 分钟阅读 - 3456 个词 阅读量 0扫雷求解器是我解决扫雷游戏专家级问题的解决方案(译文)
原文地址:https://www.codeproject.com/Articles/19200/Minesweeper-Solver-is-My-Solution-to-Solving-the-E
原文作者:kubben
译文由本站 robot-v1.0 翻译
前言
I had trouble solving the expert Minesweeper level, so I wrote a program to do it for me.
我在解决专家级扫雷方面遇到了麻烦,因此我编写了一个程序为我做.
介绍(Introduction)
您玩过扫雷游戏吗?几周前我才开始玩.我发现初学者和中级水平不太难,但是专家水平确实很痛苦.因此,我决定编写一个可以为我解决<扫雷>游戏的应用.(Have you ever played the Minesweeper game? I didn’t start playing until a few weeks ago. I found the beginner and intermediate levels not too difficult, but the expert level was a real pain. So I decided to write an app that would solve the Minesweeper game for me.)
背景(Background)
在玩扫雷游戏时,我发现在专家级别上我经常犯一些愚蠢的错误.通常,在找到40或50个地雷之后,我会精神疲倦,将某物标记为炸弹,或者单击某个炸弹.无论如何,我发现很难掌握最后的炸弹.然后,当我最终能够到达那里时,我总是不得不猜测.所以我想我会写一个程序来为我解决<扫雷>游戏,至少不会犯同样的错误.(While playing the Minesweeper game, I found on the expert level I was often making silly mistakes. Usually after finding 40 or 50 mines I would get mentally tired and mark something as a bomb or click somewhere that was a bomb. Anyway, I found it really difficult to get down to the last few bombs. Then when I finally would be able to get there, I would always have to guess. So I figured I would write a program that could solve the Minesweeper game for me and at least it wouldn’t make the same mistakes I was making.)
游戏(The Game)
如果您从未玩过<扫雷>游戏,这里有一个快速的介绍.根据您所处的级别,您会有一定数量的正方形.目标是找到所有地雷并将其标记为地雷,而无需单击任何一个.开始游戏时,您不知道地雷在哪里,因此您随机左键单击几个方块.单击时,您开始看到数字.数字与地雷的数量有关,地雷在八个接触面均围绕着地雷.当您认为自己知道地雷在哪里时,请右键单击以将其标记为地雷.您尝试尽快找到所有地雷.游戏是定时的,因此您尝试获得最好的时间,以便进入最佳时间列表.(If you have never played the Minesweeper game, here is a quick intro to it. Depending on the level you are on, you have a certain number of squares. The goal is to find all the mines and mark them as mines without clicking on one. When you start the game you have no idea where the mines are, so you randomly left click a few squares. As you click you start to see numbers. The numbers relate to the number of mines that surround the number on the eight touching sides. When you think you know where a mine is you right click to flag it as a mine. You try to find all the mines as quickly as possible. The game is timed so you try to get the best time you can to get on the best times list.)
问题(The Problem)
作为一个人,当我感到疲倦或没有给予足够的关注时,我会犯一些愚蠢的错误.我只是无法超越专家水平.因此,我写了一个可以为我解决该问题的程序,而不是玩越来越多的扫雷游戏.(Being a human, I make silly mistakes when I get tired or just don’t pay close enough attention. I just could not beat the expert level. So instead of playing more and more of the Minesweeper game, I wrote a program that could solve it for me.)
解决方案(The Solution)
首先,我想指出的是,我用这两篇文章来帮助解决程序的Windows消息传递和屏幕打印部分.(First I would like to note that I used these two articles to help out with the Windows messaging and screen print part of the program.)
- 将输入消息发送到其他Windows或如何通过编程技巧赢得Flash游戏(Sending Input Messages to Other Windows or How To Win a Flash Game By Your Programming Skills) 通过(by) 米哈尔`雷米(Michal Remi)(Michal Remi) .(.)
- 一篇非常有用的文章:(And a really helpful article:) 带有Spy ++样式的"窗口查找器"的屏幕捕获,窗口捕获和窗口图标捕获!(Screen Captures, Window Captures and Window Icon Captures with Spy++ style Window Finder!) 通过(by) 马克(Code6)美女(Mark (Code6) Belles)
首先,我确保Minesweeper程序正在运行.然后,我得到程序的句柄并将其推到最前面,并将其放在屏幕的左上角.这很重要,因此我对需要将鼠标单击发送到哪里有了一个想法.基于"扫雷"游戏的屏幕宽度,我假设用户正在玩哪个级别.接下来,我使用"扫雷"游戏的屏幕截图找出我找到了哪些盒子.我使用在框中找到的颜色来帮助我确定单击了哪个数字,等等.接下来,我编写了一些代码来帮助我确定当前要查看的当前方框中所有周围的方框.然后我将所有这些信息传递给(First I make sure the Minesweeper program is running. Then I get the handle to the program and force it to the forefront and put it in the upper left hand corner of the screen. This is important so I have an idea of where I need to be sending mouse clicks. Base off the screen width of the Minesweeper game I make an assumption on which level the user is playing at. Next I use the screen print of the Minesweeper game to figure out which boxes I have found. I use the colors found in the boxes to help me figure out which number I have clicked, etc. Next I wrote some code to help me figure out what all the surrounding boxes are to the current box I am looking at. Then I pass all this info into)
TheBrain
方法.我惊讶地发现大脑方法最终变得如此简单:(method. I was surprised to find how simple the brain method ended up being:)
private Boolean TheBrain(SquareType currPos, SquareType top,
SquareType topRight, SquareType right, SquareType bottomRight,
SquareType bottom, SquareType bottomLeft, SquareType left,
SquareType topLeft, int x, int y)
{
Boolean ret = true;
int bombCnt = GetCounts(SquareType.Bomb,top,topRight,right,
bottomRight,bottom,bottomLeft,left,topLeft);
int unKnownsCnt = GetCounts(SquareType.Unknown, top, topRight,
right, bottomRight, bottom, bottomLeft, left, topLeft);
if (unKnownsCnt == 0)
{
TheSquaresPos[x, y].Complete = true;
return ret;
}
int maxBombs = 0;
String errorNumber = String.Empty;
switch (currPos)
{
case SquareType.One :
maxBombs = 1;
errorNumber = "One";
break;
case SquareType.Two :
maxBombs = 2;
errorNumber = "Two";
break;
case SquareType.Three :
maxBombs = 3;
errorNumber = "Three";
break;
case SquareType.Four :
maxBombs = 4;
errorNumber = "Four";
break;
case SquareType.Five :
maxBombs = 5;
errorNumber = "Five";
break;
case SquareType.Six :
maxBombs = 6;
errorNumber = "Six";
break;
case SquareType.Seven :
maxBombs = 7;
errorNumber = "Seven";
break;
} //switch
if (bombCnt == maxBombs)
{
//Any Unknowns should be checked
ProcessUnknowns(top, topRight, right, bottomRight, bottom,
bottomLeft, left, topLeft, x, y);
}
else if (maxBombs >= 7 && bombCnt == 7 && unKnownsCnt == (maxBombs - 7))
{
RightClickUnknowns(top, topRight, right, bottomRight, bottom,
bottomLeft, left, topLeft, x, y);
}
else if (maxBombs >= 6 && bombCnt == 6 && unKnownsCnt == (maxBombs - 6))
{
RightClickUnknowns(top, topRight, right, bottomRight, bottom,
bottomLeft, left, topLeft, x, y);
}
else if (maxBombs >= 5 && bombCnt == 5 && unKnownsCnt == (maxBombs - 5))
{
RightClickUnknowns(top, topRight, right, bottomRight, bottom,
bottomLeft, left, topLeft, x, y);
}
else if (maxBombs >= 4 && bombCnt == 4 && unKnownsCnt == (maxBombs - 4))
{
RightClickUnknowns(top, topRight, right, bottomRight, bottom,
bottomLeft, left, topLeft, x, y);
}
else if (maxBombs >= 3 && bombCnt == 3 && unKnownsCnt == (maxBombs - 3))
{
RightClickUnknowns(top, topRight, right, bottomRight, bottom,
bottomLeft, left, topLeft, x, y);
}
else if (maxBombs >= 2 && bombCnt == 2 && unKnownsCnt == (maxBombs -2))
{
RightClickUnknowns(top, topRight, right, bottomRight, bottom,
bottomLeft, left, topLeft, x, y);
}
else if (bombCnt == 1 && unKnownsCnt == (maxBombs - 1))
{
RightClickUnknowns(top, topRight, right, bottomRight, bottom,
bottomLeft, left, topLeft, x, y);
}
else if (bombCnt == 0 && unKnownsCnt == maxBombs)
{
RightClickUnknowns(top, topRight, right, bottomRight, bottom,
bottomLeft, left, topLeft, x, y);
}
else if (bombCnt > maxBombs)
{
toolStripStatusLabel1.Text = "Error on "+errorNumber+" processing too many bombs!";
ret = false;
}
return ret;
}
一旦大脑方法决定了应该做什么,我要么发送鼠标右键,要么发送鼠标左键.当开始游戏或程序陷入困境时,我会随机选择下一个要单击的框.(Once the brain method made a decision on what should be done, I would either send right mouse clicks or left mouse clicks. When starting a game or when the program would get stuck, I would randomly pick the next box to click.)
扫雷求解器的最佳时光(The Best Times from Minesweeper Solver)
注意(Note)这些时间是合法的.那是程序解决游戏所花费的时间.我发现了一些有趣的事情,这些事情确实加速了该程序解决游戏所花费的时间.首先,Minesweeper解算器拥有的RAM内存和CPU越多,运行速度越快.其次,我停止读取正方形中的所有像素.我开始只阅读其中一半.第三,我开始在第一遍从左到右扫描板,然后在第二遍从右到左扫描板.我扫描木板的方式的这种切换也有助于解决游戏的速度.(these times are legitimate. That is how long it took the program to solve the game. I found some interesting things that really sped up the time that it took the program to solve the game. First it appears the more RAM memory and CPU the Minesweeper solver has, the faster it will run. Second, I stopped reading all the pixels in the squares. I started to read only half of them. Third, I started to scan the board left to right on the first pass and then right to left on the second pass. This switching of the way I was scanning the board also helped with the speed in which the game could be solved.)
一些奇事(Some Odds and Ends)
我发现有些计算机和显示器会为相同的颜色选择略有不同的颜色.所以我最终将它们放入(I found that some computers and monitors would pick slightly different colors for the same colors. So I ended up putting those into the)**app.config(app.config)**文件,以便可以轻松更改它们.我还发现屏幕分辨率可能会影响盒子的起始位置.因此,当尝试在PC上运行此程序时,您可能需要调整(file so they can be easily changed. I also found that screen resolution could affect the starting position of boxes. So when trying to get this to run on your PC, you might need to tweak the)**app.config(app.config)**文件值才可以工作.我有一个选中1按钮,它将选中网格中的框.您可以使用它来确定是否需要修改(file values a little before it will work. I have a check 1 button that will check on box in the grid. You can use this to figure out if you need to modify the)**app.config(app.config)**价值观.(values.)
已知的问题(Known Issues)
由于某种原因,扫雷求解器程序会将炸弹标记两次,然后将其切换为问号.当应用程序随机选择一个正方形进行点击时,它是随机的,可以在其中编程一些智能.(For some reason, the Minesweeper solver program will mark a bomb twice which switches that square to a question mark. When the app randomly picks a square to click it is random, some intelligence could be programmed into it.)
结论(Conclusion)
我花了一些时间,尽管只花了两天时间来编写此代码的核心.但这仍然是一个有趣的练习,并帮助我提高了编程技能.我发现Minesweeper解算器几乎每次都可以解决初学者水平.它将有时解决中间级别.你猜到了.它也有专家级的麻烦.一百次尝试可能会解决专家水平.(I had some time on my hands, although it only took me two days to write the core of this code. Still it was a fun exercise and helped me improve my programming skills. I found that the Minesweeper solver would solve the beginner level almost every time. It would solve the intermediate level some of the time. You guessed it. It had trouble with the expert level as well. It might solve the expert level once in a hundred tries.)
历史(History)
- 15(15)日(th)2007年6月:初始职位(June, 2007: Initial post)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# C#2.0 Windows .NET .NET2.0 Visual-Studio VS2005 Dev 新闻 翻译