"扫雷"小游戏C代码
#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
main( )
{char a[102][102],b[102][102],c[102][102],w
int i,j /*循环变量*/
int x,y,z[999] /*雷的位置*/
int t,s /*标记*/
int m,n,lei /*计数*/
int u,v /*输入*/
int hang,lie,ge,mo /*自定义变量*/
srand((int)time(NULL)) /*启动随机数发生器*/
leb1: /*选择模式*/
printf("\n 请选择模式:\n 1.标准 2.自定义\n")
scanf("%d",&mo)
if(mo==2) /*若选择自定义模式,要输入三个参数*/
{do
{t=0printf("请输入\n行数 列数 雷的个数\n")
scanf("%d%d%d",&hang,&lie,&ge)
if(hang<2){printf("行数太少\n")t=1}
if(hang>100){printf("行数太多\n")t=1}
if(lie<2){printf("列数太少\n")t=1}
if(lie>100){printf("列数太多\n")t=1}
if(ge<1){printf("至少要有一个雷\n")t=1}
if(ge>=(hang*lie)){printf("雷太多了\n"哪清)t=1}
}while(t==1)
}
else{hang=10,lie=10,ge=10} /*否则就是选择了标准模式(默认参数)*/
for(i=1i<=gei=i+1) /*确定雷的位置李拍前*/
{do
{t=0z[i]=rand( )%(hang*lie)
for(j=1j<ij=j+1){if(z[i]==z[j]) t=1}
}while(t==1)
}
for(i=0i<=hang+1i=i+1) /*初始化a,b,c*/
{for(j=0j<=lie+1j=j+1) {a[i][j]='1'b[i][j]='1'c[i][j]='0'} }
for(i=1i<=hangi=i+1)
{for(j=1j<=liej=j+1) {a[i][j]='+'} }
for(i=1i<=gei=i+1) /*把雷放入c*/
{x=z[i]/lie+1y=z[i]%lie+1c[x][y]='#'}
for(i=1i<=hangi=i+1) /*计算b中数字*/
{for(j=1j<=liej=j+1)
{m=48
if(c[i-1][j-1]=='#')m=m+1if(c[i][j-1]=='#')m=m+1
if(c[i-1][j]=='#')m=m+1 if(c[i+1][j+1]=='#')m=m+1
if(c[i][j+1]=='#')m=m+1 if(c[i+1][j]=='#')m=m+1
if(c[i+1][j-1]=='#')m=m+1if(c[i-1][j+1]=='#')m=m+1
b[i][j]=m
}
}
for(i=1i<=gei=i+1) /*把雷放入b中*/
{x=z[i]/lie+1y=z[i]%lie+1b[x][y]='#'}
lei=ge /*以下是游戏设计*/
do
{leb2: /*输出*/
system("cls")printf("\n\n\n\n")
printf(" 贺迅")
for(i=1i<=liei=i+1)
{w=(i-1)/10+48printf("%c",w)
w=(i-1)%10+48printf("%c ",w)
}
printf("\n |")
for(i=1i<=liei=i+1){printf("---|")}
printf("\n")
for(i=1i<=hangi=i+1)
{w=(i-1)/10+48printf("%c",w)
w=(i-1)%10+48printf("%c |",w)
for(j=1j<=liej=j+1)
{if(a[i][j]=='0')printf(" |")
else printf(" %c |",a[i][j])
}
if(i==2)printf(" 剩余雷个数")
if(i==3)printf(" %d",lei)
printf("\n |")
for(j=1j<=liej=j+1){printf("---|")}
printf("\n")
}
scanf("%d%c%d",&u,&w,&v) /*输入*/
u=u+1,v=v+1
if(w!='#'&&a[u][v]=='@')
goto leb2
if(w=='#')
{if(a[u][v]=='+'){a[u][v]='@'lei=lei-1}
else if(a[u][v]=='@'){a[u][v]='?'lei=lei+1}
else if(a[u][v]=='?'){a[u][v]='+'}
goto leb2
}
a[u][v]=b[u][v]
leb3: /*打开0区*/
t=0
if(a[u][v]=='0')
{for(i=1i<=hangi=i+1)
{for(j=1j<=liej=j+1)
{s=0
if(a[i-1][j-1]=='0')s=1if(a[i-1][j+1]=='0')s=1
if(a[i-1][j]=='0')s=1 if(a[i+1][j-1]=='0')s=1
if(a[i+1][j+1]=='0')s=1if(a[i+1][j]=='0')s=1
if(a[i][j-1]=='0')s=1 if(a[i][j+1]=='0')s=1
if(s==1)a[i][j]=b[i][j]
}
}
for(i=1i<=hangi=i+1)
{for(j=liej>=1j=j-1)
{s=0
if(a[i-1][j-1]=='0')s=1if(a[i-1][j+1]=='0')s=1
if(a[i-1][j]=='0')s=1 if(a[i+1][j-1]=='0')s=1
if(a[i+1][j+1]=='0')s=1if(a[i+1][j]=='0')s=1
if(a[i][j-1]=='0')s=1 if(a[i][j+1]=='0')s=1
if(s==1)a[i][j]=b[i][j]
}
}
for(i=hangi>=1i=i-1)
{for(j=1j<=liej=j+1)
{s=0
if(a[i-1][j-1]=='0')s=1if(a[i-1][j+1]=='0')s=1
if(a[i-1][j]=='0')s=1 if(a[i+1][j-1]=='0')s=1
if(a[i+1][j+1]=='0')s=1if(a[i+1][j]=='0')s=1
if(a[i][j-1]=='0')s=1 if(a[i][j+1]=='0')s=1
if(s==1)a[i][j]=b[i][j]
}
}
for(i=hangi>=1i=i-1)
{for(j=liej>=1j=j-1)
{s=0
if(a[i-1][j-1]=='0')s=1if(a[i-1][j+1]=='0')s=1
if(a[i-1][j]=='0')s=1 if(a[i+1][j-1]=='0')s=1
if(a[i+1][j+1]=='0')s=1if(a[i+1][j]=='0')s=1
if(a[i][j-1]=='0')s=1 if(a[i][j+1]=='0')s=1
if(s==1)a[i][j]=b[i][j]
}
}
for(i=1i<=hangi=i+1) /*检测0区*/
{for(j=1j<=liej=j+1)
{if(a[i][j]=='0')
{if(a[i-1][j-1]=='+'||a[i-1][j-1]=='@'||a[i-1][j-1]=='?')t=1
if(a[i-1][j+1]=='+'||a[i-1][j+1]=='@'||a[i-1][j+1]=='?')t=1
if(a[i+1][j-1]=='+'||a[i+1][j-1]=='@'||a[i+1][j-1]=='?')t=1
if(a[i+1][j+1]=='+'||a[i+1][j+1]=='@'||a[i+1][j+1]=='?')t=1
if(a[i+1][j]=='+'||a[i+1][j]=='@'||a[i+1][j]=='?')t=1
if(a[i][j+1]=='+'||a[i][j+1]=='@'||a[i][j+1]=='?')t=1
if(a[i][j-1]=='+'||a[i][j-1]=='@'||a[i][j-1]=='?')t=1
if(a[i-1][j]=='+'||a[i-1][j]=='@'||a[i-1][j]=='?')t=1
}
}
}
if(t==1)goto leb3
}
n=0 /*检查结束*/
for(i=1i<=hangi=i+1)
{for(j=1j<=liej=j+1)
{if(a[i][j]!='+'&&a[i][j]!='@'&&a[i][j]!='?')n=n+1}
}
}
while(a[u][v]!='#'&&n!=(hang*lie-ge))
for(i=1i<=gei=i+1) /*游戏结束*/
{x=z[i]/lie+1y=z[i]%lie+1a[x][y]='#'}
printf(" ")
for(i=1i<=liei=i+1)
{w=(i-1)/10+48printf("%c",w)
w=(i-1)%10+48printf("%c ",w)
}
printf("\n |")
for(i=1i<=liei=i+1){printf("---|")}
printf("\n")
for(i=1i<=hangi=i+1)
{w=(i-1)/10+48printf("%c",w)
w=(i-1)%10+48printf("%c |",w)
for(j=1j<=liej=j+1)
{if(a[i][j]=='0')printf(" |")
else printf(" %c |",a[i][j])
}
if(i==2)printf(" 剩余雷个数")
if(i==3)printf(" %d",lei)printf("\n |")
for(j=1j<=liej=j+1) {printf("---|")}
printf("\n")
}
if(n==(hang*lie-ge)) printf("你成功了!\n")
else printf(" 游戏结束!\n")
printf(" 重玩请输入1\n")
t=0
scanf("%d",&t)
if(t==1)goto leb1
}
/*注:在DEV c++上运行通过。行号和列号都从0开始,比如要确定第0行第9列不是“雷”,就在0和9中间加入一个字母,可以输入【0a9】三个字符再按回车键。3行7列不是雷,则输入【3a7】回车;第8行第5列是雷,就输入【8#5】回车,9行0列是雷则输入【9#0】并回车*/
#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_INFOcsbiInfo
HANDLEhConsoleOut
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 = 1i <Ni++)
printf("┳━")
printf("┓\n")
for(i = 0i <Ni++) {
printf("┃")
for(j = 0j <Nj++) {
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 = 1j <Nj++) {
printf("━╋")
}
printf("━┫\n")
}
else {
printf("\n┗")
for(j = 1j <Nj++) {
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=0i<numi++) {
row = rand()%N
col = rand()%N
if(mine_array[row][col].type == 0)
mine_array[row][col].type = '*'
else // 已经有雷了,重新取下一个格子
i--
}
// 计算每个非雷格子周围的地雷数
for(row=0row<Nrow++)
{
for(col = 0col <Ncol++) {
if(mine_array[row][col].type == '*') {
for(i = row-1i <= row+1i++) {
for(j = col-1j <= col+1j++) {
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)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)