c语言:带计时的扫雷游戏(一)

先上图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可能用的到的头文件

#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<conio.h>
#include<windows.h>
#include <pthread.h>
#include<stdio.h>
#include "time.h"
using namespace std;
#define NUM_THREADS 1

全局变量:

int saolei_able[100][100]={0}; //底层地图
char saolei_enable[100][100];//上层地图
int leave_number=0;//剩下的未扫区域
int grade=0;//成绩
int game=0;//开始游戏时,判断是否停止计时退出线程(1为停止,退出线程)
int width=10;//地图行(默认为10)
int height=10;//地图列(默认为10)
int dilei_qty=20;//地雷数量(默认为20)

主菜单

主菜单有4个选项,开始游戏,游戏排行,游戏设置,退出游戏
开始游戏有计时,判断游戏胜利,判断游戏失败,排行榜写入等功能
游戏排行只有读取显示排行的功能
游戏设置可以自定义地雷数量,地图大小
主菜代码:menu()
system(“cls”); 清屏作用

void menu(){
	system("cls");
	printf("************菜单************\n\n");
	printf("         1.开始游戏\n");
	printf("         2.游戏排名\n");
	printf("         3.游戏设置\n");
	printf("         4.退出游戏\n\n");
	printf("****************************\n\n");
	int n;
	printf("菜单操作:");
	scanf("%d",&n);
	switch(n){
		case 1:
			start_game();
			system("cls");
			break;
		case 2:
			system("cls");
			read_rank();
			break;
		case 3:
			setting_game();
			break;
		case 4:
			system("cls");
			printf("game over!");
			break;
		default:
			break;
	}
}

开始游戏:start_game()
init_saolei() 上层地图初始化,*为不可见。
数组变量saolei_able是底层地图
数组变量saolei_enable是上层地图
dilei_number() 设置底层地图地雷数量
blank_number() 点击的坐标的周围没有地雷的时候自动翻起周围一圈
refresh_window() 动画刷新界面
times() 线程计时

void start_game(){
	int index=0,row,column;
	init_saolei();
	while(index<dilei_qty){
		row=rand()%width;
		column=rand()%height;
		if(saolei_able[row][column]!=-1){
			saolei_able[row][column]=-1;
			index++;
			dilei_number(row,column);
		}
	}
	pthread_t tids[NUM_THREADS];
	for( int i = 0; i < NUM_THREADS; ++i )
	    {
	        int ret = pthread_create( &tids[i], NULL, times, NULL ); //参数:创建的线程id,线程参数,线程运行函数的起始地址,运行函数的参数
	    }
//	pthread_exit( NULL );
	int a,b,n;
	while(1){
		refresh_window();
		scanf("%d %d",&a,&b);
		while(a<0 || b<0 || a>=width|| b>=height || saolei_enable[a][b]!='*'){
			scanf("%d %d",&a,&b);
		}
		leave_number++;
		if(saolei_able[a][b]!=-1)
			saolei_enable[a][b]=saolei_able[a][b]+48;
		else
			saolei_enable[a][b]=35;
		if(saolei_able[a][b]==0){
			blank_number(a,b);
		} 
		if(saolei_able[a][b]==-1){
			refresh_window();
			char name[10];
			printf("You Lose!\n");
			printf("Game Over!\n");
			printf("1.返回菜单\t2.退出游戏\n");
			game=1;
			scanf("%d",&n);
			if(n==1){
				game=0;
				grade=0;
				menu();
			}
			break;
		}
		if(leave_number==width*height-dilei_qty){
			char name[10];
			printf("Yow Win!\n");
			game=1;
			printf("输入您的昵称:");
			scanf("%s",&name);
			write_rank(name,grade-1);
			printf("1.返回菜单\t2.退出游戏\n");
			scanf("%d",&n);
			if(n==1){
				grade=0;
				game=0;
				system("cls");
				menu();
			}
			break;
		}
	} 
}

上层地图初始化:init_saolei()

void init_saolei(){
	for(int i=0;i<width;i++){
		for(int j=0;j<height;j++){
			saolei_enable[i][j]='*';
		}
	}
}

初始化地雷数量:dilei_number()

void dilei_number(int a,int b){
	    if(a-1>=0 && b-1>=0 && saolei_able[a-1][b-1]!=-1)
	        saolei_able[a-1][b-1]+=1;
	    if(a-1>=0 &&  saolei_able[a - 1][b] != -1)
	        saolei_able[a - 1][b] += 1;
	    if(a-1>=0 && b+1<height && saolei_able[a - 1][b + 1] != -1)
	        saolei_able[a - 1][b + 1] += 1;
	    if(b-1>=0 && saolei_able[a ][b - 1] != -1)
	        saolei_able[a][b - 1] += 1;
	    if(b+1<height && saolei_able[a][b + 1] != -1)
	        saolei_able[a ][b +1] += 1;
	    if(a+1<width && b-1>=0 && saolei_able[a +1][b - 1] != -1) 
	        saolei_able[a + 1][b - 1] += 1;
	    if(a+1<width && saolei_able[a + 1][b] != -1) 
	        saolei_able[a + 1][b ] += 1;
	    if(a+1<width && b+1<height && saolei_able[a +1 ][b + 1] != -1)
	        saolei_able[a+1][b +1] += 1;
}

自动翻起周围一圈:blank_number()

void blank_number(int a,int b){
	    if(a - 1 >= 0 && b - 1 >= 0)
	        if(saolei_enable[a-1][b-1]=='*'){
	            saolei_enable[a-1][b-1]=saolei_able[a-1][b-1]+48;
	            leave_number++;
	            if(saolei_able[a-1][b-1]==0)
	                blank_number(a-1,b-1);
	        }
	    if (a-1>=0)
	        if(saolei_enable[a-1][b]=='*'){
	            saolei_enable[a-1][b]=saolei_able[a-1][b]+48;
	            leave_number++;
	            if(saolei_able[a-1][b]==0)
	                blank_number(a-1,b);
	        }
	    if(a-1>=0 && b+1<height)
	        if(saolei_enable[a-1][b+1]=='*'){
	            saolei_enable[a-1][b+1]=saolei_able[a-1][b+1]+48;
	            leave_number++;
	            if(saolei_able[a-1][b+1]==0)
	                blank_number(a - 1, b+1);
	        }
	    if(b-1>=0)
	        if(saolei_enable[a][b - 1]=='*'){
	            saolei_enable[a][b - 1] = saolei_able[a][b - 1]+48;
	            leave_number++;
	            if(saolei_able[a][b - 1]==0)
	                blank_number(a, b - 1);
	        }
	    if (b+1<height)
	        if(saolei_enable[a][b + 1]=='*'){
	            saolei_enable[a][b + 1] = saolei_able[a][b + 1]+48;
	            leave_number++;
	            if(saolei_able[a][b + 1]==0)
	                blank_number(a,b+1);
	        }
	    if(a+1<width && b-1>=0)
	        if(saolei_enable[a + 1][b - 1]=='*'){
	            saolei_enable[a + 1][b - 1] = saolei_able[a + 1][b - 1]+48;
	            leave_number++;
	            if(saolei_able[a + 1][b - 1]==0)
	                blank_number(a+1,b-1);
	        }
	    if(a+1<width)
	        if(saolei_enable[a + 1][b]=='*'){
	            saolei_enable[a + 1][b] = saolei_able[a + 1][b]+48;
	            leave_number++;
	            if(saolei_able[a + 1][b]==0)
	                blank_number(a+1,b);
	        }
	    if(a+1<width && b+1<height)
	        if(saolei_enable[a + 1][b + 1]=='*'){
	            saolei_enable[a + 1][b + 1] = saolei_able[a + 1][b + 1]+48;
	            leave_number++;
	            if(saolei_able[a + 1][b + 1]==0)
	                blank_number(a+1,b+1);
	        }
}

刷新界面:refresh_window()

void refresh_window(){
	system("cls");
	printf("\n");
	printf("  ");
	for(int i=0;i<height;i++){
		printf("%2d",i);
	}
	printf("\n");
	for(int i=0;i<width;i++){
		printf("%2d",i);
		for(int j=0;j<height;j++){
			printf("%2c",saolei_enable[i][j]);
		}printf("\n");
	}
}

线程计时:
函数gotoxy(),自定义光标位置,通过光标定位,实现局部刷新

void gotoxy(int a, int b)
{
	HANDLE hOutput;
	COORD loc;
	loc.X =a;
	loc.Y=b;
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hOutput, loc);
	return;
}

线程函数times()
将计时器定位到0,0的坐标进行计时。
当主函数需要输入时恢复光标位置,实现输入

void* times(void *args){
	HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_SCREEN_BUFFER_INFO pt;
	GetConsoleScreenBufferInfo(hout,&pt);
	gotoxy(0,0);
	gotoxy(pt.dwCursorPosition.X,pt.dwCursorPosition.Y);
	
	while(1){
		GetConsoleScreenBufferInfo(hout,&pt);
		gotoxy(0,0);
		printf("计时:%d",grade++);
		gotoxy(pt.dwCursorPosition.X,pt.dwCursorPosition.Y);
		if(game==1){
			break;
		}
		Sleep(1000);
	}
	return 0;
}

先更到这里。。。
源代码,点赞/评论/收藏后单发
下载源码

已更新源码


#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<conio.h>
#include<windows.h>
#include <pthread.h>
#include<stdio.h>
#include "time.h"
using namespace std;
#define NUM_THREADS 1
int saolei_able[100][100]={0};
char saolei_enable[100][100];
int leave_number=0;
int grade=0;
int game=0;
int width=10;
int height=10;
int dilei_qty=20;
int k=1;
void menu();
void read_rank();
void start_game();
//void write_rank();
void refresh_window();
void init_saolei();
void setting_game();
int* printCurrentTime();
void* times(void *args);
void write_rank(const char* name,int time);

struct ranks_str{
	char *name;
	char *gtime;
	char *ctime;
}ranks[10];
void gotoxy(int a, int b)
{
	HANDLE hOutput;
	COORD loc;
	loc.X =a;
	loc.Y=b;
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hOutput, loc);
	return;
}
void dilei_number(int a,int b){
	    if(a-1>=0 && b-1>=0 && saolei_able[a-1][b-1]!=-1)
	        saolei_able[a-1][b-1]+=1;
	    if(a-1>=0 &&  saolei_able[a - 1][b] != -1)
	        saolei_able[a - 1][b] += 1;
	    if(a-1>=0 && b+1<height && saolei_able[a - 1][b + 1] != -1)
	        saolei_able[a - 1][b + 1] += 1;
	    if(b-1>=0 && saolei_able[a ][b - 1] != -1)
	        saolei_able[a][b - 1] += 1;
	    if(b+1<height && saolei_able[a][b + 1] != -1)
	        saolei_able[a ][b +1] += 1;
	    if(a+1<width && b-1>=0 && saolei_able[a +1][b - 1] != -1) 
	        saolei_able[a + 1][b - 1] += 1;
	    if(a+1<width && saolei_able[a + 1][b] != -1) 
	        saolei_able[a + 1][b ] += 1;
	    if(a+1<width && b+1<height && saolei_able[a +1 ][b + 1] != -1)
	        saolei_able[a+1][b +1] += 1;
}
void blank_number(int a,int b){
	    if(a - 1 >= 0 && b - 1 >= 0)
	        if(saolei_enable[a-1][b-1]=='*'){
	            saolei_enable[a-1][b-1]=saolei_able[a-1][b-1]+48;
	            leave_number++;
	            if(saolei_able[a-1][b-1]==0)
	                blank_number(a-1,b-1);
	        }
	    if (a-1>=0)
	        if(saolei_enable[a-1][b]=='*'){
	            saolei_enable[a-1][b]=saolei_able[a-1][b]+48;
	            leave_number++;
	            if(saolei_able[a-1][b]==0)
	                blank_number(a-1,b);
	        }
	    if(a-1>=0 && b+1<height)
	        if(saolei_enable[a-1][b+1]=='*'){
	            saolei_enable[a-1][b+1]=saolei_able[a-1][b+1]+48;
	            leave_number++;
	            if(saolei_able[a-1][b+1]==0)
	                blank_number(a - 1, b+1);
	        }
	    if(b-1>=0)
	        if(saolei_enable[a][b - 1]=='*'){
	            saolei_enable[a][b - 1] = saolei_able[a][b - 1]+48;
	            leave_number++;
	            if(saolei_able[a][b - 1]==0)
	                blank_number(a, b - 1);
	        }
	    if (b+1<height)
	        if(saolei_enable[a][b + 1]=='*'){
	            saolei_enable[a][b + 1] = saolei_able[a][b + 1]+48;
	            leave_number++;
	            if(saolei_able[a][b + 1]==0)
	                blank_number(a,b+1);
	        }
	    if(a+1<width && b-1>=0)
	        if(saolei_enable[a + 1][b - 1]=='*'){
	            saolei_enable[a + 1][b - 1] = saolei_able[a + 1][b - 1]+48;
	            leave_number++;
	            if(saolei_able[a + 1][b - 1]==0)
	                blank_number(a+1,b-1);
	        }
	    if(a+1<width)
	        if(saolei_enable[a + 1][b]=='*'){
	            saolei_enable[a + 1][b] = saolei_able[a + 1][b]+48;
	            leave_number++;
	            if(saolei_able[a + 1][b]==0)
	                blank_number(a+1,b);
	        }
	    if(a+1<width && b+1<height)
	        if(saolei_enable[a + 1][b + 1]=='*'){
	            saolei_enable[a + 1][b + 1] = saolei_able[a + 1][b + 1]+48;
	            leave_number++;
	            if(saolei_able[a + 1][b + 1]==0)
	                blank_number(a+1,b+1);
	        }
}
void init_saolei(){
	for(int i=0;i<width;i++){
		for(int j=0;j<height;j++){
			saolei_enable[i][j]='*';
		}
	}
}
void read_rank(){
	FILE *fread;
	char rank[30];
	int index=0;
	fread=fopen("d:/rank.txt","r");
	if(fread!=NULL){
		while(fgets(rank,30,fread)!=NULL){
			printf("%s\n",rank);
			index++;
		}
	}if(index==0){
		printf("时间\t昵称\t成绩\n\n");
	}
	fclose(fread);
	printf("\n任意按键返回菜单...");
	getch();
}
int* printCurrentTime()
{
	int *date;
	date=(int *)malloc(sizeof(int)*6);
	time_t tt = time(NULL);//这句返回的只是一个时间cuo
	tm* t = localtime(&tt);
	date[0]=t->tm_year + 1900;
	date[1]=t->tm_mon+1;
	date[2]=t->tm_mday;
	date[3]=t->tm_hour;
	date[4]=t->tm_min;
	date[5]=t->tm_sec;
	return date;
}
void write_rank(const char* name,int time){
	FILE *fwirte,*fread;
	char rank[11][30];
	char delims[]="\t";
	char *spilt=NULL;
	
	ranks_str rank_str[10];
	fread=fopen("d:/rank.txt","r");
	int index=0;
	if(fread!=NULL){
		while(fgets(rank[index],30,fread)!=NULL){
			spilt=strtok(rank[index],delims);
			rank_str[index].gtime=spilt;
			spilt = strtok(NULL,delims);
			rank_str[index].name=spilt;
			spilt = strtok(NULL,delims);
			rank_str[index].ctime=spilt;
			index++;
		}	
	}
	fwirte=fopen("d:/rank.txt","w+");
	int *date;
	char record[30];
	if(fread==NULL ||index==0){
		fputs("时间\t昵称\t成绩",fwirte);
		date=printCurrentTime();
		fprintf(fwirte,"%d-%02d-%02d %02d:%02d:%02d\t%s\t%d",date[0],date[1],date[2],date[3],date[4],date[5],name,time);
	}else{
		for(int i=0;i<index;i++){
			if(time<atoi(rank_str[i].ctime)){
				for(int j=0;j<index;j++){
					if(j==i){
						date=printCurrentTime();
						fprintf(fwirte,"%d-%02d-%02d %02d:%02d:%02d\t%s\t%d\n",date[0],date[1],date[2],date[3],date[4],date[5],name,time);	
					}
					fprintf(fwirte,"%s\t%s\t%s",rank_str[j].gtime,rank_str[j].name,rank_str[j].ctime);
					if(j>=9){
						break;
					}
				}
				break;
			}
		}
	}
	fclose(fread);
	fclose(fwirte);
}

void setting_game(){
	system("cls");
	printf("***********************************************\n\n");
	printf("  1.修改地雷数量(10-100)\n");
	printf("  2.修改地图大小(长宽最大不超过20,最小不低于5)\n"); 
	printf("  3.返回菜单\n\n"); 
	printf("***********************************************\n\n");
	int n;
	printf("输入操作数:");
	scanf("%d",&n);
	switch (n) {
		case 1:
			printf("地雷数量:");
			scanf("%d",&dilei_qty);
			while(10>dilei_qty ||dilei_qty>100 ||dilei_qty>=width*height){
				printf("重新输入地雷数量:");
				scanf("%d",&dilei_qty);
			}
			break;
		case 2:
			printf("地图大小(长和宽):");
			scanf("%d %d",&width,&height);
			while(width<10 || height<10||width>100||height>100||dilei_qty>=width*height){
				printf("重新输入地图大小(长和宽):");
				scanf("%d %d",&width,&height);
			}
			break;
		default:
			break;
	}
}

void refresh_window(){
//	gotoxy(10,10);
	system("cls");
	
	printf("\n");
	printf("  ");
	for(int i=0;i<height;i++){
		printf("%2d",i);
	}
	printf("\n");
	for(int i=0;i<width;i++){
		printf("%2d",i);
		for(int j=0;j<height;j++){
			printf("%2c",saolei_enable[i][j]);
		}printf("\n");
	}
}
void* times(void *args){
	HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_SCREEN_BUFFER_INFO pt;
	 
	GetConsoleScreenBufferInfo(hout,&pt);
	gotoxy(0,0);
	gotoxy(pt.dwCursorPosition.X,pt.dwCursorPosition.Y);
	
	while(1){
		GetConsoleScreenBufferInfo(hout,&pt);
		gotoxy(0,0);
		printf("计时:%d",grade++);
		gotoxy(pt.dwCursorPosition.X,pt.dwCursorPosition.Y);
		if(game==1){
			break;
		}
		Sleep(1000);
	}
	pthread_exit(NULL);
	return NULL;
}

void start_game(){
	int index=0,row,column;
	init_saolei();
	while(index<dilei_qty){
		row=rand()%width;
		column=rand()%height;
		if(saolei_able[row][column]!=-1){
			saolei_able[row][column]=-1;
			index++;
			dilei_number(row,column);
		}
	}
	pthread_t tids[NUM_THREADS];
	for( int i = 0; i < NUM_THREADS; ++i )
	    {
	        int ret = pthread_create( &tids[i], NULL, times, NULL ); //参数:创建的线程id,线程参数,线程运行函数的起始地址,运行函数的参数
	    }
//	pthread_exit(NULL);
	int a,b,n;
	while(1){
		refresh_window();
		scanf("%d %d",&a,&b);
		while(a<0 || b<0 || a>=width|| b>=height || saolei_enable[a][b]!='*'){
			scanf("%d %d",&a,&b);
		}
		leave_number++;
		if(saolei_able[a][b]!=-1)
			saolei_enable[a][b]=saolei_able[a][b]+48;
		else
			saolei_enable[a][b]=35;
		if(saolei_able[a][b]==0){
			blank_number(a,b);
		} 
		if(saolei_able[a][b]==-1){
			refresh_window();
			char name[10];
			printf("You Lose!\n");
			printf("Game Over!\n");
			printf("1.返回菜单\t2.退出游戏\n");
			game=1;
			scanf("%d",&n);
			if(n==1){
				game=0;
				grade=0;
			}
			break;
		}
		if(leave_number==width*height-dilei_qty){
			char name[10];
			printf("Yow Win!\n");
			game=1;
			printf("输入您的昵称:");
			scanf("%s",&name);
			write_rank(name,grade-1);
			printf("1.返回菜单\t2.退出游戏\n");
			scanf("%d",&n);
			if(n==1){
				grade=0;
				game=0;
			}
			break;
		}
	} 
}
void menu(){
	
	system("cls");
	printf("************菜单************\n\n");
	printf("         1.开始游戏\n");
	printf("         2.游戏排名\n");
	printf("         3.游戏设置\n");
	printf("         4.退出游戏\n\n");
	printf("****************************\n\n");
	int n;
	printf("菜单操作:");
	scanf("%d",&n);
	switch(n){
		case 1:
			start_game();
//			system("cls");
			break;
		case 2:
			system("cls");
			read_rank();
			break;
		case 3:
			setting_game();
			break;
		case 4:
			k=0;
			system("cls");
			printf("game over!");
			break;
		default:
			menu();
			break;
	}
}
int main() {
	while(k){
		menu();	
	}
	system("pause");
	return 0;
}
  • 7
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
C语言扫雷游戏排行榜是一个用于记录玩家在扫雷游戏中的得分和排名的榜单。在C语言中,我们可以使用数组和结构体来实现这个排行榜。 首先,我们可以创建一个结构体来表示每个玩家的信息,如玩家的姓名和得分。结构体的定义可以像这样: ``` struct Player { char name[20]; int score; }; ``` 然后,我们创建一个数组来存储多个玩家的信息,数组的大小可以根据需要进行调整。例如: ``` struct Player leaderboard[10]; ``` 接下来,我们可以编写函数来实现对排行榜的操作,如添加玩家、更新得分和显示排行榜等。 添加玩家的函数可以接受玩家的姓名和得分,并将其添加到排行榜中。例如: ``` void addPlayer(char name[20], int score) { // 找到排行榜中得分低于当前得分的位置,并将其后的玩家信息依次后移一位 // 将当前玩家信息插入到空出的位置 } ``` 更新得分的函数可以接受玩家的姓名和新得分,并根据姓名找到对应的玩家并更新其得分。例如: ``` void updateScore(char name[20], int newScore) { // 根据姓名找到对应的玩家,并更新其得分 } ``` 最后,我们可以编写显示排行榜的函数,按照得分从高到低的顺序显示玩家信息。例如: ``` void showLeaderboard() { // 对排行榜中的玩家根据得分进行排序,并输出玩家信息 } ``` 以上是用C语言实现扫雷游戏排行榜的基本思路,具体的实现细节可以根据实际需求进行调整和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值