C语言扫雷源代码 不用鼠标 操作 急求!!!
像推箱子那样有个随便用个不同的符号表示现在所在的位置WSAD控制移动翻开用X标记用C急求!!!!!...
像推箱子那样有个 随便用个不同的符号表示现在所在的位置 W S A D 控制移动 翻开用X 标记用 C 急求!!!!!
展开
1个回答
展开全部
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#define N 3
struct mine_box {
char type; // '*'代表地雷,n代表周围有地雷的地雷数(n=0-8)
char bMarked; // 是否被标记
char bOpened; // 是否被打开
} mine_array[N][N];
int CurrentRow, CurrentCol; // 记录当前光标的位置
int openedBlank = 0; // 记录被掀开的格子数
/*将光标定位到屏幕上的某个指定位置的坐标上*/
void gotoxy(int x,int y)
{ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
HANDLE hConsoleOut;
hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
csbiInfo.dwCursorPosition.X = x;
csbiInfo.dwCursorPosition.Y = y;
SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition);
}
// 显示一个格子的内容
void printBox(struct mine_box mb)
{
// 格子没被掀开也没做标记
if(mb.bOpened == 0 && mb.bMarked == 0)
printf("□");
// 格子被标记一次
else if(mb.bMarked == 1)
printf("√");
// 格子被标记两次
else if(mb.bMarked == 2)
printf("?");
// 格子被掀开,显示格子中的内容
else
switch(mb.type) {
// 格子中有地雷
case '*':
printf("⊕");
break;
// 格子没有地雷并且四周也没有地雷
case 0:
printf(" ");
break;
case 1:
printf("1");
break;
case 2:
printf("2");
break;
case 3:
printf("3");
break;
case 4:
printf("4");
break;
case 5:
printf("5");
break;
case 6:
printf("6");
break;
case 7:
printf("7");
break;
case 8:
printf("8");
break;
}
}
// 将光标移动到第row行第col列的格子上
void MoveTo(int row, int col)
{
CurrentRow = row;
CurrentCol = col;
gotoxy(CurrentCol*4+2,CurrentRow*2+1);
}
// 刷新屏幕
void refreshScreen(int state)
{
int i, j;
gotoxy(0, 0);
printf("┏━");
for(i = 1; i < N; i++)
printf("┳━");
printf("┓\n");
for(i = 0; i < N; i++) {
printf("┃");
for(j = 0; j < N; j++) {
if(state == -1 && mine_array[i][j].bMarked == 1 && mine_array[i][j].type != '*') {
printf("¤"); // 标记错了地雷
continue;
}
if(state != 0) { // 游戏结束,将所有的盒子掀开显示其中内容
mine_array[i][j].bOpened = 1;
mine_array[i][j].bMarked = 0;
}
printBox(mine_array[i][j]);
printf("┃");
}
if(i < N-1) {
printf("\n┣");
for(j = 1; j < N; j++) {
printf("━╋");
}
printf("━┫\n");
}
else {
printf("\n┗");
for(j = 1; j < N; j++) {
printf("━┻");
}
printf("━┛\n");
}
}
printf("按键指南:A左移,D右移,W上移,S下移,X翻开,C标记,Q退出\n");
}
void MoveUp()
{
if(CurrentRow > 0) {
CurrentRow --;
MoveTo(CurrentRow, CurrentCol);
}
}
void MoveDown()
{
if(CurrentRow < N-1) {
CurrentRow ++;
MoveTo(CurrentRow, CurrentCol);;
}
}
void MoveLeft()
{
if(CurrentCol > 0) {
CurrentCol --;
MoveTo(CurrentRow, CurrentCol);
}
}
void MoveRight()
{
if(CurrentCol < N-1) {
CurrentCol ++;
MoveTo(CurrentRow, CurrentCol);
}
}
int openMine()
{
int saveRow = CurrentRow, saveCol = CurrentCol;
if(mine_array[CurrentRow][CurrentCol].bOpened)
return 0;
mine_array[CurrentRow][CurrentCol].bOpened = 1;
mine_array[CurrentRow][CurrentCol].bMarked = 0;
if(mine_array[CurrentRow][CurrentCol].type == '*') {
refreshScreen(-1);
MoveTo(N+1, 0);
printf("失败!游戏结束)\n");
exit(2);
}
printBox(mine_array[CurrentRow][CurrentCol]);
MoveTo(CurrentRow, CurrentCol);
// 进一步要做的是当掀开一个type=0的空格子时,将其周围没有地雷的空格子自动掀开
return 1;
}
void markMine()
{
if(mine_array[CurrentRow][CurrentCol].bOpened == 1)
return;
if(mine_array[CurrentRow][CurrentCol].bMarked == 0)
mine_array[CurrentRow][CurrentCol].bMarked = 1;
else if(mine_array[CurrentRow][CurrentCol].bMarked == 1)
mine_array[CurrentRow][CurrentCol].bMarked = 2;
else if(mine_array[CurrentRow][CurrentCol].bMarked ==2)
mine_array[CurrentRow][CurrentCol].bMarked = 0;
printBox(mine_array[CurrentRow][CurrentCol]);
MoveTo(CurrentRow, CurrentCol);
}
main()
{
int num, i, j, row, col, count;
printf("输入地雷数: ");
scanf("%u", &num);
if(num > N*N) {
printf("地雷数超限\n");
return -1;
}
memset((void*)mine_array, 0, N*N*sizeof(struct mine_box));
//随机设置num个地雷的位置
srand((unsigned)time(NULL));
for(i=0; i<num; i++) {
row = rand()%N;
col = rand()%N;
if(mine_array[row][col].type == 0)
mine_array[row][col].type = '*';
else // 已经有雷了,重新取下一个格子
i--;
}
// 计算每个非雷格子周围的地雷数
for(row=0; row<N; row++)
{
for(col = 0; col < N; col++) {
if(mine_array[row][col].type == '*') {
for(i = row-1; i <= row+1; i++) {
for(j = col-1; j <= col+1; j++) {
if(i >= 0 && j >= 0 && i < N && j < N && mine_array[i][j].type != '*')
mine_array[i][j].type ++;
}
}
}
}
}
refreshScreen(0);
MoveTo(N/2, N/2); // 将光标移到中央的位置
do {
switch(getch()) {
case 'a':
case 'A':
MoveLeft();
break;
case 's':
case 'S':
MoveDown();
break;
case 'd':
case 'D':
MoveRight();
break;
case 'w':
case 'W':
MoveUp();
break;
case 'x':
case 'X':
if(openMine() == 1) {
if(++openedBlank == N*N-num) { //所有的空格都被掀开
refreshScreen(1);
MoveTo(N+1, 0);
printf("成功!游戏结束。\n");
exit(0);
}
}
break;
case 'c':
case 'C':
markMine();
break;
case 'q':
case 'Q':
MoveTo(N+1, 0);
printf("是否退出?(y/n)");
if(getch() == 'y')
return 0;
}
} while(1);
}
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#define N 3
struct mine_box {
char type; // '*'代表地雷,n代表周围有地雷的地雷数(n=0-8)
char bMarked; // 是否被标记
char bOpened; // 是否被打开
} mine_array[N][N];
int CurrentRow, CurrentCol; // 记录当前光标的位置
int openedBlank = 0; // 记录被掀开的格子数
/*将光标定位到屏幕上的某个指定位置的坐标上*/
void gotoxy(int x,int y)
{ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
HANDLE hConsoleOut;
hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
csbiInfo.dwCursorPosition.X = x;
csbiInfo.dwCursorPosition.Y = y;
SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition);
}
// 显示一个格子的内容
void printBox(struct mine_box mb)
{
// 格子没被掀开也没做标记
if(mb.bOpened == 0 && mb.bMarked == 0)
printf("□");
// 格子被标记一次
else if(mb.bMarked == 1)
printf("√");
// 格子被标记两次
else if(mb.bMarked == 2)
printf("?");
// 格子被掀开,显示格子中的内容
else
switch(mb.type) {
// 格子中有地雷
case '*':
printf("⊕");
break;
// 格子没有地雷并且四周也没有地雷
case 0:
printf(" ");
break;
case 1:
printf("1");
break;
case 2:
printf("2");
break;
case 3:
printf("3");
break;
case 4:
printf("4");
break;
case 5:
printf("5");
break;
case 6:
printf("6");
break;
case 7:
printf("7");
break;
case 8:
printf("8");
break;
}
}
// 将光标移动到第row行第col列的格子上
void MoveTo(int row, int col)
{
CurrentRow = row;
CurrentCol = col;
gotoxy(CurrentCol*4+2,CurrentRow*2+1);
}
// 刷新屏幕
void refreshScreen(int state)
{
int i, j;
gotoxy(0, 0);
printf("┏━");
for(i = 1; i < N; i++)
printf("┳━");
printf("┓\n");
for(i = 0; i < N; i++) {
printf("┃");
for(j = 0; j < N; j++) {
if(state == -1 && mine_array[i][j].bMarked == 1 && mine_array[i][j].type != '*') {
printf("¤"); // 标记错了地雷
continue;
}
if(state != 0) { // 游戏结束,将所有的盒子掀开显示其中内容
mine_array[i][j].bOpened = 1;
mine_array[i][j].bMarked = 0;
}
printBox(mine_array[i][j]);
printf("┃");
}
if(i < N-1) {
printf("\n┣");
for(j = 1; j < N; j++) {
printf("━╋");
}
printf("━┫\n");
}
else {
printf("\n┗");
for(j = 1; j < N; j++) {
printf("━┻");
}
printf("━┛\n");
}
}
printf("按键指南:A左移,D右移,W上移,S下移,X翻开,C标记,Q退出\n");
}
void MoveUp()
{
if(CurrentRow > 0) {
CurrentRow --;
MoveTo(CurrentRow, CurrentCol);
}
}
void MoveDown()
{
if(CurrentRow < N-1) {
CurrentRow ++;
MoveTo(CurrentRow, CurrentCol);;
}
}
void MoveLeft()
{
if(CurrentCol > 0) {
CurrentCol --;
MoveTo(CurrentRow, CurrentCol);
}
}
void MoveRight()
{
if(CurrentCol < N-1) {
CurrentCol ++;
MoveTo(CurrentRow, CurrentCol);
}
}
int openMine()
{
int saveRow = CurrentRow, saveCol = CurrentCol;
if(mine_array[CurrentRow][CurrentCol].bOpened)
return 0;
mine_array[CurrentRow][CurrentCol].bOpened = 1;
mine_array[CurrentRow][CurrentCol].bMarked = 0;
if(mine_array[CurrentRow][CurrentCol].type == '*') {
refreshScreen(-1);
MoveTo(N+1, 0);
printf("失败!游戏结束)\n");
exit(2);
}
printBox(mine_array[CurrentRow][CurrentCol]);
MoveTo(CurrentRow, CurrentCol);
// 进一步要做的是当掀开一个type=0的空格子时,将其周围没有地雷的空格子自动掀开
return 1;
}
void markMine()
{
if(mine_array[CurrentRow][CurrentCol].bOpened == 1)
return;
if(mine_array[CurrentRow][CurrentCol].bMarked == 0)
mine_array[CurrentRow][CurrentCol].bMarked = 1;
else if(mine_array[CurrentRow][CurrentCol].bMarked == 1)
mine_array[CurrentRow][CurrentCol].bMarked = 2;
else if(mine_array[CurrentRow][CurrentCol].bMarked ==2)
mine_array[CurrentRow][CurrentCol].bMarked = 0;
printBox(mine_array[CurrentRow][CurrentCol]);
MoveTo(CurrentRow, CurrentCol);
}
main()
{
int num, i, j, row, col, count;
printf("输入地雷数: ");
scanf("%u", &num);
if(num > N*N) {
printf("地雷数超限\n");
return -1;
}
memset((void*)mine_array, 0, N*N*sizeof(struct mine_box));
//随机设置num个地雷的位置
srand((unsigned)time(NULL));
for(i=0; i<num; i++) {
row = rand()%N;
col = rand()%N;
if(mine_array[row][col].type == 0)
mine_array[row][col].type = '*';
else // 已经有雷了,重新取下一个格子
i--;
}
// 计算每个非雷格子周围的地雷数
for(row=0; row<N; row++)
{
for(col = 0; col < N; col++) {
if(mine_array[row][col].type == '*') {
for(i = row-1; i <= row+1; i++) {
for(j = col-1; j <= col+1; j++) {
if(i >= 0 && j >= 0 && i < N && j < N && mine_array[i][j].type != '*')
mine_array[i][j].type ++;
}
}
}
}
}
refreshScreen(0);
MoveTo(N/2, N/2); // 将光标移到中央的位置
do {
switch(getch()) {
case 'a':
case 'A':
MoveLeft();
break;
case 's':
case 'S':
MoveDown();
break;
case 'd':
case 'D':
MoveRight();
break;
case 'w':
case 'W':
MoveUp();
break;
case 'x':
case 'X':
if(openMine() == 1) {
if(++openedBlank == N*N-num) { //所有的空格都被掀开
refreshScreen(1);
MoveTo(N+1, 0);
printf("成功!游戏结束。\n");
exit(0);
}
}
break;
case 'c':
case 'C':
markMine();
break;
case 'q':
case 'Q':
MoveTo(N+1, 0);
printf("是否退出?(y/n)");
if(getch() == 'y')
return 0;
}
} while(1);
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询