/ Vijos / 讨论 / 游戏 /

2048

可保存进度的2048小游戏
附上exe文件:
链接: https://pan.baidu.com/s/1tY1DIA0Lq6QBPXcMFPXuAA 提取码: 4jyg
```c
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <math.h>
#include <string.h>
#define MAXL 24
#define MAXC 60
void init();
void highlight(int x);
void lowlight(int x);
void initgrid();
void gotoxy(int, int);
int option();
int up();
int down();
int left();
int right();
int alarm();
int check();
void choose();
void reset();
void color(int x);
void print();
void getdata();
void savedata();
void getrank();
void saverank();
void showrank();
int hl = 0;
time_t tim = 0;
int a[100000][4][4], cur = 0; //a[cur][i][j]
int map[70000];
int score[100000] = {0};
int rscore[20];
struct tm *rtime[20];
char lines[4][40] = {" 新游戏 ", " 继续游戏 ", " 本地排行 ", " 离开 "};
int main()
{
FILE *fp = fopen("D:\2048data.txt", "rb");
if (fp == NULL)
{
fp = fopen("D:\2048data.txt", "wb");
fprintf(fp, "0\n");
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
fprintf(fp, "0 ");
fprintf(fp, "\n");
}
}
fclose(fp);
fp = fopen("D:\2048rank.txt", "rb");
if (fp == NULL)
{
fp = fopen("D:\2048rank.txt", "wb");
for (int i = 0; i < 10; i++)
fprintf(fp, "0 0 0 0 0 0 0\n");
}
fclose(fp);
char c = 0;
int flag = 0;
srand(time(0));
for (int i = 1; i <= 16; i++)
{
map[1 << i] = (i - 1) % 6 + 1;
}
int ret = 0;
do
{
getrank();
if (flag)
initgrid();
else
{
if (ret != -1)
{
init();
A:
choose();
int x;
switch (hl)
{
case 0:
if (alarm())
goto A;
initgrid();
break;
case 1:
fp = fopen("D:\2048data.txt", "rb");
fscanf(fp, "%d", &x);
fclose(fp);
if (x == 0)
{
gotoxy(MAXC / 2 - 10, MAXL - 3);
printf("没有正在进行的游戏。");
gotoxy(1, MAXL + 1);
Sleep(1000);
gotoxy(MAXC / 2 - 10, MAXL - 3);
printf(" ");
gotoxy(1, MAXL + 1);
goto A;
}
initgrid();
getdata();
print();
break;
case 2:
showrank();
break;
case 3:
exit(0);
}
}
else
initgrid();
}
flag = 0;
if (hl < 2)
{
while ((ret = option()) == 0)
;
tim = time(NULL);
if (ret == -2)
savedata();
if (ret == 1)
{
if (score[cur] > rscore[0])
{
for (int i = 9; i > 0; i--)
{
rscore[i] = rscore[i - 1];
*rtime[i] = *rtime[i - 1];
}
rscore[0] = score[cur];
rtime[0] = localtime(&tim);
}
else
{
for (int i = 9; i > 0; i--)
{
if (rscore[i] < score[cur] && rscore[i - 1] >= score[cur])
{
for (int j = 9; j > i; j--)
{
rscore[j] = rscore[j - 1];
*rtime[j] = *rtime[j - 1];
}
rscore[i] = score[cur];
rtime[i] = localtime(&tim);
}
}
}
saverank();
reset();
gotoxy(4, MAXL - 3);
printf("你输了!");
gotoxy(4, MAXL - 2);
printf("再来一次? (y/n)");
while ((c = getch()) != 'N' && c != 'n' && c != 'Y' && c != 'y')
;
if (c == 'Y' || c == 'y')
flag = 1;
}
}
} while (1);
gotoxy(1, MAXL + 2);
return 0;
}
int alarm()
{
int x;
FILE *fp = fopen("D:\2048data.txt", "rb");
fscanf(fp, "%d", &x);
fclose(fp);
if (x)
{
int d = 20;
gotoxy(d, MAXL - 4);
printf("您有一个游戏尚未结束,");
gotoxy(d, MAXL - 3);
printf("这将导致现有游戏进度丢失。");
gotoxy(d, MAXL - 2);
printf("确定吗? (y/n)");
char c;
while ((c = getch()) != 'Y' && c != 'y' && c != 'N' && c != 'n')
;
gotoxy(d, MAXL - 4);
printf(" ");
gotoxy(d, MAXL - 3);
printf(" ");
gotoxy(d, MAXL - 2);
printf(" ");
gotoxy(1, MAXL + 1);
if (c == 'Y' || c == 'y')
return 0;
return 1;
}
else
return 0;
}
void choose()
{
int flag = 0;
int c;
while (!flag)
{
switch (c = getch())
{
case 10:
case 13:
flag = 1;
break;
case 224:
switch (getch())
{
case 72:
//printf("up");
lowlight(hl);
hl = (hl + 3) % 4;
highlight(hl);
break;
case 80:
//printf("down");
lowlight(hl);
hl = (hl + 1) % 4;
highlight(hl);
break;
}
break;
}
}
}
void highlight(int x)
{
gotoxy(MAXC / 2 - 10, 7 + 2 * x);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x70);
printf("%s", lines[x]);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x07);
gotoxy(1, MAXL + 1);
}
void lowlight(int x)
{
gotoxy(MAXC / 2 - 10, 7 + 2 * x);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x07);
printf("%s", lines[x]);
gotoxy(1, MAXL + 1);
}
void init()
{
system("cls");
system("title 快乐2048 By wxh");
gotoxy(1, 1);
for (int i = 0; i < MAXC; i++)
putchar('*');
for (int i = 2; i < MAXL; i++)
{
gotoxy(1, i);
printf("*");
gotoxy(MAXC, i);
printf("*");
}
gotoxy(1, MAXL);
for (int i = 0; i < MAXC; i++)
putchar('*');
gotoxy(MAXC / 2 - 9, 3);
printf("欢迎来到快乐2048!");
lowlight(0);
lowlight(1);
lowlight(2);
lowlight(3);
highlight(hl);
gotoxy(MAXC / 2 - 5, MAXL - 7);
printf("↑↓:选择");
gotoxy(MAXC / 2 - 5, MAXL - 6);
printf("Enter:确定");
gotoxy(1, MAXL + 1);
}
void initgrid()
{
cur = 0;
system("cls");
gotoxy(1, 1);
for (int i = 0; i < MAXC; i++)
putchar('*');
for (int i = 2; i < MAXL; i++)
{
gotoxy(1, i);
printf("*");
gotoxy(MAXC, i);
printf("*");
}
gotoxy(1, MAXL);
for (int i = 0; i < MAXC; i++)
putchar('*');
gotoxy(MAXC / 2 - 9, 3);
printf("欢迎来到快乐2048!");
gotoxy(4, 4);
printf("╔═══════╤═══════╤═══════╤═══════╗");
gotoxy(4, 5);
printf("║ │ │ │ ║");
gotoxy(4, 6);
printf("║ │ │ │ ║");
gotoxy(4, 7);
printf("║ │ │ │ ║");
gotoxy(4, 8);
printf("╟───────┼───────┼───────┼───────╢");
gotoxy(4, 9);
printf("║ │ │ │ ║");
gotoxy(4, 10);
printf("║ │ │ │ ║");
gotoxy(4, 11);
printf("║ │ │ │ ║");
gotoxy(4, 12);
printf("╟───────┼───────┼───────┼───────╢");
gotoxy(4, 13);
printf("║ │ │ │ ║");
gotoxy(4, 14);
printf("║ │ │ │ ║");
gotoxy(4, 15);
printf("║ │ │ │ ║");
gotoxy(4, 16);
printf("╟───────┼───────┼───────┼───────╢");
gotoxy(4, 17);
printf("║ │ │ │ ║");
gotoxy(4, 18);
printf("║ │ │ │ ║");
gotoxy(4, 19);
printf("║ │ │ │ ║");
gotoxy(4, 20);
printf("╚═══════╧═══════╧═══════╧═══════╝");
gotoxy(43, 5);
printf("得分: 0");
gotoxy(43, 10);
printf("Q/q:撤销");
gotoxy(43, 13);
printf("R/r:重新开始");
gotoxy(43, 16);
printf("E/e:返回");
int x0 = rand() % 4, y0 = rand() % 4;
memset(a, 0, sizeof(a));
a[cur = 0][x0][y0] = 2;
print();
gotoxy(1, MAXL + 1);
}
void gotoxy(int x, int y)
{
COORD c;
c.X = x - 1;
c.Y = y - 1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
int option()
{
char c;
switch (getch())
{
case 224:
switch (getch())
{
case 72:
//printf("up");
if (up())
return 1;
break;
case 80:
//printf("down");
if (down())
return 1;
break;
case 75:
//printf("left");
if (left())
return 1;
break;
case 77:
//printf("right");
if (right())
return 1;
break;
}
break;
case 'Q':
case 'q':
if (cur > 0)
{
cur--;
}
break;
case 'R':
case 'r':
gotoxy(4, MAXL - 2);
printf("真的要重新开始吗? (y/n)");
gotoxy(1, MAXL + 1);
while ((c = getch()) != 'Y' && c != 'y' && c != 'N' && c != 'n')
;
if (c == 'Y' || c == 'y')
return -1;
else
{
gotoxy(4, MAXL - 2);
printf(" ");
gotoxy(1, MAXL + 1);
}
break;
case 'E':
case 'e':
gotoxy(4, MAXL - 2);
printf("真的要返回吗?进度将自动保存 (y/n)");
gotoxy(1, MAXL + 1);
while ((c = getch()) != 'Y' && c != 'y' && c != 'N' && c != 'n')
;
if (c == 'Y' || c == 'y')
return -2;
else
{
gotoxy(4, MAXL - 2);
printf(" ");
gotoxy(1, MAXL + 1);
}
break;
}
print();
return 0;
}
int up()
{
cur++;
score[cur] = score[cur - 1];
memcpy(a[cur], a[cur - 1], sizeof(a[cur]));
int rem[4] = {0};
int moveable = 0;
for (int i = 0; i < 4; i++)
{
int tmp[10] = {0};
int cnt = -1;
for (int j = 0; j < 4; j++)
if (a[cur][i][j])
tmp[++cnt] = a[cur][i][j];
for (int j = 0; j < cnt; j++)
if (tmp[j] == tmp[j + 1])
{
tmp[j] *= 2;
score[cur] += tmp[j];
tmp[j + 1] = 0;
}
for (int j = 0; j < 4; j++)
if (a[cur][i][j] != tmp[j])
moveable = 1;
for (int j = 0; j < 4; j++)
a[cur][i][j] = 0;
int k = 0;
for (int j = 0; j <= cnt; j++)
{
if (tmp[j])
a[cur][i][k++] = tmp[j];
}
rem[i] = 4 - k;
}
if (!moveable)
{
cur--;
if (check())
return 0;
else
return 1;
}
int M = rem[0] + rem[1] + rem[2] + rem[3];
if (M == 0 && !check())
return 1;
if (M == 0)
return 0;
int pos = rand() % M + 1;
int k = 0;
for (int i = 0; i < 4; i++)
{
int flag = 0;
for (int j = 0; j < 4; j++)
{
if (a[cur][i][j] == 0)
k++;
if (k == pos)
{
flag = 1;
a[cur][i][j] = 2;
break;
}
}
if (flag)
break;
}
return 0;
}
int down()
{
cur++;
score[cur] = score[cur - 1];
memcpy(a[cur], a[cur - 1], sizeof(a[cur]));
int rem[4] = {0};
int moveable = 0;
for (int i = 0; i < 4; i++)
{
int tmp[10] = {0};
int cnt = 4;
for (int j = 3; j >= 0; j--)
if (a[cur][i][j])
tmp[--cnt] = a[cur][i][j];
for (int j = 3; j > cnt; j--)
if (tmp[j] == tmp[j - 1])
{
tmp[j] *= 2;
score[cur] += tmp[j];
tmp[j - 1] = 0;
}
for (int j = 0; j < 4; j++)
if (a[cur][i][j] != tmp[j])
moveable = 1;
for (int j = 0; j < 4; j++)
a[cur][i][j] = 0;
int k = 3;
for (int j = 3; j >= cnt; j--)
{
if (tmp[j])
a[cur][i][k--] = tmp[j];
}
rem[i] = k + 1;
}
if (!moveable)
{
cur--;
if (check())
return 0;
else
return 1;
}
int M = rem[0] + rem[1] + rem[2] + rem[3];
if (M == 0 && !check())
return 1;
if (M == 0)
return 0;
int pos = rand() % M + 1;
int k = 0;
for (int i = 0; i < 4; i++)
{
int flag = 0;
for (int j = 3; j >= 0; j--)
{
if (a[cur][i][j] == 0)
k++;
if (k == pos)
{
flag = 1;
a[cur][i][j] = 2;
break;
}
}
if (flag)
break;
}
return 0;
}
int left()
{
cur++;
score[cur] = score[cur - 1];
memcpy(a[cur], a[cur - 1], sizeof(a[cur]));
int rem[4] = {0};
int moveable = 0;
for (int j = 0; j < 4; j++)
{
int tmp[10] = {0};
int cnt = -1;
for (int i = 0; i < 4; i++)
if (a[cur][i][j])
tmp[++cnt] = a[cur][i][j];
for (int i = 0; i < cnt; i++)
if (tmp[i] == tmp[i + 1])
{
tmp[i] *= 2;
score[cur] += tmp[i];
tmp[i + 1] = 0;
}
for (int i = 0; i < 4; i++)
if (a[cur][i][j] != tmp[i])
moveable = 1;
for (int i = 0; i < 4; i++)
a[cur][i][j] = 0;
int k = 0;
for (int i = 0; i <= cnt; i++)
{
if (tmp[i])
a[cur][k++][j] = tmp[i];
}
rem[j] = 4 - k;
}
if (!moveable)
{
cur--;
if (check())
return 0;
else
return 1;
}
int M = rem[0] + rem[1] + rem[2] + rem[3];
if (M == 0 && !check())
return 1;
if (M == 0)
return 0;
int pos = rand() % M + 1;
int k = 0;
for (int j = 0; j < 4; j++)
{
int flag = 0;
for (int i = 0; i < 4; i++)
{
if (a[cur][i][j] == 0)
k++;
if (k == pos)
{
flag = 1;
a[cur][i][j] = 2;
break;
}
}
if (flag)
break;
}
return 0;
}
int right()
{
cur++;
score[cur] = score[cur - 1];
memcpy(a[cur], a[cur - 1], sizeof(a[cur]));
int rem[4] = {0};
int moveable = 0;
for (int j = 0; j < 4; j++)
{
int tmp[10] = {0};
int cnt = 4;
for (int i = 3; i >= 0; i--)
if (a[cur][i][j])
tmp[--cnt] = a[cur][i][j];
for (int i = 3; i > cnt; i--)
if (tmp[i] == tmp[i - 1])
{
tmp[i] *= 2;
score[cur] += tmp[i];
tmp[i - 1] = 0;
}
for (int i = 0; i < 4; i++)
if (a[cur][i][j] != tmp[i])
moveable = 1;
for (int i = 0; i < 4; i++)
a[cur][i][j] = 0;
int k = 3;
for (int i = 3; i >= cnt; i--)
{
if (tmp[i])
a[cur][k--][j] = tmp[i];
}
rem[j] = k + 1;
}
if (!moveable)
{
cur--;
if (check())
return 0;
else
return 1;
}
int M = rem[0] + rem[1] + rem[2] + rem[3];
if (M == 0 && !check())
return 1;
if (M == 0)
return 0;
int pos = rand() % M + 1;
int k = 0;
for (int j = 0; j < 4; j++)
{
int flag = 0;
for (int i = 3; i >= 0; i--)
{
if (a[cur][i][j] == 0)
k++;
if (k == pos)
{
flag = 1;
a[cur][i][j] = 2;
break;
}
}
if (flag)
break;
}
return 0;
}
void color(int x)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), (x << 4) + 15);
}
void print()
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (a[cur][i][j])
{
color(map[a[cur][i][j]]);
gotoxy(5 + 8 * i, 5 + 4 * j);
printf(" ");
gotoxy(5 + 8 * i, 5 + 4 * j + 1);
printf(" ");
gotoxy(5 + 8 * i, 5 + 4 * j + 2);
printf(" ");
int d;
switch ((int)floor(log10(a[cur][i][j])))
{
case 0:
case 1:
d = 3;
break;
case 2:
case 3:
d = 2;
break;
default:
d = 1;
}
gotoxy(5 + 8 * i + d, 5 + 4 * j + 1);
if (a[cur][i][j])
printf("%d", a[cur][i][j]);
color(0);
}
else
{
color(0);
gotoxy(5 + 8 * i, 5 + 4 * j);
printf(" ");
gotoxy(5 + 8 * i, 5 + 4 * j + 1);
printf(" ");
gotoxy(5 + 8 * i, 5 + 4 * j + 2);
printf(" ");
}
}
}
gotoxy(49, 5);
printf("%7d", score[cur]);
gotoxy(1, MAXL + 1);
}
int check()
{
int k = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (i < 3 && a[cur][i][j] == a[cur][i + 1][j])
k++;
if (j < 3 && a[cur][i][j] == a[cur][i][j + 1])
k++;
}
}
return k;
}
void getdata()
{
FILE *fp = fopen("D:\2048data.txt", "rb");
fscanf(fp, "%d", &score[0]);
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 4; i++)
{
fscanf(fp, "%d", &(a[0][i][j]));
}
}
fclose(fp);
}
void savedata()
{
FILE *fp = fopen("D:\2048data.txt", "wb");
fprintf(fp, "%d\n", score[cur]);
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 4; i++)
{
fprintf(fp, "%d ", a[cur][i][j]);
}
fprintf(fp, "\n");
}
fclose(fp);
}
void reset()
{
FILE *fp = fopen("D:\2048data.txt", "wb");
fprintf(fp, "0\n");
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 4; i++)
{
fprintf(fp, "0 ");
}
fprintf(fp, "\n");
}
fclose(fp);
}
void saverank()
{
FILE *fp = fopen("D:\2048rank.txt", "wb");
for (int i = 0; i < 10; i++)
{
fprintf(fp, "%d %d %d %d %d %d %d\n", rscore[i], rtime[i]->tm_year, rtime[i]->tm_mon, rtime[i]->tm_mday, rtime[i]->tm_hour, rtime[i]->tm_min, rtime[i]->tm_sec);
}
fclose(fp);
}
void getrank()
{
FILE fp = fopen("D:\2048rank.txt", "rb");
for (int i = 0; i < 10; i++)
{
if (rtime[i] == NULL)
rtime[i] = malloc(sizeof(struct tm));
fscanf(fp, "%d %d %d %d %d %d %d", &rscore[i], &(rtime[i]->tm_year), &(rtime[i]->tm_mon), &(rtime[i]->tm_mday), &(rtime[i]->tm_hour), &(rtime[i]->tm_min), &(rtime[i]->tm_sec));
}
fclose(fp);
}
void showrank()
{
system("cls");
gotoxy(1, 1);
for (int i = 0; i < MAXC; i++)
putchar('
');
for (int i = 2; i < MAXL; i++)
{
gotoxy(1, i);
printf("*");
gotoxy(MAXC, i);
printf("*");
}
gotoxy(1, MAXL);
for (int i = 0; i < MAXC; i++)
putchar('*');
gotoxy(MAXC / 2 - 9, 3);
printf("欢迎来到快乐2048!");
gotoxy(MAXC / 2 - 19, 6);
printf("名次 得分 达成时间");
gotoxy(11, MAXL - 3);
printf("E/e:返回");
for (int i = 0; i < 10; i++)
{
gotoxy(MAXC / 2 - 19, 7 + i);
if (rscore[i])
printf(" %2d %7d %04d-%02d-%02d %02d:%02d:%02d", i + 1, rscore[i], 1900 + rtime[i]->tm_year, 1 + rtime[i]->tm_mon, rtime[i]->tm_mday, rtime[i]->tm_hour, rtime[i]->tm_min, rtime[i]->tm_sec);
else
printf(" %2d 0", i + 1);
}
gotoxy(1, MAXL + 1);
char c;
while ((c = getch()) != 'E' && c != 'e')
;
}

1 条评论

  • @ 2021-08-10 21:38:34

    请问您是用C++多少的编译器的呀,我用Dev-C++大概是C++14或C++17的版本编译这个c语言程序疯狂报错(好像说的是要在C++99或C++11编译器里才能编译)
    原文: [Error] 'for' loop initial declarations are only allowed in C99 or C11 mode
    (My English is not so good,so I can not understand them well)

  • 1