大一c语言实训2048小游戏

实训感言

第一次实训,啥也不知道,各种文档啥的做的挺累的,代码大概花了一天半搞完,然后测试修改,最终定稿,能力也确实得到了提高

组成

因为是小游戏嘛,用户体验感挺重要的,在网上自学了插入音乐,多线程等方面

  1. 精美的开始页面,然后有几个功能可供选择(继续游戏,新游戏,音乐选项等)
  2. 打印棋盘
  3. 移动合并函数
  4. 判断胜负函数
  5. 统分函数
  6. 游戏读取保存函数
  7. 游戏结束界面函数
  8. 音乐播放函数等
    这里我只列出了主要的函数

话不多说直接上源代码

因为要实现一些功能需要用到一些库,学校电脑的vc没有,我用的是自己下载的dev c++

#include<stdio.h>
#include<windows.h>   //颜色 清屏  
#include<conio.h>     //getch   
#include<stdlib.h>     //万能表头 
#include<time.h>      //随机数种子 
#include <math.h>     //多线程 
#include <pthread.h>  // 随机数种子
#include<mmsystem.h>  //音乐 
int score=0;
int high=0;
void kaitou(); 
int temp=1;
int temp2=0;
void saveScore()
{
	FILE *fp;//文件指针 
	fp=fopen("Score.txt","w");//‘w’以只写的方式打开,成功即指向那个地址 ,如果不存在自动新创,如存在即删掉原文件再写入 
	if(!fp)
	{
		printf("存储失败"); 
		return;
	}
	fprintf(fp,"%d",high);//赋值 
 	fclose(fp);//关闭 
}
int loadScore()
{
	FILE *fp;
	int a;
	fp=fopen("Score.txt","r");//‘r’只读 
	if(!fp)
	{
		printf("读取失败"); 
		return 0;
	}
	fscanf(fp,"%d",&a);//存储a 
 	fclose(fp);
 	return a;
 }
void saveGame(int a[4][4])
{
	FILE *fp;
	int i,j;
	fp=fopen("Game.txt","w");
	if(!fp)
	{
		printf("存储失败"); 
		return;
	}
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
		{
			fprintf(fp,"%d ",a[i][j]);
		}
 	fclose(fp);
}
void loadGame(int a[4][4])
{
	FILE *fp;
	int i,j;
	fp=fopen("Game.txt","r");
	if(!fp)
	{
		printf("存储失败"); 
		return;
	}
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
		{
			fscanf(fp,"%d",&a[i][j]);
		}
 	fclose(fp);
}
void bangzhu()
{
	system("CLS");
	int k;
		printf("                       游戏规则    \n");
	printf("\n");
	printf("               首先先将输入法改为英文\n");
	printf("\n");
	printf("               通过 W \n");
	printf("                   ASD   控制数字移动 \n");
	printf("\n");
	printf("               相邻的相同数字合并,分数增加\n");
	printf("\n");
	printf("               直至页面填满且无可合并数字游戏结束\n");
	printf("                                           (0)->返回\n");
	k=getch();
	if(k=='0') kaitou();
}
/* 生成随机数 函数定义 */
void shengcheng(int map[4][4])
{
	//初始化一个随机数种子
	//随机出来一个坐标
	int x = rand()%4;
	int y = rand()%4;
	//随机出来一个2或者4   cjh版权所有 
	int nNumber = rand()%2?2:4;
	do
	{
		//看看地图的这个位置是不是没有数字,如果没有数字,就生成成功,
		//否则还需要再生成
		if (map[x][y]==0)
		{
			map[x][y] = nNumber;
			break;
		}
		x = rand()%4;
		y = rand()%4;
	} while (1);
}

int tongfen(int a[4][4])
{
	int sum=0,j,i;
	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			if(a[i][j]>sum)
				sum=a[i][j];
	/*找每个格子的最大数字作为实时分*/
	return sum;
}
void menu(int a[4][4])
{
	if(high<score) high=score;
	int i,j;
	printf("\n");
	printf("\n");
	printf("\n");
	printf("\n");
	printf("\n");
	printf("                             GAME:2048     SCORE:%d      BEST:%d \n",score,high);
	printf("                         ------------------------------------------------\n");
	printf("\n");
	for(i=0;i<4;i++)
	{
		printf("                               -------------------------------------\n");
		printf("                               |");
		for(j=0;j<4;j++)
		{
			if(a[i][j]==0) printf("        |");
			else printf("  %4d  |",a[i][j]);
		}
		printf("\n");
	}
	printf("                               -------------------------------------\n");
	printf("\n");
	printf("                         ------------------------------------------------\n");
	printf("                          [W]:UP  [S]:DOWN  [A]:LEFT  [D]:REGHT  [1]:NEXT [2]:SAVE");
}


void up(int date[4][4])
{
	int i,j,n;//i为行,j为列, n 是移动的次数//
	for(n=0;n<3;n++) 	//移动三轮 
	{
		for(i=1;i<4;i++)		//全体向上移动 
		{
			for(j=0;j<4;j++)
			{
				if(date[i][j]!=0&&date[i-1][j]==0)
				{
					date[i-1][j]=date[i][j];
					date[i][j]=0;
				}
			}
		}
	}
	 //合并//
	for(i=0;i<3;i++)		
	{
		for(j=0;j<4;j++)
		{
			if(date[i][j]!=0&&date[i+1][j]==date[i][j])
			{
				date[i][j]=date[i][j]*2;
				date[i+1][j]=0;
			}
		}	
	}
	//再次上移//
	for(n=0;n<3;n++)	//移动三轮
	{
		for(i=1;i<4;i++)		//全体向上移动 
		{
			for(j=0;j<4;j++)
			{
				if(date[i][j]!=0&&date[i-1][j]==0)
				{
					date[i-1][j]=date[i][j];
					date[i][j]=0;
				}
			}
		}
	}
}
void down(int date[4][4])
{
	int i,j,n;//i为行,j为列, n 是移动的次数//
	for(n=0;n<3;n++) 	//移动三轮 
	{
		for(i=0;i<3;i++)		//全体向下移动 
		{
			for(j=0;j<4;j++)
			{
				if(date[i][j]!=0&&date[i+1][j]==0)
				{
					date[i+1][j]=date[i][j];
					date[i][j]=0;
				}
			}
		}
	}
	 //合并//
	for(i=3;i>0;i--)		 
	{
		for(j=0;j<4;j++)
		{
			if(date[i][j]!=0&&date[i-1][j]==date[i][j])
			{
				date[i][j]=date[i][j]*2;
				date[i-1][j]=0;
			}
		}	
	}
	//再次下移//
	for(n=0;n<3;n++) 	//移动三轮 
	{
		for(i=0;i<3;i++)		//全体向下移动 
		{
			for(j=0;j<4;j++)
			{
				if(date[i][j]!=0&&date[i+1][j]==0)
				{
					date[i+1][j]=date[i][j];
					date[i][j]=0;
				}
			}
		}
	}
}
void left(int date[4][4])
{
	int i,j,n;//i为行,j为列, n 是移动的次数//
	for(n=0;n<3;n++) 	//移动三轮 
	{
		for(i=0;i<4;i++)		//全体向左移动 
		{
			for(j=1;j<4;j++)
			{
				if(date[i][j]!=0&&date[i][j-1]==0)
				{
					date[i][j-1]=date[i][j];
					date[i][j]=0;
				}
			}
		}
	}
	 //合并//
	for(i=0;i<4;i++)		
	{
		for(j=0;j<3;j++)
		{
			if(date[i][j]!=0&&date[i][j+1]==date[i][j])
			{
				date[i][j]=date[i][j]*2;
				date[i][j+1]=0;
			}
		}	
	}
	//再次左移//
	for(n=0;n<3;n++) 	//移动三轮 
	{
		for(i=0;i<4;i++)		//全体向左移动 
		{
			for(j=1;j<4;j++)
			{
				if(date[i][j]!=0&&date[i][j-1]==0)
				{
					date[i][j-1]=date[i][j];
					date[i][j]=0;
				}
			}
		}
	}
}
void right(int date[4][4])
{
	int i,j,n;//i为行,j为列, n 是移动的次数//
	for(n=0;n<3;n++) 	//移动三轮 
	{
		for(i=0;i<4;i++)		//全体向右移动 
		{
			for(j=0;j<3;j++)
			{
				if(date[i][j]!=0&&date[i][j+1]==0)
				{
					date[i][j+1]=date[i][j];
					date[i][j]=0;
				}
			}
		}
	}
	 //合并//
	for(i=0;i<4;i++)		
	{
		for(j=3;j>0;j--)
		{
			if(date[i][j]!=0&&date[i][j-1]==date[i][j])
			{
				date[i][j]=date[i][j]*2;
				date[i][j-1]=0;
			}
		}	
	}
	//再次右移//
	for(n=0;n<3;n++) 	//移动三轮 
	{
		for(i=0;i<4;i++)		//全体向右移动 
		{
			for(j=0;j<3;j++)
			{
				if(date[i][j]!=0&&date[i][j+1]==0)
				{
					date[i][j+1]=date[i][j];
					date[i][j]=0;
				}
			}
		}
	}
}
void menuMusic()
{
	system("cls");
	printf("	  请选择你想选择的音乐\n"); 
	printf("	  1.时尚酷炫庆功酒		\n");
	printf(" 	  2.经典酸爽欢乐多		\n");
}
void kaitou(int a[4][4])
{
	system("CLS");
	int k;
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);
	printf("               welcome to  \n");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),1);
	printf("                 2048          \n");
	printf("               1.新游戏      \n");
	printf("               2.继续游戏      \n");
	printf("               3.历史最高:%d       \n",high);
	printf("               4.音乐设置\n");
	printf("               5.帮助\n");
	printf("       (w)上移  (s)下移  (a)左移  (d)右移   (0)返回\n");
	k=getch();
	if(k=='1') return;
	else if(k=='2') loadGame(a);
	else if(k=='5')bangzhu();
	else if(k=='4')
	{
		menuMusic();
		char choice;
		do
		{
			choice=getch();
		}while(choice!='1'&&choice!='2');//防止客人刁钻 
		temp2=1;
		temp=choice-'0';
		kaitou(a);
	} 
	else
	{printf("未开发");
	getch();
	kaitou(a);} 

}

void* music(void* arg);
int main()
{
	high=loadScore();
	srand(time(NULL));//生成随机数种子 
	pthread_t id; //创建一个线程id 
	pthread_create(&id, NULL, music, NULL);//生成music多线程 
	int a[4][4];
	char x;
	int y;
	int flag=0,i,j; 
	start:score=0;
	for(i=0;i<4;i++)//int不能重复定义 所以goto here 
		for(j=0;j<4;j++)
			a[i][j]=0;
	kaitou(a);
	while(1) 
	{	flag=0;
		score+=tongfen(a);//统分函数
		
		system("color 0f");
		shengcheng(a);//随机生成2/4
		jixu:
		system("CLS");
		menu(a);
		x=getch();
		switch(x)//移动函数
		{
		case 72:
		case 'w':up(a);break;
		case 80:
		case 's':down(a);break;
		case 75:
		case 'a':left(a);break;
		case 77:
		case 'd':right(a);break;
		case '2':saveGame(a);goto jixu;break;
		}
	//合并函数
		for(i=0;i<4;i++)
			for(j=0;j<4;j++)
				if(a[i][j]==0)
					flag=1;
		if(flag!=1)
			break;
	}
	saveScore();//分数存档 
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);
	printf("\n              game over!输入1重新开始!");
	y=getch();
	if(y=='1')
		goto start;
	return 0;
} 
void* music(void* arg)//百度教的 
{
	int t,t1=213,t2=218;//t1为歌曲的持续时间 
    mciSendString(TEXT("open 2.mp3 alias music"),0,0,0);//发送命令 
    while(1)
    {
    	if(temp2==1)
		{
			mciSendString(TEXT("close music"),0,0,0);
			if(temp==1) 
			{
				mciSendString(TEXT("open 1.mp3 alias music"),0,0,0);
				t=t1; 
			}
			if(temp==2) 
			{
				mciSendString(TEXT("open 2.mp3 alias music"),0,0,0);
				t=t2;
			}
			temp2=0;
		}
		mciSendString(TEXT("play music"),0,0,0);
		if(t==0) temp2=1; 
		Sleep(1000);//休息1s 
		t--;
	}
}

emmmmm
如果不能运行的话,可能是编译环境的问题
在这里插入图片描述点开工具
然后有个编译选项打开
在这里插入图片描述按理来说加上 -lwinmm就好了
记得空格啊
###用户体验
主要就是音乐
把音乐和生成的exe文件放在同一个文件夹
将你想要的音乐命名为1 2就okk了(或者改下代码也ok)

最后给大家看下游戏截图

游戏页面就这样挺简洁的然后有什么问题请各位指出
小弟只是刚接触c语言 的小萌新
寒假打算自学c++
谢谢各位支持!!!在这里插入代码片

发布了1 篇原创文章 · 获赞 1 · 访问量 23

猜你喜欢

转载自blog.csdn.net/weixin_45944993/article/details/104013003
今日推荐