1、C语言课程设计报告游戏东华理工大学 C语言课程设计 报告学院: 国际教育学院学院 专业: 电子信息工程 班级: 1420606 学号: 2 姓名: 钟天运 一、课程设计题目:游戏2048二、课程设计要求:a)使用C语言编写2048这款游戏b)能够正常运行,拥有游戏界面。c)能正常进行游戏从开始到结束。d)用户操作方便三、设计思路:a)游戏介绍:i.2048是一款简单的数字类游戏,界面是一个4*4的方形格子。每个格子里可以为空或者有一个2n的数值。ii.用户可以输入4种指令,分别是:上下左右,游戏会根据用户的指定的方向,将格子中的数值向对应方向进行移动,直至移动到最边上的格子或者有其他数值占用,
2、如果碰到等大数值,将会进行合并。此外,成功移动后,会在一个空格子随机生成一个2或者4iii.游戏目标是合成2048这个数值或者更大的数值。b)实现思路:i.可以使用二维数组来保存4*4格子中的数值ii.指令,可以通过输入字符函数,读取用户在键盘上的方向键,进行判断执行对应的代码。iii.游戏界面,可以使用简单的特殊制表符,来实现,并通过清屏函数来进行反复同位置打印界面。iv.需要判断游戏结束的函数,以及记录游戏分数和步骤的变量v.当游戏结束时,能够询问 用户是否重新开始。vi.随机生成一个新数,可以调用随机函数,使用时间做种子。c)实现难点:i.打印游戏界面,要实现灵活能根据棋盘数组里面的数据
3、灵活打印。ii.执行操作时,数值的移动和合并。四、流程图五、C语言源代码/ 游戏2048.c#include windows.h#include time.h#include stdio.h#include conio.h#include string.h/宏定义常量 方向键值/const int LEFT = 75, UP = 72, RIGHT = 77, DOWN = 80;#define LEFT 75#define UP 72#define RIGHT 77#define DOWN 80const char error_str = 您上次输入的指令无法识别,请重新输入。;struct
4、 board int place44; long int stepn; long int num; /存储游戏分数 long int time; int dtk; /direction key 记录方向键,及操作方向 int over; int zeronum;/该函数为游戏运行函数,当只是玩游戏的时候。进入该函数,游戏控制函数。int main() /place数组为棋盘,其中为零代表空,-1代表不能合并的牌,其他2的倍数值为本身含义,初始化为全0。 struct board board1, board_backup; int newgame(struct board *, int), sh
5、ow(struct board *), operate(struct board *); char str100 = 首次运行游戏; /用于记录系统返回给用户的信息,例如:上一步执行向左合并,按键有误等 newgame(&board1, 0); /调用函数为新局初始化,第二个参数为初始化方式 show(&board1); printf(n%snn请从键盘上单击方向键,指定下一步操作(ESC键退出游戏)n, str); do switch (_getch() case 224: switch (board1.dtk = _getch() case LEFT: strcpy_s(str, size
6、of(str), 您上次输入的方向键为:,已执行左向合并。); board_backup = board1; operate(&board1); break; case UP: strcpy_s(str, sizeof(str), 您上次输入的方向键为:,已执行上向合并。); board_backup = board1; operate(&board1); break; case RIGHT: strcpy_s(str, sizeof(str), 您上次输入的方向键为:,已执行右向合并。); board_backup = board1; operate(&board1); break; cas
7、e DOWN: strcpy_s(str, sizeof(str), 您上次输入的方向键为:,已执行下向合并。); board_backup = board1; operate(&board1); break; default: strcpy_s(str, sizeof(str), error_str); break; case 27: exit(27); default: strcpy_s(str, sizeof(str), error_str); system(cls); show(&board1); printf(n%snn请从键盘上单击方向键,指定下一步操作(ESC键退出游戏)n, s
8、tr); if (board1.over) printf(n游戏结束,是否重新开始?(y重新开始/n或ECS退出/其他键无效); while (1) str99 = _getch(); if (str99 = y) newgame(&board1, 0); show(&board1); break; else if (str99 = c) change(&board1, &board_backup); break; else if (str99 = n | str99 = 27) break; while (!board1.over); printf(n按任意键退出); _getch(); r
9、eturn 0;/该函数为主要打印函数,包括棋盘的打印,分数,等信息int show(struct board * pboard) int i, j, x, len, numlen(int); printf(游戏2048游戏运行时间:%ld Sn, time(NULL) - (*pboard).time); printf(游戏分数:%ld, (*pboard).num); printf( 已执行步骤数:%ldn, (*pboard).stepn); /开始绘制棋盘 printf(n n); for (i = 0; i 7; +i) if (i % 2 = 0) printf(); for (j
10、 = 0; j 8; +j) if (j % 2 = 0) if (*pboard).placei / 2j / 2 = 0) printf( ); /如果值为0,输入六个空格 else /打印值时。调用numlen判断值的位数,控制数值前后的空格数量,最长为6,若为奇数,前面空格比后面多一个。 len = numlen(*pboard).placei / 2j / 2); for (x = 0; x (6 - len + 1) / 2; +x) printf( ); printf(%d, (*pboard).placei / 2j / 2); for (x = 0; x (6 - len)
11、/ 2; +x) printf( ); else printf(); else printf( nn ); printf(n); printf( nn); return 0;/这是show函数的附属函数,用于求一个整数长度。int numlen(int a) int i, n = 1; for (i = 1; i 11; +i) n *= 10; if (a = a%n) return i; return 0;/开始新的游戏,将棋盘和数据初始化,或者载入棋盘,第二个参数决定初始化方案,默认0int newgame(struct board * pboard, int project) int
12、i, j, t; (*pboard).stepn = 0; (*pboard).num = 0; (*pboard).time = (long int)time(NULL); /取当前时间为开始时间 (*pboard).dtk = 0; (*pboard).over = 0; (*pboard).zeronum = 14; for (i = 0; i 4; +i) for (j = 0; j 4; +j) (*pboard).placeij = 0; do i = (int)(rand() / 32768.0 * 4); j = (int)(rand() / 32768.0 * 4); whi
13、le (*pboard).placeij); t = 2 * (int)(rand() / 32768.0 * 2) + 1); (*pboard).placeij = t; do i = (int)(rand() / 32768.0 * 4); j = (int)(rand() / 32768.0 * 4); while (*pboard).placeij); t = 2 * (int)(rand() / 32768.0 * 2) + 1); (*pboard).placeij = t; return 0;/主要操作函数,调用该函数,将执行结构体中对应按键值的方向的操作,并增加分数和操作次数
14、。int operate(struct board * pboard) int i, j, t, shun = -1, alter = 0, /alter变量是用来判断执行步骤的时候是否改变了棋局。shun用来记录已经进行合并的值对应的I或J,用来避免该值再次合并 randget(struct board *), calczeronum(struct board *); switch (*pboard).dtk) case UP: for (j = 0; j 4; +j, shun = -1) for (i = 1; i = 0; -t) if (*pboard).placetj != 0)
15、if (*pboard).placetj = (*pboard).placeij & shun != t) (*pboard).num += (*pboard).placetj *= 2; (*pboard).placeij = 0; shun = t; alter = 1; else if (t + 1 != i) (*pboard).placet + 1j = (*pboard).placeij; (*pboard).placeij = 0; alter = 1; break; else if (t = 0) (*pboard).placetj = (*pboard).placeij; (
16、*pboard).placeij = 0; alter = 1; break; break; case DOWN: for (j = 0; j = 0; -i) if (*pboard).placeij != 0) for (t = i + 1; t 4; +t) if (*pboard).placetj != 0) if (*pboard).placetj = (*pboard).placeij & shun != t) (*pboard).num += (*pboard).placetj *= 2; (*pboard).placeij = 0; shun = t; alter = 1; e
17、lse if (t - 1 != i) (*pboard).placet - 1j = (*pboard).placeij; (*pboard).placeij = 0; alter = 1; break; else if (t = 3) (*pboard).placetj = (*pboard).placeij; (*pboard).placeij = 0; alter = 1; break; break; case RIGHT: for (i = 0; i = 0; -j) if (*pboard).placeij != 0) for (t = j + 1; t 4; +t) if (*p
18、board).placeit != 0) if (*pboard).placeit = (*pboard).placeij & shun != t) (*pboard).num += (*pboard).placeit *= 2; (*pboard).placeij = 0; shun = t; alter = 1; else if (t - 1 != j) (*pboard).placeit - 1 = (*pboard).placeij; (*pboard).placeij = 0; alter = 1; break; else if (t = 3) (*pboard).placeit =
19、 (*pboard).placeij; (*pboard).placeij = 0; alter = 1; break; break; case LEFT: for (i = 0; i 4; +i, shun = -1) for (j = 1; j = 0; -t) if (*pboard).placeit != 0) if (*pboard).placeit = (*pboard).placeij & shun != t) (*pboard).num += (*pboard).placeit *= 2; (*pboard).placeij = 0; shun = t; alter = 1;
20、else if (t + 1 != j) (*pboard).placeit + 1 = (*pboard).placeij; (*pboard).placeij = 0; alter = 1; break; else if (t = 0) (*pboard).placeit = (*pboard).placeij; (*pboard).placeij = 0; alter = 1; break; break; default:return -1; if (alter) +(*pboard).stepn; return randget(pboard); return 1;/计算place数组中
21、有多少个零,即多少个空位,返回值等同于 board1.zeronumint calczeronum(struct board * pboard) int i, j; for (*pboard).zeronum = 0, i = 0; i 4; +i) for (j = 0; j 4; +j) if (*pboard).placeij = 0) +(*pboard).zeronum; return (*pboard).zeronum;/新数生成函数。每次有效执行 操作函数 时,进行新的数生成int randget(struct board * pboard) int i, j, t, x, if
22、over(struct board *); calczeronum(pboard); t = (int)(rand() / 32768.0 * (*pboard).zeronum) + 1; for (x = 0, i = 0; i 4; +i) for (j = 0; j 4; +j) if (*pboard).placeij = 0) if (+x = t) (*pboard).placeij = 2 * (int)(rand() / 32768.0 * 2) + 1); if (!(-(*pboard).zeronum) | (*pboard).zeronum = 0) ifover(p
23、board); return 0; return -1;/用来判断游戏是否结束,当board.zeronum 的值为零的时候,调用该函数进行判断。游戏结束时返回1,over值为1,否则返回可操作方向值,DOWN或RIGHTint ifover(struct board * pboard) int i; for (i = 0; i 4; +i) if (*pboard).placei0 = (*pboard).placei1 | (*pboard).placei1 = (*pboard).placei2 | (*pboard).placei2 = (*pboard).placei3) (*pboard).over = 0; return DOWN; if (*pboard).place0i = (*pboard).place1i | (*pboard).place1i = (*pboard).place2i | (*pboard).place2i = (*pboard).place3i) (*pboard).over = 0; return RIGHT; return (*pboard).over = 1;六
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1