扫雷的程序

扫雷的程序,第1张

普通版本WINDOS扫雷程序是将布雷和扫雷结合
扫雷程序思想讲解
在我大二的时候就编写了一个扫雷程序,现在也有很多
源程序下载,我不知道他们的算法是怎么样的,但我想我的
算法应是最清晰和简单的。下面就来讲解我的扫雷程序思想。
首先我们在雷区上随机地放上雷,没有雷的地方被点击
后就会显示一个数字表示它周围有几个雷,这是怎么实现的
呢?我们可以把整个雷区看成一个二维数组a[i,j],如雷区:

11 12 13 14 15 16 17 18
21 22 23 24 25 26 27 28
31 32 33 34 35 36 37 38
41 42 43 44 45 46 47 48
51 52 53 54 55 56 57 58

我要知道a[34]周围有几个雷,就只有去检测
a[23],a[24],a[25]
a[33], a[35]
a[43],a[44],a[45]
这8个雷区是否放上了雷,仔细观察它们成在数学关系。
抽象出来就是:a[i,j]的雷的个数就是由
a[i-1,j-1],a[i-1,j],a[i-1,j+1]
a[ i ,j-1], a[ i ,j+1]
a[i+1,j-1],a[i+1,j],a[i+1,j+1]
(如果超出边界再加以判断)
这样的8个雷区决定的。
扫雷程序还会自动展开已确定没有雷的雷区。如果
a[3,4]周围雷数为1,a[2,3]已被标示为地雷,那么
a[24],a[25],a[33],a[35],a[43],a[44],a[45]
将被展开,一直波及到不可确定的雷区。这也是实现的
关键。我们可以把数组的元素设定为一个类对象,它们
所属的类
因此普通版本WINDOS扫雷程序是将布雷和扫雷结合的

import javaxswingImageIcon; //程序入口
public class Block {
String name; //名字,比如"雷"或数字
int aroundMineNumber; //周围雷的数目
ImageIcon mineIcon; //雷的图标
boolean isMine=false; //是否是雷
boolean isMark=false; //是否被标记
boolean isOpen=false; //是否被挖开
public void setName(String name) {
thisname=name;
}
//设置周围的雷数
public void setAroundMineNumber(int n) {
aroundMineNumber=n;
}
//获得周围的雷数
public int getAroundMineNumber() {
return aroundMineNumber;
}

public String getName() {
return name;
}
//判断是否是雷
public boolean isMine() {
return isMine;
}
//设置是否为雷
public void setIsMine(boolean b) {
isMine=b;
}
//设置雷的图标
public void setMineIcon(ImageIcon icon){
mineIcon=icon;
}
//获得雷的图标
public ImageIcon getMineicon(){
return mineIcon;
}
//确定雷是否被挖开
public boolean getIsOpen() {
return isOpen;
}
//设置为已经被挖开
public void setIsOpen(boolean p) {
isOpen=p;
}
//返回此处是否已经被标记
public boolean getIsMark() {
return isMark;
}
//设置此处是否已经被标记
public void setIsMark(boolean m) {
isMark=m;
}
import javaxswing;
import javaawt;
public class BlockView extends JPanel{
JLabel blockNameOrIcon; //用来显示Block对象的name、number和mineIcon属性
JButton blockCover; //用来遮挡blockNameOrIcon
CardLayout card; //卡片式布局
BlockView(){
card=new CardLayout();
setLayout(card);
blockNameOrIcon=new JLabel("",JLabelCENTER);
blockNameOrIconsetHorizontalTextPosition(AbstractButtonCENTER);
blockNameOrIconsetVerticalTextPosition(AbstractButtonCENTER);
blockCover=new JButton();
add("cover",blockCover);
add("view",blockNameOrIcon);
}
//给出视觉效果变化
public void giveView(Block block){
// 如果是雷,将对应的图标和文字更改
if(blockisMine){
blockNameOrIconsetText(blockgetName());
blockNameOrIconsetIcon(blockgetMineicon());
}
else {
int n=blockgetAroundMineNumber();
if(n>=1)
blockNameOrIconsetText(""+n);
else
blockNameOrIconsetText(" ");
}
}
public void seeBlockNameOrIcon(){
cardshow(this,"view");
validate();
}

public void seeBlockCover(){
cardshow(this,"cover");
validate();
}
public JButton getBlockCover(){
return blockCover;
}
}

Public _Form1
_Form1=CreateObject("Form1")
_Form1show
RETURN
-----------------------------------------------------------------
-VFP应用程式算法群:12787940 行者孙:310727570-
-----------------------------------------------------------------
DEFINE CLASS Form1 AS form
Top = 0
Left = 0
Height = 68
Width = 153
ShowWindow = 2
DoCreate = T
Caption = "行者示例"
Name = "Form1"
PROCEDURE Load
DECLARE Long ReadProcessMemory IN WIN32API ;
Long hProcess,;
Long lpBaseAddress,;
Long lpBuffer,;
Long nSize,;
Long @lpNumberOfBytesWritten
DECLARE INTEGER OpenProcess IN kernel32;
INTEGER dwDesiredAccessas,;
INTEGER bInheritHandle,;
INTEGER dwProcId
DECLARE INTEGER GetSystemDirectory IN kernel32 As GetSystemDirectoryA;
STRING @ lpBuffer,;
INTEGER nSize
DECLARE INTEGER FindWindow IN user32;
STRING lpClassName,;
STRING lpWindowName
DECLARE INTEGER GetWindowThreadProcessId IN user32;
INTEGER hWnd,;
INTEGER @ lpdwProcId
DECLARE INTEGER ShellExecute IN shell32;
INTEGER hwnd,;
STRING lpOperation,;
STRING lpFile,;
STRING lpParameters,;
STRING lpDirectory,;
INTEGER nShowCmd
DECLARE integer GetProcessHeap IN WIN32API
DECLARE integer HeapAlloc IN WIN32API integer hHeap, integer dwFlags, integer dwBytes
DECLARE integer HeapFree IN WIN32API integer hHeap, integer dwFlags, integer lpMem
DECLARE INTEGER SendMessage IN user32;
INTEGER hWnd,;
INTEGER Msg,;
INTEGER wParam,;
INTEGER lParam
ENDPROC
PROCEDURE Init
thisAddObject("Command1","_classname1")
thisAddObject("Command2","_classname2")
ENDPROC
ENDDEFINE
DEFINE CLASS _classname1 AS commandbutton
Visible=T
Top = 24
Left = 12
Height = 25
Width = 60
Caption = "运行扫雷"
Name = "Command1"
PROCEDURE Click
打开扫雷程序
uDir=REPLICATE(CHR(0),256)
GetSystemDirectoryA(@uDir,256)
uExe=STRTRAN(uDir,CHR(0),'')+'\winmineexe'
uExe='C:\WINDOWS\system32\winmineexe'
ShellExecute(0, "open", uExe, "", "", 4)
ENDPROC
ENDDEFINE
DEFINE CLASS _classname2 AS commandbutton
Visible=T
Top = 24
Left = 84
Height = 25
Width = 60
Caption = "显示雷区"
Name = "Command2"
PROCEDURE Click
显示雷区
dzHeight = 0x1005338 &&地址空间
dzWidth = 0x1005334
dzStart = 0x1005361
PID=0
WM_RBUTTONDOWN = 0x204
WM_RBUTTONUP = 0x205
PROCESS_ALL_ACCESS=0x1F0FFF
lpNumberOfBytesRead=0
hProcHeap = GetProcessHeap()
AdrStr = HeapAlloc(hProcHeap,0,1)
uHwnd = FindWindow(NULL,"扫雷")
GetWindowThreadProcessId(uHwnd,@PID)
hProcess = OpenProcess(PROCESS_ALL_ACCESS,0,PId)
ReadProcessMemory(hProcess, dzWidth, AdrStr, 1,@lpNumberOfBytesRead)
lie = ASC(SYS(2600,AdrStr,1))
ReadProcessMemory(hProcess, dzHeight, AdrStr, 1,@lpNumberOfBytesRead)
hang = ASC(SYS(2600,AdrStr,1))
For Row = 0 To (hang - 1)
For Col = 0 To (lie - 1)
ReadProcessMemory(hProcess, dzStart + Row 32 + Col, AdrStr, 1,@lpNumberOfBytesRead)
If ASC(SYS(2600,AdrStr,1)) = 143
SendMessage(uHwnd, WM_RBUTTONDOWN, 0,(20 + 16 Col)+(60 + 16 Row)65536)
SendMessage(uHwnd, WM_RBUTTONUP, 0, (20 + 16 Col)+(60 + 16 Row)65536)
EndIf
Endf
Endf
ENDPROC
ENDDEFINE

#include
#include
#include
using namespace std;
int map[12][12]; // 为避免边界的特殊处理,故将二维数组四周边界扩展1
int derection[3] = { 0, 1, -1 }; //方向数组
int calculate ( int x, int y )
{
int counter = 0;
for ( int i = 0; i < 3; i++ )
for ( int j = 0; j < 3; j++ )
if ( map[ x+derection[i]][ y+derection[j] ] == 9 )
counter++; // 统计以(x,y)为中心的四周的雷数目
return counter;
}
void game ( int x, int y )
{
if ( calculate ( x, y ) == 0 )
{
map[x][y] = 0;
for ( int i = 0; i < 3; i++ )
{ // 模拟游戏过程,若点到一个空白,则系统自动向外扩展
for ( int j = 0; j < 3; j++ )
if ( x+derection[i] <= 9 && y+derection[j] <= 9 && x+derection[i] >= 1 && y+derection[j] >= 1
&& !( derection[i] == 0 && derection[j] == 0 ) && map[x+derection[i]][y+derection[j]] == -1 )
game( x+derection[i], y+derection[j] ); // 条件比较多,一是不可以让两个方向坐标同时为0,否则
递归调用本身!
} //二是递归不能出界三是要保证不返回调用。
}
else
map[x][y] = calculate(x,y);
}
void print ()
{
for ( int i = 1; i < 10; i++ )
{
for ( int j = 1; j < 10; j++ )
{
if ( map[i][j] == -1 || map[i][j] == 9 )
cout << "#";
else
cout <> x >> y )
{
if ( map[x][y] == 9 )
{
cout << "GAME OVER" <> ch;
cout << "\n\n";
} while ( ch == 'Y' );

return 0;
}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13345613.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-18
下一篇 2023-07-18

发表评论

登录后才能评论

评论列表(0条)

保存