C语言扫雷游戏源代码

Python013

C语言扫雷游戏源代码,第1张

"扫雷"小游戏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 <conio.h>

#include <graphics.h>

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <ctype.h>

#include "mouse.c"

#define YES 1

#define NO 0

#define XPX 15 /* X pixels by square */

#define YPX 15 /* Y pixels by square */

#define DEFCX 30 /* Default number of squares */

#define DEFCY 28

#define MINE 255-'0' /* So that when it prints, it prints char 0xff */

#define STSQUARE struct stsquare

STSQUARE {

unsigned char value/* Number of mines in the surround squares */

unsigned char sqopen/* Square is open */

unsigned char sqpress/* Square is pressed */

unsigned char sqmark/* Square is marked */

} *psquare

#define value(x,y) (psquare+(x)*ncy+(y))->value

#define sqopen(x,y) (psquare+(x)*ncy+(y))->sqopen

#define sqpress(x,y) (psquare+(x)*ncy+(y))->sqpress

#define sqmark(x,y) (psquare+(x)*ncy+(y))->sqmark

int XST, /* Offset of first pixel X */

YST,

ncx, /* Number of squares in X */

ncy,

cmines, /* Mines discovered */

initmines, /* Number of initial mines */

sqclosed, /* Squares still closed */

maxy/* Max. number of y pixels of the screen */

void Graph_init(void)

void Read_param(int argc, char *argv[])

void Set_mines(int nminas)

void Set_square(int x, int y, int status)

void Mouse_set(void)

void Draw_squares(void)

int Do_all(void)

void Blow_up(void)

void Open_square(int x, int y)

int Open_near_squares(int x, int y)

/************************************************************************/

void main(int argc, char *argv[])

{

if (!mouse_reset()) {

cputs(" ERROR: I can't find a mouse driver\r\n")

exit(2)

}

Graph_init()

Read_param(argc, argv)

Mouse_set()

do {

randomize()

cleardevice()

Set_mines(cmines=initmines)

mouse_enable()

Draw_squares()

}

while (Do_all() != '\x1b')

closegraph()

}

/*************************************************************************

* *

* F U N C T I O N S *

* *

*************************************************************************/

/*----------------------------------------------------------------------*/

void Graph_init(void)

{

int graphdriver=DETECT, graphmode, errorcode

if(errorcode <0) {

cprintf("\n\rGraphics System Error: %s\n",grapherrormsg(errorcode))

exit(98)

}

initgraph(&graphdriver, &graphmode, "")

errorcode=graphresult()

if(errorcode!=grOk) {

printf(" Graphics System Error: %s\n",grapherrormsg(errorcode))

exit(98)

}

maxy=getmaxy()

} /* Graph_init */

/*----------------------------------------------------------------------*/

void Read_param(int argc, char *argv[])

{

int x, y, m

x=y=m=0

if (argc!=1) {

if (!isdigit(*argv[1])) {

closegraph()

cprintf("Usage is: %s [x] [y] [m]\r\n\n"

"Where x is the horizontal size\r\n"

" y is the vertical size\r\n"

" m is the number of mines\r\n\n"

" Left mouse button: Open the square\r\n"

"Right mouse button: Mark the square\r\n"

" -The first time puts a 'mine' mark\r\n"

" -The second time puts a 'possible "

"mine' mark\r\n"

" -The third time unmarks the square\r\n"

"Left+Right buttons: Open the surrounded squares only if "

"the count of mines\r\n"

" is equal to the number in the square",argv[0])

exit (1)

}

switch (argc) {

case 4: m=atoi(argv[3])

case 3: y=atoi(argv[2])

case 2: x=atoi(argv[1])

}

}

XST=100

ncx=DEFCX

if (maxy==479) {

YST=30

ncy=DEFCY

}

else {

YST=25

ncy=20

}

if (x>0 &&x<ncx)

ncx=x

if (y>0 &&y<ncy) {

YST+=((ncy-y)*YPX)>>1

ncy=y

}

initmines= m ? m : ncx*ncy*4/25/* There are about 16% of mines */

if (((void near*)psquare=calloc(ncx*ncy, sizeof(STSQUARE)))==NULL) {

closegraph()

cputs("ERROR: Not enought memory")

exit(3)

}

} /* Read_param */

/*----------------------------------------------------------------------*/

void Set_mines(int nminas)

{

#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)

}