阵列中的地雷、数字、空白格与标记格设计
用一个二维矩阵代表阵列:
元素值统一初始化为-1;
随机产生10组坐标,每组坐标对应地雷元素,共10个地雷,并均赋值为9,即地雷的元素值为9;
元素值为n(-1<n<9)代表周围有n个地雷(遍历元素周围8个元素如果检测是地雷counter++,遍历完后返回counter);
元素值为0代表周围没有地雷,挖到该元素时自动显示周围8个元素,如果周围又有个0值元素,递归调用自动显示周围8个元素的方法;
如果确认某一元素是地雷,则对其标记并将元素值设为-2,这样挖掘某一元素时判断是地雷的条件为(元素值为9或元素值为-2),当然没有考虑误标记的情况,但一般人不会将标记了的元素再挖掘一次,在本程序中如果你挖掘标记为地雷的元素,游戏就结束了,你得为自己的智商付出代价;
当然标记也可以取消,这样就把这个元素值初始化为-1。
流程设计
1.初始化阵列。2.输入坐标点。
3.选择:挖掘,标记,取消标记,重启,退出游戏。
如果选了挖掘,判断坐标点是地雷则游戏结束,是数字则显示数字并回到2,是空格则显示周围8个元素值并直到连带的空格显示完了回到2;
如果选了标记,将该点的元素值设为-2并回到2;
如果选了取消标记,初始化该点,回到2;
如果选了重启,则初始化阵列,回到2;
如果选了退出游戏,则exit。
4.挖掘完所有非地雷点后,游戏胜利,选择是否再来一局,是则回到1,否则exit
面向对象设计思想
创建一个bombsweep类,存储几个方法:
calculate:统计以(x,y)为中心周围8个点的地雷数目。
game:模拟游戏过程。
print:打印阵列。
check:检查是否满足胜利条件。
在main函数中,在需要的时候根据bombsweep类创建bs对象,调用bs里面的相关方法。
程序代码
参考了点击打开链接 的代码并进行了优化,谢谢原作者分享。
<span style="font-weight: normal;"><span style="font-size:14px;">#include <ctime>
#include <cstdlib>
#include <iostream>
#include <cstring>
using namespace std;
int map[12][12]; // 为避免边界的特殊处理,故将二维数组四周边界扩展1
int derection[3] = { 0, 1, -1 }; //用于处理中心周围8个点的数组
int type;
class bombsweep
{
public:
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)为中心周围8个点的地雷数目
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 (int x,int y)
{
cout << " |";
for (int i=1; i<10; i++)
cout << " " << i;
cout << endl;
cout << "__|__________________Y" ;
cout << endl;
for ( int i = 1; i < 10; i++ )
{
cout << i << " |";
for ( int j = 1; j < 10; j++ )
{
if(map[i][j]==-2)
cout <<" B";
else if ( map[i][j] == -1 || map[i][j] == 9 )
cout << " #";
else
cout << " "<< map[i][j];
}
cout << "\n";
}
cout << " X\n";
}
bool check ()
{
int counter = 0;
for ( int i = 1; i < 10; i++ )
for ( int j = 1; j < 10; j++ )
if ( map[i][j] != -1 )
counter++;
if ( counter == 10 )
return true;
else
return false;
}
};
int main ()
{
int i, j, x, y;
char ch;
srand ( time ( 0 ) );
do
{
//初始化阵列
memset ( map, -1, sizeof(map) );
for ( i = 0; i < 10; )
{
x = rand()%9 + 1;
y = rand()%9 + 1;
if ( map[x][y] != 9 )
{
map[x][y] = 9;
i++;
}
}
cout << " |";
for (i=1; i<10; i++)
cout << " " << i;
cout << endl;
cout << "__|__________________Y" ;
cout << endl;
for ( i = 1; i < 10; i++ )
{
cout << i << " |";
for ( j = 1; j < 10; j++ )
cout << " "<< "#";
cout << "\n";
}
cout << " X\n";
cout << "Please input location x,press enter then input location y: \n";
while ( cin >> x >> y )
{
cout << "Please select:1.dig, 2.sign, 3.cancel sign, 4.restart, 5.exit: \n";
cin >>type;
switch(type)
{
case 1:
{
if ( map[x][y] == 9 || map[x][y]==-2)
{
cout << "YOU LOSE!" << endl;
cout << " |";
for (i=1; i<10; i++)
cout << " " << i;
cout << endl;
cout << "__|__________________Y"<<endl ;
for ( i = 1; i < 10; i++ )
{
cout << i << " |";
for ( j = 1; j < 10; j++ )
{
if ( map[i][j] == 9 || map[i][j]==-2)
cout << " @";
else
cout << " #";
}
cout << "\n";
}
cout << " X\n";
exit(0);
}
bombsweep bs;
bs.game(x,y);
bs.print(x,y);
cout << "Please input location x,press enter then input location y: \n";
if ( bs.check())
{
cout << "YOU WIN" << endl;
break;
}
continue;
}
case 2:
{
bombsweep bs;
map[x][y]=-2;
bs.print(x,y);
cout << "Please input location x,press enter then input location y: \n";
continue;
}
case 3:
{
bombsweep bs;
map[x][y]=-1;
bs.print(x,y);
cout << "Please input location x,press enter then input location y: \n";
continue;
}
case 4:
{
memset ( map, -1, sizeof(map) );
for ( i = 0; i < 10; )
{
x = rand()%9 + 1;
y = rand()%9 + 1;
if ( map[x][y] != 9 )
{
map[x][y] = 9;
i++;
}
}
cout << " |";
for (i=1; i<10; i++)
cout << " " << i;
cout << endl;
cout << "__|__________________Y" ;
cout << endl;
for ( i = 1; i < 10; i++ )
{
cout << i << " |";
for ( j = 1; j < 10; j++ )
cout << " "<< "#";
cout << "\n";
}
cout << " X\n";
cout << "Please input location x,press enter then input location y: \n";
continue;
}
case 5:
cout << "Game Ended\n";
exit(0);
break;
default:
cout<< "Invalid input, try again: \n";
continue;
}//end switch
}//end while(cin >> x >>y)
cout << "Do you want to play again?(y/n):" << endl;
cin >> ch;
}//end do
while ( ch == 'y' );
return 0;
}//end main()
</span></span>