程序设计报告——控制台游戏2048
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
函数原型12int down(int a[4][4])
函数功能:控制按下s(下)之后数组元素的运算
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:与up函数算法相同,只是读取元素的方向相反,将temp写入二维数组的方向也相反。
函数原型13intleft(int a[4][4])
函数原型19int average()
函数功能:根据数据文件求玩家纪录中的平均水平
入口参数:void
出口参数:void
算法描述:以读的方式打开数据文件,读进相应的数组,调用quntity函数求出文件中数据的个数,计算出平均值,结果直接输出在屏幕上。
下面是int game(int a[4][4],int step,int grade)函数的流程图。
函数原型12int down(int a[4][4])
函数功能:控制按下d(右)之后数组元素的运算
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:与left函数算法相同,只是读取元素的方向相反,将temp写入二维数组的方向也相反。
函数原型15int create_newpoint(int a[4][4])
函数原型11int up(int a[4][4])
函数功能:控制按下w(上)之后数组元素的运算
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:定义一个循环队列,以列为单位,将该列元素依次入队列。元素入队列时判断队列是否已满,如果满了判断队列中元素是否相同,如果相同将二者相加后存入temp[4],如果不同头元素出队列,将新元素入队;如果没满,直接入队。如果以上的操作后队列不空,重负之前的判定步骤,直到元素全部出队。再按顺序将temp中的元素重新写入二维数组。
选题意义:2048是最近最流行的小游戏之一,益智益趣,通过C语言控制台仿写这个游戏,可以锻炼编程框架思想以及技巧,同时将所学到的数据结构等知识灵活的运用。
目标实现的系统功能:完成2048游戏主体,可查看各玩家排名情况,可查看玩家平均水平,可存档、读档。
二、
1.
设计的控制台游戏2048结构图如图一所示。
Hale Waihona Puke Baidu
函数功能:绘制游戏地图以及提示信息。
入口参数:void
出口参数:void
算法描述:利用for循环以及gotoxy函数绘制边框,再通过对文件的操作读取当前最高分显示在屏幕上。
函数功能:绘制游戏中出现的各级菜单(通过参数x控制具体绘制哪一种)。
入口参数:int x
出口参数:数字1~3
算法描述:同样利用for循环和gotoxy函数,绘制出菜单边框,通过参数x的值决定绘制的内容。
函数功能:读取游戏存档。
入口参数:int x,int a[4][4],int b[2]
出口参数:x值为1或2,保存游戏数据的二维数组a[4][4],保存步数step和分数grade的数组b[2]。
算法描述:通过参数x的控制以读的方式打开相应的数据文件,将游戏数据信息读取到数组a[4][4]中,将分数等信息读取到b[2]中。
函数功能:控制按下a(左)之后数组元素的运算
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:定义一个循环队列,以行为单位,将该列元素依次入队列。元素入队列时判断队列是否已满,如果满了判断队列中元素是否相同,如果相同将二者相加后存入temp[4],如果不同头元素出队列,将新元素入队;如果没满,直接入队。如果以上的操作后队列不空,重负之前的判定步骤,直到元素全部出队。再按顺序将temp中的元素重新写入二维数组。
函数功能:保存游戏排名
入口参数:StepRecord s,GradeRecord g,int num1,int num2
出口参数:s为上一局游戏中的步数结构体,g为上一局游戏中的分数结构体,num1和num2分别为当前数据文件中记录个数。
算法描述:先以读的方式打开相应的文件,将原本数据文件中的排名信息读入相应数组,由于原来的信息已经有序,只需确定新数据的插入位置即可(这里采用顺序查找,可用二分查找减少比较次数)。再以读的方式打开文件,将排序后的新序列写入文件。
函数功能:更新数据
入口参数:int step,int grade,int a[4][4]
出口参数:step和grade分别为当前的步数以及分数,a[4][4]为游戏数据数组
算法描述:遍历二维数组元素,利用gotoxy函数在正确的位置输出数字以及恰当的空格符,同时利用API函数SetConsoleTextAttribute达到不同数字不同颜色的效果。
函数功能:获取数据文件中记录个数。
入口参数:int x
出口参数:1或2
算法描述:利用指针定位函数fseek,文件打开时,指针位于文件首第一个字节,调用fseek函数把指针移到文件末尾,再调用ftell()返回指针当前所在位置,这个返回值是文件长度,再根据参数x的值用它除以类型StepRecord或者GradeRecord的长度,得到记录个数。
大连理工大学程序设计总结报告
控制台游戏——2048
学生姓名:刘阳
院系班级:电计1203
学号:201281303
联系电话:188-4085-1891
Email:rick@mail.dlut.edu.cn
完成日期:2014年7月1日
一、
设计目标:完成一个控制台小游戏,其中包括游戏、排名、存档和读档等功能。
五、 程序操作说明
程序文件夹中已包含数据文件;游戏中wasd控制上下左右;游戏中允许误操作;游戏中请按说明进行。
游戏规则:开始时棋盘内随机出现两个数字,出现的数字仅可能为2或4,玩家可以选择上下左右四个方向,若棋盘内的数字出现位移或合并,视为有效移动,玩家选择的方向上若有相同的数字则合并,每次有效移动可以同时合并,但不可以连续合并,合并所得的所有新生成数字想加即为该步的有效得分,玩家选择的方向行或列前方有空格则出现位移,每有效移动一步,棋盘的空位(无数字处)随机出现一个数字(依然可能为2或4),棋盘被数字填满,无法进行有效移动,判负,游戏结束,棋盘上出现2048,判胜,游戏结束
函数功能:隐藏光标,减少游戏中的闪烁。
入口参数(形参):void
出口参数(实参):void
算法描述(即实现步骤):
函数功能:隐藏光标,减少游戏中的闪烁。
入口参数:int x,int y
出口参数:实际点的坐标。
算法描述:运用api函数,GetStdHandle获取标准输出设备句柄,SetConsoleCursorPosition设置控制台光标位置并输出。
分数模块数据采用结构体数组存放,用typedef定义了StepRecord和GradeRecord。StepRecord中name[15]代表玩家在步数排行榜中的名字,step代表玩家所坚持的步数;GradeRecord中name[15]代表玩家在分数排行榜中的名字,grade代表玩家取得的分数(分数计算规则见说明)。存储时以二进制文件存储,数据文件位于工程文件夹中step_rank.dat、grade_rank.dat。读取数据的目的是将新的数据加入排行榜或者读取并显示排行榜。
函数原型17int initialization(int a[4][4])
函数功能:完成新的游戏的初始化
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:利用for循环,两次执行while(1),while(1)的出口为找到值为0的位置。将找到的两个位置元素置为2,完成新的游戏数据初始化。
函数原型10int judge(int a[4][4],int flag[5])
函数功能:判断游戏是否可以继续进行
入口参数:int a[4][4],int flag[5]
出口参数:a[4][4]为当前游戏数据,flag[5]保存判断信息的数组
算法描述:首先将判断数组flag[5]置0,再遍历二维数组元素,如果有0,将flag置1;如果有2048的出现,return 2结束;如果既不为0也不为2048,则判断其上下左右是否有相邻相等的元素或者为0的元素,flag[1]~flag[4]表示是否可以进行上下左右四个操作,如果满足上述条件就将相应的flag置1。最后只要flag数组中有一个元素为1,游戏便可继续,返回0;否则返回1。
函数功能:在随机的空白位置随机的产生2或者4
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:首先一个while(1)循环,出口为找到值为0的位置。再利用随机数决定产生的是2还是4。
函数原型16int update_menu(int step,int grade,int a[4][4])
函数功能:游戏中数据存档
入口参数:int x,int a[4][4],int step,int grade
出口参数:x值为1或2,a[4][4]为游戏中存放数据的二维数组,step和grade分别是游戏中的步数和分数。
算法描述:通过参数x的控制以写的方式打开对应的存档位置,将相应数据写进数据文件。
函数原型9int save_rank(StepRecord s,GradeRecord g,int num1,int num2)
算法描述:利用一个while(1)循环,每次利用judge函数检查游戏是否结束,如果结束根据返回值1或者2判断游戏获胜或失败并调用save_rank函数将信息加入排行榜;如果没有结束,嵌套一个while(1),出口为有wasd或者表示存档的i按下,每当有wasd或者i按下,便执行相应的操作(up函数等)并将w置1,w等于1的情况下将会更新屏幕上的数据并且在空白处产生新的数字(调用create_newpoint和update_menu函数)。
函数原型18int game(int a[4][4],int step,int grade)
函数功能:游戏主体函数,完成游戏各种操作并允许各种误操作以及提供了存档接口。
入口参数:int a[4][4],int step,int grade
出口参数:a[4][4]为初始游戏数据数组,step以及grade为游戏开始时的步数和分数。
函数原型7int read_rank(int x,int num)
函数功能:读取游戏排名
入口参数:int x,int num
出口参数:x值为1或2,num为数据文件中记录个数
算法描述:通过参数x的控制以读的方式打开相应的数据文件,将排名数据存入相应数组中,再通过gotoxy函数以及for循环打印。
函数原型8int save_record(int x,int a[4][4],int step,int grade);
使用API函数。比如SetConsoleTextAttribute设置字体颜色、SetConsoleCursorPosition移动光标、GetStdHandle获取标准输出设备句柄等。
三、
(原程序是彩色的,报告需要打印时打成黑白的)
四、
最深的体会就是学到的知识要学会用,比如数据结构与算法中的查找算法、队列等等完全可以运用在平时的程序中提高效率;还有就是要不断的学习,这个2048我几个月前就开始写的,但之前的版本中游戏算法中一直有bug并且屏幕有闪烁界面不友好,之后为了一个一个解决这些问题通过百度学习了一点API等,一点点的完善这个程序。学习就是需要这样,在完善中进步。还有这个报告真心没办法在五页内完成,请老师谅解。
N
Y
Y
N
N
Y
N
Y
N
(3)
遇到的问题:控制台游戏大多依赖于system(“cls”),但清屏会闪烁影响游戏。在update_menu函数中,没有采用清屏的方式,而是用gotoxy函数直接输出数字,只修改变化的部分。
使用的数据结构:在up等函数中,运用了循环队列,通过元素依次入队判断捕捉到相应的键值后的元素位置变化,节省空间。
图1.2048游戏框图
2.
(1)
游戏模块数据采用二维数组存放,并且不断根据按键信息更新其中数据。存储时以二进制文件存储,数据文件位于工程文件夹中load1.dat以及load2.dat(此时的步数以及分数存储在load1_step.dat、load2_grade、load2_step.dat、load2_grade)。读取数据的目的是可以继续之前没有完成但存档了的游戏。
函数功能:控制按下s(下)之后数组元素的运算
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:与up函数算法相同,只是读取元素的方向相反,将temp写入二维数组的方向也相反。
函数原型13intleft(int a[4][4])
函数原型19int average()
函数功能:根据数据文件求玩家纪录中的平均水平
入口参数:void
出口参数:void
算法描述:以读的方式打开数据文件,读进相应的数组,调用quntity函数求出文件中数据的个数,计算出平均值,结果直接输出在屏幕上。
下面是int game(int a[4][4],int step,int grade)函数的流程图。
函数原型12int down(int a[4][4])
函数功能:控制按下d(右)之后数组元素的运算
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:与left函数算法相同,只是读取元素的方向相反,将temp写入二维数组的方向也相反。
函数原型15int create_newpoint(int a[4][4])
函数原型11int up(int a[4][4])
函数功能:控制按下w(上)之后数组元素的运算
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:定义一个循环队列,以列为单位,将该列元素依次入队列。元素入队列时判断队列是否已满,如果满了判断队列中元素是否相同,如果相同将二者相加后存入temp[4],如果不同头元素出队列,将新元素入队;如果没满,直接入队。如果以上的操作后队列不空,重负之前的判定步骤,直到元素全部出队。再按顺序将temp中的元素重新写入二维数组。
选题意义:2048是最近最流行的小游戏之一,益智益趣,通过C语言控制台仿写这个游戏,可以锻炼编程框架思想以及技巧,同时将所学到的数据结构等知识灵活的运用。
目标实现的系统功能:完成2048游戏主体,可查看各玩家排名情况,可查看玩家平均水平,可存档、读档。
二、
1.
设计的控制台游戏2048结构图如图一所示。
Hale Waihona Puke Baidu
函数功能:绘制游戏地图以及提示信息。
入口参数:void
出口参数:void
算法描述:利用for循环以及gotoxy函数绘制边框,再通过对文件的操作读取当前最高分显示在屏幕上。
函数功能:绘制游戏中出现的各级菜单(通过参数x控制具体绘制哪一种)。
入口参数:int x
出口参数:数字1~3
算法描述:同样利用for循环和gotoxy函数,绘制出菜单边框,通过参数x的值决定绘制的内容。
函数功能:读取游戏存档。
入口参数:int x,int a[4][4],int b[2]
出口参数:x值为1或2,保存游戏数据的二维数组a[4][4],保存步数step和分数grade的数组b[2]。
算法描述:通过参数x的控制以读的方式打开相应的数据文件,将游戏数据信息读取到数组a[4][4]中,将分数等信息读取到b[2]中。
函数功能:控制按下a(左)之后数组元素的运算
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:定义一个循环队列,以行为单位,将该列元素依次入队列。元素入队列时判断队列是否已满,如果满了判断队列中元素是否相同,如果相同将二者相加后存入temp[4],如果不同头元素出队列,将新元素入队;如果没满,直接入队。如果以上的操作后队列不空,重负之前的判定步骤,直到元素全部出队。再按顺序将temp中的元素重新写入二维数组。
函数功能:保存游戏排名
入口参数:StepRecord s,GradeRecord g,int num1,int num2
出口参数:s为上一局游戏中的步数结构体,g为上一局游戏中的分数结构体,num1和num2分别为当前数据文件中记录个数。
算法描述:先以读的方式打开相应的文件,将原本数据文件中的排名信息读入相应数组,由于原来的信息已经有序,只需确定新数据的插入位置即可(这里采用顺序查找,可用二分查找减少比较次数)。再以读的方式打开文件,将排序后的新序列写入文件。
函数功能:更新数据
入口参数:int step,int grade,int a[4][4]
出口参数:step和grade分别为当前的步数以及分数,a[4][4]为游戏数据数组
算法描述:遍历二维数组元素,利用gotoxy函数在正确的位置输出数字以及恰当的空格符,同时利用API函数SetConsoleTextAttribute达到不同数字不同颜色的效果。
函数功能:获取数据文件中记录个数。
入口参数:int x
出口参数:1或2
算法描述:利用指针定位函数fseek,文件打开时,指针位于文件首第一个字节,调用fseek函数把指针移到文件末尾,再调用ftell()返回指针当前所在位置,这个返回值是文件长度,再根据参数x的值用它除以类型StepRecord或者GradeRecord的长度,得到记录个数。
大连理工大学程序设计总结报告
控制台游戏——2048
学生姓名:刘阳
院系班级:电计1203
学号:201281303
联系电话:188-4085-1891
Email:rick@mail.dlut.edu.cn
完成日期:2014年7月1日
一、
设计目标:完成一个控制台小游戏,其中包括游戏、排名、存档和读档等功能。
五、 程序操作说明
程序文件夹中已包含数据文件;游戏中wasd控制上下左右;游戏中允许误操作;游戏中请按说明进行。
游戏规则:开始时棋盘内随机出现两个数字,出现的数字仅可能为2或4,玩家可以选择上下左右四个方向,若棋盘内的数字出现位移或合并,视为有效移动,玩家选择的方向上若有相同的数字则合并,每次有效移动可以同时合并,但不可以连续合并,合并所得的所有新生成数字想加即为该步的有效得分,玩家选择的方向行或列前方有空格则出现位移,每有效移动一步,棋盘的空位(无数字处)随机出现一个数字(依然可能为2或4),棋盘被数字填满,无法进行有效移动,判负,游戏结束,棋盘上出现2048,判胜,游戏结束
函数功能:隐藏光标,减少游戏中的闪烁。
入口参数(形参):void
出口参数(实参):void
算法描述(即实现步骤):
函数功能:隐藏光标,减少游戏中的闪烁。
入口参数:int x,int y
出口参数:实际点的坐标。
算法描述:运用api函数,GetStdHandle获取标准输出设备句柄,SetConsoleCursorPosition设置控制台光标位置并输出。
分数模块数据采用结构体数组存放,用typedef定义了StepRecord和GradeRecord。StepRecord中name[15]代表玩家在步数排行榜中的名字,step代表玩家所坚持的步数;GradeRecord中name[15]代表玩家在分数排行榜中的名字,grade代表玩家取得的分数(分数计算规则见说明)。存储时以二进制文件存储,数据文件位于工程文件夹中step_rank.dat、grade_rank.dat。读取数据的目的是将新的数据加入排行榜或者读取并显示排行榜。
函数原型17int initialization(int a[4][4])
函数功能:完成新的游戏的初始化
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:利用for循环,两次执行while(1),while(1)的出口为找到值为0的位置。将找到的两个位置元素置为2,完成新的游戏数据初始化。
函数原型10int judge(int a[4][4],int flag[5])
函数功能:判断游戏是否可以继续进行
入口参数:int a[4][4],int flag[5]
出口参数:a[4][4]为当前游戏数据,flag[5]保存判断信息的数组
算法描述:首先将判断数组flag[5]置0,再遍历二维数组元素,如果有0,将flag置1;如果有2048的出现,return 2结束;如果既不为0也不为2048,则判断其上下左右是否有相邻相等的元素或者为0的元素,flag[1]~flag[4]表示是否可以进行上下左右四个操作,如果满足上述条件就将相应的flag置1。最后只要flag数组中有一个元素为1,游戏便可继续,返回0;否则返回1。
函数功能:在随机的空白位置随机的产生2或者4
入口参数:int a[4][4]
出口参数:a[4][4]为游戏数据数组
算法描述:首先一个while(1)循环,出口为找到值为0的位置。再利用随机数决定产生的是2还是4。
函数原型16int update_menu(int step,int grade,int a[4][4])
函数功能:游戏中数据存档
入口参数:int x,int a[4][4],int step,int grade
出口参数:x值为1或2,a[4][4]为游戏中存放数据的二维数组,step和grade分别是游戏中的步数和分数。
算法描述:通过参数x的控制以写的方式打开对应的存档位置,将相应数据写进数据文件。
函数原型9int save_rank(StepRecord s,GradeRecord g,int num1,int num2)
算法描述:利用一个while(1)循环,每次利用judge函数检查游戏是否结束,如果结束根据返回值1或者2判断游戏获胜或失败并调用save_rank函数将信息加入排行榜;如果没有结束,嵌套一个while(1),出口为有wasd或者表示存档的i按下,每当有wasd或者i按下,便执行相应的操作(up函数等)并将w置1,w等于1的情况下将会更新屏幕上的数据并且在空白处产生新的数字(调用create_newpoint和update_menu函数)。
函数原型18int game(int a[4][4],int step,int grade)
函数功能:游戏主体函数,完成游戏各种操作并允许各种误操作以及提供了存档接口。
入口参数:int a[4][4],int step,int grade
出口参数:a[4][4]为初始游戏数据数组,step以及grade为游戏开始时的步数和分数。
函数原型7int read_rank(int x,int num)
函数功能:读取游戏排名
入口参数:int x,int num
出口参数:x值为1或2,num为数据文件中记录个数
算法描述:通过参数x的控制以读的方式打开相应的数据文件,将排名数据存入相应数组中,再通过gotoxy函数以及for循环打印。
函数原型8int save_record(int x,int a[4][4],int step,int grade);
使用API函数。比如SetConsoleTextAttribute设置字体颜色、SetConsoleCursorPosition移动光标、GetStdHandle获取标准输出设备句柄等。
三、
(原程序是彩色的,报告需要打印时打成黑白的)
四、
最深的体会就是学到的知识要学会用,比如数据结构与算法中的查找算法、队列等等完全可以运用在平时的程序中提高效率;还有就是要不断的学习,这个2048我几个月前就开始写的,但之前的版本中游戏算法中一直有bug并且屏幕有闪烁界面不友好,之后为了一个一个解决这些问题通过百度学习了一点API等,一点点的完善这个程序。学习就是需要这样,在完善中进步。还有这个报告真心没办法在五页内完成,请老师谅解。
N
Y
Y
N
N
Y
N
Y
N
(3)
遇到的问题:控制台游戏大多依赖于system(“cls”),但清屏会闪烁影响游戏。在update_menu函数中,没有采用清屏的方式,而是用gotoxy函数直接输出数字,只修改变化的部分。
使用的数据结构:在up等函数中,运用了循环队列,通过元素依次入队判断捕捉到相应的键值后的元素位置变化,节省空间。
图1.2048游戏框图
2.
(1)
游戏模块数据采用二维数组存放,并且不断根据按键信息更新其中数据。存储时以二进制文件存储,数据文件位于工程文件夹中load1.dat以及load2.dat(此时的步数以及分数存储在load1_step.dat、load2_grade、load2_step.dat、load2_grade)。读取数据的目的是可以继续之前没有完成但存档了的游戏。