实训感言
第一次实训,啥也不知道,各种文档啥的做的挺累的,代码大概花了一天半搞完,然后测试修改,最终定稿,能力也确实得到了提高
组成
因为是小游戏嘛,用户体验感挺重要的,在网上自学了插入音乐,多线程等方面
- 精美的开始页面,然后有几个功能可供选择(继续游戏,新游戏,音乐选项等)
- 打印棋盘
- 移动合并函数
- 判断胜负函数
- 统分函数
- 游戏读取保存函数
- 游戏结束界面函数
- 音乐播放函数等
这里我只列出了主要的函数
话不多说直接上源代码
因为要实现一些功能需要用到一些库,学校电脑的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++
谢谢各位支持!!!在这里插入代码片