C語言遞歸實現(xiàn)掃雷游戲
前言
首先要實現(xiàn)掃雷原理上同三子棋,都是通過一個二維數(shù)組來實現(xiàn)游戲主題功能那么這里有幾個值得注意的點
1、初級掃雷我們知道是九乘九數(shù)組實現(xiàn),那么在這里我們創(chuàng)建的是11乘11的數(shù)組,目的是方便后續(xù)判斷周圍九個格子的雷的數(shù)量!
2、而且我們需要創(chuàng)建兩個數(shù)組,一個用來存放字符1和0(1表示有雷,隨機數(shù)生成;0表示沒雷,初始化時自動全放0);
另一個用來根據(jù)上邊的數(shù)組輸出顯示玩家是否被炸死,以及玩家選擇的坐標周圍雷的數(shù)量

3、需要注意排雷時候如果附近沒有雷需要遞歸展開!??!
4、我們這里需要兩個源文件test.c game.c和頭文件game.h
一、菜單
這個游戲界面小伙伴自己設(shè)計就可老生常談我直接上代碼
void menu()
{
printf("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n");
printf("-*-*-*-*-*-*1.play 0.exit*-*-*-*-*-*-*-\n");
printf("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n");
}
void test()
{
int input = 0;
do {
menu();
printf("請輸入:");
scanf("%d", &input);
switch(input)
{
case 1:game(); break;
case 0:
printf("退出游戲!");
break;
default:printf("輸入非法,請重新輸入:\n");
break;
}
} while (input);
}
int main()
{
srand((unsigned int)time(0));
test();
return 0;
}
二、游戲數(shù)組的創(chuàng)建和初始化
那么在這里為了方便使用行數(shù)列數(shù)依然采用宏定義給出行數(shù)列數(shù)和雷的個數(shù)EASYCOUT
#define ROW 9 #define COL 9 #define ROWS 11 #define COLS 11 #define EASYCOUT 10
數(shù)組的創(chuàng)建
char mine[ROWS][COLS]; char show[ROWS][COLS];
數(shù)組初始化和打印
init(mine, ROWS, COLS, '0'); init(show, ROWS, COLS, '*'); display(mine, ROW, COL); display(show,ROW,COL);
void init(char board[ROWS][COLS], int rows, int cols, char ch)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
board[i][j] = ch;
}
}
}
void display(char board[ROWS][COLS], int rows, int cols)
{
printf(" ");
for (int i = 1; i <= rows; i++)
printf(" %d ",i);
printf("\n");
for (int i = 1; i <= rows; i++)
{
printf("%d ",i);
for (int j = 1; j <= cols; j++)
{
printf(" %c ", board[i][j]);
}printf("\n");
}
}
三、設(shè)置雷和掃雷
setmine(mine,ROWS,COLS); display(mine, ROW, COL);
1.設(shè)置雷
這里主要應(yīng)用隨機數(shù)的生成,之前的文章已經(jīng)介紹過。其次就是需要判斷隨機數(shù)的生成是否重復(fù),重復(fù)需要去重:
void setmine(char board[ROWS][COLS], int rows, int cols)
{
int x, y;
for(int i=0;i < EASYCOUT;i++)
{
x = rand() % 9 + 1;
y = rand() % 9 + 1;
if (board[x][y] == '0')
board[x][y] = '1';//1表示雷
else i--;
}
}
2.掃雷
在這個游戲主體部分我們需要用循環(huán)解決,循環(huán)次數(shù)則需要用
行數(shù)*列數(shù)-雷數(shù)量
同時需要注意輸入坐標x y的范圍以及周圍的判斷?。?/p>
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
//
int x = 0, y = 0;
int count = ROW* COL-EASYCOUT;
int i = 0;//計算排雷次數(shù)
while (count)
{
printf("請輸入排查的行數(shù)列數(shù):");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
i++;
if (mine[x][y] == '1')
{
if (i == 1)
{
printf("很遺憾第一次你被炸死了,你還有最后機會!\n");
continue;
}
display(mine, ROW, COL);
printf("很遺憾你被炸死了!\n");
break;
}
else
{
count--;
//遞歸實現(xiàn)
diguishow(mine,show,x,y, ROW, COL);
display(show, ROW, COL);
}
}
else
{
printf("輸入非法,重新輸入!\n");
}
}
if (!count)
{
printf("恭喜你獲得勝利!\n");
}
}
3.周圍雷的數(shù)量的判斷
這里采用數(shù)值相減的方法字符1和字符0的值差1.
int getnum(char mine[ROWS][COLS],int x,int y)
{
return mine[x - 1][y - 1] +
mine[x - 1][y] +
mine[x - 1][y + 1] +
mine[x][y - 1] +
mine[x][y + 1] +
mine[x + 1][y - 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] - 8 * '0';
}
四、遞歸實現(xiàn)展示
這里注意兩個條件:
1、遞歸截止條件是該坐標周圍的雷的數(shù)量非0
2、讓周圍8個坐標依次遞歸
3、注意判斷過周圍8個格子沒有雷的坐標需要標記置空格?。?!來避免重復(fù)操作否則棧溢出
void diguishow(char mine[ROWS][COLS],char show[ROWS][COLS],int x,int y,int row,int col)
{
//截止條件該數(shù)字不是0
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (show[x][y] == ' ')
{
return;
}
else if (getnum(mine, x, y) != 0)
{
show[x][y] = getnum(mine, x, y) + '0';
return;
}
else {
show[x][y] = ' ';
diguishow(mine, show, x - 1, y - 1,row,col);
diguishow(mine, show, x - 1, y, row, col);
diguishow(mine, show, x - 1, y + 1, row, col);
diguishow(mine, show, x, y - 1, row, col);
diguishow(mine, show, x, y + 1, row, col);
diguishow(mine, show, x + 1, y - 1, row, col);
diguishow(mine, show, x + 1, y, row, col);
diguishow(mine, show, x + 1, y + 1, row, col);
}
}
}
全代碼:
game.h
#pragma once #include<stdio.h> #include<Windows.h> #include<time.h> #include<stdlib.h> #define ROW 9 #define COL 9 #define ROWS 11 #define COLS 11 #define EASYCOUT 10 void init(char board[ROWS][COLS],int rows,int cols,char ch); void display(char board[ROWS][COLS],int rows,int cols); void setmine(char board[ROWS][COLS],int rows,int cols); void findmine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col); int getnum(char mine[ROWS][COLS], int x, int y); void diguishow(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int row, int col);
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
init(mine, ROWS, COLS, '0');
init(show, ROWS, COLS, '*');
display(mine, ROW, COL);
display(show,ROW,COL);
//生成雷
setmine(mine,ROWS,COLS);
display(mine, ROW, COL);
//排雷
findmine(mine,show,ROW,COL);
}
void menu()
{
printf("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n");
printf("-*-*-*-*-*-*1.play 0.exit*-*-*-*-*-*-*-\n");
printf("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-\n");
}
void test()
{
int input = 0;
do {
menu();
printf("請輸入:");
scanf("%d", &input);
switch(input)
{
case 1:game(); break;
case 0:
printf("退出游戲!");
break;
default:printf("輸入非法,請重新輸入:\n");
break;
}
} while (input);
}
int main()
{
srand((unsigned int)time(0));
test();
return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void diguishow(char mine[ROWS][COLS],char show[ROWS][COLS],int x,int y,int row,int col)
{
//截止條件該數(shù)字不是0
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (show[x][y] == ' ')
{
return;
}
else if (getnum(mine, x, y) != 0)
{
show[x][y] = getnum(mine, x, y) + '0';
return;
}
else {
show[x][y] = ' ';
diguishow(mine, show, x - 1, y - 1,row,col);
diguishow(mine, show, x - 1, y, row, col);
diguishow(mine, show, x - 1, y + 1, row, col);
diguishow(mine, show, x, y - 1, row, col);
diguishow(mine, show, x, y + 1, row, col);
diguishow(mine, show, x + 1, y - 1, row, col);
diguishow(mine, show, x + 1, y, row, col);
diguishow(mine, show, x + 1, y + 1, row, col);
}
}
}
int getnum(char mine[ROWS][COLS],int x,int y)
{
return mine[x - 1][y - 1] +
mine[x - 1][y] +
mine[x - 1][y + 1] +
mine[x][y - 1] +
mine[x][y + 1] +
mine[x + 1][y - 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] - 8 * '0';
}
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
//
int x = 0, y = 0;
int count = ROW* COL-EASYCOUT;
int i = 0;//計算排雷次數(shù)
while (count)
{
printf("請輸入排查的行數(shù)列數(shù):");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
i++;
if (mine[x][y] == '1')
{
if (i == 1)
{
printf("很遺憾第一次你被炸死了,你還有最后機會!\n");
continue;
}
display(mine, ROW, COL);
printf("很遺憾你被炸死了!\n");
break;
}
else
{
count--;
//遞歸實現(xiàn)
diguishow(mine,show,x,y, ROW, COL);
display(show, ROW, COL);
}
}
else
{
printf("輸入非法,重新輸入!\n");
}
}
if (!count)
{
printf("恭喜你獲得勝利!\n");
}
}
void init(char board[ROWS][COLS], int rows, int cols, char ch)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
board[i][j] = ch;
}
}
}
void display(char board[ROWS][COLS], int rows, int cols)
{
printf(" ");
for (int i = 1; i <= rows; i++)
printf(" %d ",i);
printf("\n");
for (int i = 1; i <= rows; i++)
{
printf("%d ",i);
for (int j = 1; j <= cols; j++)
{
printf(" %c ", board[i][j]);
}printf("\n");
}
}
void setmine(char board[ROWS][COLS], int rows, int cols)
{
int x, y;
for(int i=0;i < EASYCOUT;i++)
{
x = rand() % 9 + 1;
y = rand() % 9 + 1;
if (board[x][y] == '0')
board[x][y] = '1';//1表示雷
else i--;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
通過先序遍歷和中序遍歷后的序列還原二叉樹(實現(xiàn)方法)
下面小編就為大家?guī)硪黄ㄟ^先序遍歷和中序遍歷后的序列還原二叉樹(實現(xiàn)方法)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06

