这个是上学期期末的时候的大作业,纯C语言,中间有很多的函数就是为了好看,瞎放上去的,实际上用不了这么多的代码段。水平有限,多多包容。
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
#include<conio.h> //getch
#include<string.h>
#define SIZE 4
typedef struct intormation{
char username[100];//用户名
char cryptography[100];//密码
char name[100];//用户的真实姓名
char sex;//用户的性别
long int phone;//用户的号码
}users;
int high=0;
int score=0;
void help(int a[][SIZE]);
void begin(int a[][SIZE]);
void savescore(int score){
FILE*fp;
fp=fopen("tscore.txt","w");
if(!fp){
printf("分数存入失败\n");
return ;
}
fprintf(fp,"%d",score);
fclose(fp);
}
int loadscore(){
FILE*fp;
int a;
fp=fopen("tscore.txt","r");//以只读的形式打开文件,
if(fp==NULL){
printf("ERROR,分数读取失败");
return 0;
}
fscanf(fp,"%d",&a);//从历史记录中读出来最高分
fclose(fp);
return a;
}
void loadgame(int (*a)[SIZE]){
FILE*fp;
int i,j;
fp=fopen("tgame.txt","r");
if(fp==NULL){
printf("ERROR!内存读取失败");
return;
}
for(i=0;i<SIZE;i++){
for(j=0;j<SIZE;j++){
fscanf(fp,"%d",&a[i][j]);
}
}
fclose(fp);
}
void search(){
FILE*fp;
users a;
int p=0;
fp=fopen("user.txt","r");
fread(&a,sizeof(users),1,fp);
for(p=1;!feof(fp);p++){
printf("第%d位: %s\n",p,a.username );
fread(&a,sizeof(users),1,fp);
}
printf("以上就是全部啦!\n");
fclose(fp);
}
void begin(int (*a)[SIZE]){
system("CLS");
char n;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);
printf("Welcome to:");
printf("2048\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),3);
printf("菜单:\n");
printf("1:新游戏\n");
printf("2:继续游戏\n");
printf("3:历史最高分:%d\n",high);
printf("4:帮助\n");
printf("5:查看全球用户\n");
printf("\n");
fflush(stdin);
do{
printf("请键入你想要的操作的对应数字\n");
scanf("%c",&n);
fflush(stdin);
}while(n!='1'&&n!='2'&&n!='3'&&n!='4'&&n!='5');
switch(n){
case '1':break;
case '2':loadgame(a);break;
case '4':help(a);break;
case '5':search();break;
}
}
void help(int (*a)[SIZE]){
system("CLS");
int n=0;
printf("帮助界面\n");
printf("1:操作说明:\n");
printf("\t\t本款游戏以方向键来代表上下左右的移动\n"
"同时,用户也可以用WASD来分别代表上左下右\n");
printf("2:游戏规则\n");
printf("\t\t用户通过键入上下左右\n"
"来控制数字在该方向上的移动,移动的范围不局限于一格,\n"
"可以多格移动,遇到数字相同的就相加,以最终加出2048为胜利\n") ;
printf("3:游戏结束的计算:\n");
printf("\t\t如果方格内输满了数\n"
"并且方格中没有相邻的可以进行相加的项,那么就视为游戏失败\n");
printf("分数的计算:\n");
printf("\t\t按照当前表格内的最大的数来计分\n");
printf(" ->按下1返回主列表\n");
do{
scanf("%d",&n);
}while(n!=1);
begin(a);
}
int check(int (*a)[SIZE]){
int i,j,m=0,t=0;
//检查是否所有的格子都被填满
for(i=0;i<SIZE;i++){
for(j=0;j<SIZE;j++){
if(*(*(a+i)+j)==0)
m=1;
}
}
if(m==1)
return 1;
else{
//检查同一行是否还有可加项
for(i=0;i<SIZE;i++){
for(j=0;j<SIZE-1;j++){
if(*(*(a+i)+j)==*(*(a+i)+j+1))
t=1;
}
}
//检查同一列是否还有可加项
for(j=0;j<SIZE;j++){
for(i=0;i<SIZE-1;i++){
if(*(*(a+i)+j)==*(*(a+i+1)+j))
t=1;
}
}
if(t==1){
return 1;
}
}
return 0;
}
void print(int (*a)[SIZE]){
int i,j;
system("CLS");
//输出打印游戏界面
printf("\n\n");
printf("\n\n");
printf("\n\n");
printf("\n\n");
printf("\t\t\t\t\tGame: 2048 score:%5d high score:%5d\n",score,high);
printf("\t\t\t\t\t------------------------------------------------------------");
printf("\n\n");
printf("\t\t\t\t\t\t---------------------------------\n");
// printf("\t|");
for(i=0;i<SIZE;i++){
printf("\t\t\t\t\t\t|");
for(j=0;j<SIZE;j++){
if(*(*(a+i)+j)==0)
printf(" |");
else
printf("%7d|",*(*(a+i)+j));
}
printf("\n");
printf("\t\t\t\t\t\t---------------------------------\n");
}
printf("\n");
printf("\n");
printf("\t\t\t\t\t\t-----------------------------------------------------------\n");
printf("\t\t\t[W]:UP\t[S]:DOWN\t[A]:LEFT\t[D]:RIGHT\t[1]:NEXT\t[2]:SAVE AND QUIT\n");
}
int SUMscore(int (*a)[SIZE]){
int highest=0;
int i,j;
for(i=0;i<SIZE;i++){
for(j=0;j<SIZE;j++){
if(*(*(a+i)+j)>highest)
highest=*(*(a+i)+j);
}
}
return highest;
}
void product(int (*a)[SIZE]){
int i,j,t,w;
//判断是否还有为0的点,防止函数持续产生,无法终止 ***
for(i=0;i<SIZE;i++){
for(j=0;j<SIZE;j++){
if(*(*(a+i)+j)==0)
w=0;
}
}
if(w==0){
do{
i=rand()%SIZE;
j=rand()%SIZE;
}while(*(*(a+i)+j)!=0);
t=rand()%2;
if(t==1)
*(*(a+i)+j)=2;
else if(t==0)
*(*(a+i)+j)=4;
}
}
void saveGame(int (*a)[SIZE]){
FILE*fp;
int i,j;
fp=fopen("tgame.txt","w");
if(!fp){
printf("ERROR!读取内存失败\n");
return ;
}
for(i=0;i<SIZE;i++){
for(j=0;j<SIZE;j++){
fprintf(fp,"%d\n",a[i][j]);//文件读取的时候注意
}
}
fclose(fp);
}
void left(int (*a)[SIZE]){
//为水平向左移
int i,j,k;
for(i=0;i<SIZE;i++) {
for(k=1;k<=SIZE-1;k++){//通过数学推演得出,至少要令其循环3次
for(j=1;j<SIZE;j++){
if(*(*(a+i)+j)!=0){
if(*(*(a+i)+j-1)==0){
*(*(a+i)+j-1)=*(*(a+i)+j);
*(*(a+i)+j)=0;
}
}
}
}
}
//检查是否有相同的项,此时只在乎水平方向上的
for(i=0;i<SIZE;i++){
for(j=0;j<SIZE-1;j++){
if(*(*(a+i)+j)!=0&&*(*(a+i)+j)==*(*(a+i)+j+1)){
*(*(a+i)+j)=*(*(a+i)+j)*2;
*(*(a+i)+j+1)=0;
}
}
}
for(i=0;i<SIZE;i++) {
for(k=1;k<=SIZE-1;k++){//通过数学推演得出,至少要令其循环3次
for(j=1;j<SIZE;j++){
if(*(*(a+i)+j)!=0){
if(*(*(a+i)+j-1)==0){
*(*(a+i)+j-1)=*(*(a+i)+j);
*(*(a+i)+j)=0;
}
}
}
}
}
}
void down(int (*a)[SIZE]){
//向下移动,此时则应该是以列为基准
int i,j,k;
for(j=0;j<SIZE;j++){
for(k=1;k<=SIZE-1;k++){
for(i=0;i<SIZE-1;i++){
if(*(*(a+i)+j)!=0){
if(*(*(a+i+1)+j)==0){
*(*(a+i+1)+j)=*(*(a+i)+j);
*(*(a+i)+j)=0;
}
}
}
}
}
//检查是否有相同项
for(j=0;j<SIZE;j++){
for(i=SIZE-1;i>0;i--){
if(*(*(a+i)+j)!=0&&*(*(a+i-1)+j)==*(*(a+i)+j)){
*(*(a+i)+j)*=2;
*(*(a+i-1)+j)=0;
}
}
}
//再次向下移
for(j=0;j<SIZE;j++){
for(k=1;k<=SIZE-1;k++){
for(i=0;i<SIZE-1;i++){
if(*(*(a+i)+j)!=0){
if(*(*(a+i+1)+j)==0){
*(*(a+i+1)+j)=*(*(a+i)+j);
*(*(a+i)+j)=0;
}
}
}
}
}
}
void up(int (*a)[SIZE]){
int i,j,k;
for(j=0;j<SIZE;j++){
for(k=1;k<=SIZE-1;k++){
for(i=1;i<SIZE;i++){
if(*(*(a+i)+j)!=0){
if(*(*(a+i-1)+j)==0){
*(*(a+i-1)+j)=*(*(a+i)+j);
*(*(a+i)+j)=0;
}
}
}
}
}
//检查是否有相同项
for(j=0;j<SIZE;j++){
for(i=0;i<SIZE-1;i++){
if(*(*(a+i)+j)!=0&&*(*(a+i)+j)==*(*(a+i+1)+j)){
*(*(a+i)+j)*=2;
*(*(a+i+1)+j)=0;
}
}
}
//再次向上移
for(j=0;j<SIZE;j++){
for(k=1;k<=SIZE-1;k++){
for(i=1;i<SIZE;i++){
if(*(*(a+i)+j)!=0){
if(*(*(a+i-1)+j)==0){
*(*(a+i-1)+j)=*(*(a+i)+j);
*(*(a+i)+j)=0;
}
}
}
}
}
}
void right(int (*a)[SIZE]){
int i,j,k;
for(i=0;i<SIZE;i++){
for(k=1;k<=SIZE-1;k++){
for(j=0;j<SIZE-1;j++){
if(*(*(a+i)+j)!=0){
if(*(*(a+i)+j+1)==0){
*(*(a+i)+j+1)=*(*(a+i)+j);
*(*(a+i)+j)=0;
}
}
}
}
}
//检查是否有相同项
for(i=0;i<SIZE;i++){
for(j=SIZE-1;j>0;j--){
if(*(*(a+i)+j)!=0&&*(*(a+i)+j)==*(*(a+i)+j-1)){
*(*(a+i)+j)*=2;
*(*(a+i)+j-1)=0;
}
}
}
//再次右移
for(i=0;i<SIZE;i++){
for(k=1;k<=SIZE-1;k++){
for(j=0;j<SIZE-1;j++){
if(*(*(a+i)+j)!=0){
if(*(*(a+i)+j+1)==0){
*(*(a+i)+j+1)=*(*(a+i)+j);
*(*(a+i)+j)=0;
}
}
}
}
}
}
void win(int (*a)[SIZE]){
int i,j;
for(i=0;i<SIZE;i++){
for(j=0;j<SIZE;j++){
if(a[i][j]==2048){
savescore(score);
system("CLS");
printf("Congratulations!!!\n");
printf("You have winned the game!\n");
printf("本局游戏分数为%d,历史最高分为%d\n",score,high);
score=0;
savescore(score);
exit(0);
}
}
}
}
//找回密码
void find(users a){
users c;
char t;
system("CLS");
printf("\n\n\t\t\t欢迎来到找回密码界面\n\n");
printf("请输入你的姓名\n");
scanf("%s",c.name );
fflush(stdin);
if(strcmp(c.name ,a.name )==0){
printf("请输入你的性别\n");
c.sex =getchar();
fflush(stdin);
if(c.sex ==a.sex ){
printf("请输入你的号码\n");
scanf("%d",&c.phone );
if(c.phone ==a.phone){
printf("您的密码是:\n");
printf("\t\t\t%s\n",a.cryptography );
while(1){
fflush(stdin);
printf("按1返回登录界面\n");
t=getchar();
if(t=='1'){
load();
break;
}
}
}
else{
printf("号码输入错误,请重新输入\n");
Sleep(500);
find(a);
}
}
else{
printf("性别输入错误,请重新输入\n");
find(a);
}
}
else{
printf("姓名输入错误,请重新输入\n");
find(a);
}
}
//注册一个账号
void get(){
FILE*fp;
users a,b;
char attempt[100];
system("cls");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),1);
printf("\n\n\n\n\t\t\t\t\t欢迎来到注册界面\n");
Sleep(500);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),2);
printf("\t\t\t\t请输入你要注册的用户名,用户名不支持空白符\n");
scanf("%s",a.username );
fflush(stdin);
fp=fopen("user.txt","a+");
fread(&b,sizeof(users),1,fp);//从定义的用户名库中读取一个用户名
//比较注册时输入的用户名与实际的用户名是否相同
while(1){
if(strcmp(a.username ,b.username )==0){
printf("\t\t\t\t用户名已存在,请再输入其他用户名\n");
Sleep(500);
fclose(fp);
fflush(stdin);
get();
return;
}
else{
if(!feof(fp))
fread(&b,sizeof(users),1,fp);
else{
printf("\t\t\t\t用户名创建成功\n");
break;
}
}
}
//fclose(fp);
//fp=fopen("user.txt","a");
while(1){
printf("\t\t\t\t请输入密码\n");
scanf("%s",a.cryptography );
printf("\t\t\t\t请再次输入密码\n");
scanf("%s",attempt);
if(strcmp(attempt,a.cryptography )==0){
printf("\t\t\t\t输入密码成功\n");
break;
}
else
printf("\t\t\t\t两次密码不相同,请再次输入密码\n");
}
printf("\t\t\t\t请输入您的姓名\n");
scanf("%s",a.name );
fflush(stdin);
while(1){
printf("\t\t\t\t请输入您的性别,以m代表男性,f代表女性\n");
scanf("%c",&a.sex );
fflush(stdin);
if(a.sex =='f'||a.sex =='m')
break;
}
printf("\t\t\t\t请输入你的电话号码\n");
scanf("%d",&a.phone );
printf("\t\t\t\t账号创建成功\n");
Sleep(500);
fwrite(&a,sizeof(users),1,fp);
fclose(fp);
}
void load(){
FILE*fp;
users a,b;
int i=0,m,n;
fp=fopen("user.txt","r");
if(feof(fp)) {
printf("\t\t\t\t该用户名不存在,您将返回注册界面\n");
get();
return;
}
fread(&b,sizeof(users),1,fp);
system("cls");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),2);
printf("\n\n\n\n\t\t\t\t\t请输入你的账号\n");
scanf("%s",a.username );
fflush(stdin);
while(1){
if(strcmp(a.username,b.username )==0)
break;
else{
if(!feof(fp))//如果文件没有读到结尾处***
fread(&b,sizeof(users),1,fp);
else{
do{
printf("\t\t\t\t该用户名不存在,请选择注册一个新的账号或者重新输入\n");
printf("\t\t\t\t注册新账号请输入1\n");
printf("\t\t\t\t重新输入请按2\n");
scanf("%d",&n);
fflush(stdin);
}while(n!=1&&n!=2);
if(n==1){
fclose(fp);
get();
load();
return;
}
else if(n==2){
Sleep(500);
fclose(fp);
load();
return;
}
}
}
}
while(i<3){
printf("\t\t\t\t请输入密码\n");
scanf("%s",a.cryptography );
i++;
if(strcmp(a.cryptography ,b.cryptography )==0){
fclose(fp);
system("CLS");
printf("\t\t\t\t登录成功\n");
printf("\t\t\t\t欢迎来到2048小游戏\n");
system("CLS");
return;
}
else{
fclose(fp);
printf("密码错误!\n");
do{
printf("请选择再次输入密码或找回密码\n");
printf("再次输入密码请按1,找回密码请按2\n");
scanf("%d",&m);
fflush(stdin);
}while(m!=1&&m!=2);
if(m==2){
find(b);
}
}
}
printf("密码输入错误!\n");
access();
}
void access(){
system("CLS");
char t;
do{
printf("新用户注册请按1\n");
printf("登录请按2\n");
fflush(stdin);
scanf("%c",&t);
fflush(stdin);
}while(t!='1'&&t!='2');
if(t=='1'){
get();
return;
}
else if(t=='2'){
load();
return;
}
// else
// access();//返回函数开头
}
void kaitou(){
int i;
printf("\n\n\n\n\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);
printf("\n\n\n\n\n\n\t\t\t\t\t\t\t欢迎来到2048!\n");
Sleep(500);
system("CLS");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),3);
printf("\n\n\n\n\n\n\t\t\t\t\t\t\t欢迎来到2048!\n");
Sleep(500);
system("CLS");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),2);
printf("\n\n\n\n\n\n\t\t\t\t\t\t\t欢迎来到2048!\n");
Sleep(500);
system("CLS");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),1);
printf("\n\n\n\n\n\n\t\t\t\t\t\t\t欢迎来到2048!\n");
system("CLS");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),1);
printf("\n\n\n\n\n\n\t\t\t\t本游戏本着做出一款高端的2048游戏原则\n");
Sleep(500);
system("CLS");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),2);
printf("\n\n\n\n\n\n\t\t\t\t现在\n");
Sleep(500);
system("CLS");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),3);
printf("\n\n\n\n\n\n\t\t\t\t开启你的奇妙之旅吧!\n");
for(i=1;i<=4;i++){
system("CLS");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),i);
printf(" * * * * * * *\n");
printf(" * * * * * * * *\n");
printf(" * * * * * * * * * * * * * * * *\n");
printf(" * * * * * *\n");
printf(" * * * * * *\n");
printf(" * * * * * * \n");
printf(" * * * * * * *\n");
printf(" * * * * * * * * * * * \n");
Sleep(200);
}
sleep(1);
}
int main(){
int t,i,j,num=0,o=0;
char c,h;
int a[SIZE][SIZE];
//打开界面
kaitou();
//用户登录注册系统
access();
//读取历史最高分记录
high=loadscore();
srand(time(NULL));//播撒随机数种子
start:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);//设置颜色
printf("欢迎来到2048小游戏:\n");
for(i=0;i<SIZE;i++){
for(j=0;j<SIZE;j++){
a[i][j]=0;
}
}//将框内的元素都定义为0,即赋初值操作
begin(a);//菜单
printf("请键入你想要哪种输入方式\n");
do{
fflush(stdin);
printf("如果你想要用字母盘上的,则输入1;如果你想要用方向键,则键入2\n");
scanf("%c",&h);
fflush(stdin);
}while(h!='1'&&h!='2');
product(a);
//进入游戏
do{
t=check(a);//返回1为未结束,返回0为结束
if(t==0){
if(score>high)
savescore(score);
system("CLS");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);
printf("\n\n\n\n\n\nTry again! I`m sure you will get better scores!\n");
Sleep(500);
system("CLS");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),1);
printf("\n\n\n\n\n\t\t\t本局得分为%d,历史最高分为%d\n",score,high);
Sleep(500);
system("CLS");
printf("\n\n\n\n\n\n\t\t\t\t是否要再来一次:\n");
printf("\t\t\t\t\t\t\t按下1表示再来一局,其余键表示结束游戏\n");
score=0;
fflush(stdin);
if(getchar()=='1'){
goto start;
}
else
exit(0);
}
if(o!=0){
num=SUMscore(a);
score+=num;
}
o=1;//防止第一次的分数被算入
product(a);//在表内产生一个随机数2或者4
if(score>high)
savescore(score);
high=loadscore();
print(a);//显示当前界面
//选择键盘输入方式
if(h=='2'){
getch();
switch(getch()){
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);
Sleep(500);
exit(0);
}
}
else if(h=='1'){
switch(getch()){
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);
Sleep(500);
exit(0);
}
}
win(a);
} while(1);
system("PAUSE");
return 0;
}