c语言程序设计(猜数字游戏)报告 下载本文

《高级语言程序设计》课程设计

题 目: 猜数字游戏 班 级: 09软件工程R3 学生姓名: 谢泽雄 学生学号: 200931000622 指导老师: 姚金涛 提交时间: 2010年5月29日

华南农业大学 信息(软件)学院

1

《高级语言程序设计》 课程设计评分表

题 目 专业班级 小组成员 组 长 组 员 组 员 小组评分表 评分项目 1.实现情况(15):完成课程设计要求的情况 2.系统分析(10):对系统的理解及分析的深入程度。 3.系统设计(20):总体设计、具体设计、数据结构设计等。 4.程序设计(30):面向对象程序设计方法与编程工具掌握水平。 5.界面设计(15):界面美观程度、操作方式友好程度等。 6.论文撰写(10):论文撰写的规范性、合理性等等。 小组总成绩: 教师签名 猜数字游戏 09软件工程R3 学 号 无 200931000622 姓 名 无 谢泽雄 提交日期 2010年05月29日 完成情况 成绩 (指导老师填写) 分数 日 期 2

目录

一、猜数字游戏分析。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。4

1.游戏概述。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。4 2.系统运行环境。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。4 3.功能需求描述。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。4

二、总体设计。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。5

1.开发和设计的总体思想。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。5 2.程序模块结构图。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。5 3.模块设计。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。5

4.程序流程描述。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。6 5.界面设计。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。7 6.数据结构设计。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。12

三、详细设计。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。13

1.文件及函数组成。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。13 2.函数设计。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。14

四.程序代码。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。17

1.start.h。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。17 2.start.c。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。19 3.mianzone.c。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。25 4.game zone.c。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。32 5.refreshline.c。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。37 6.reset.c。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。40 7.print.c。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。40 8.count_num.c。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。48 9.intset – del.c。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。49 10.imageline.c。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。49

五. 运行结果。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。50 六、调试分析。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。51

1.情况1。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。51 2.情况2。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。51 3.情况3。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。51 4.情况4。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。52

七、总结。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。52

3

一、猜数字游戏分析

在《猜数字游戏》分析环节中,会对该游戏开发的意图、应用目标、作用范围和有关该软件开发的背景材料进行详细的分析。《猜数字游戏》作为一个用来进行娱乐、消遣的应用软件,在对其进行需求分析的过程中,需要充分考虑游戏的可用性和娱乐性,联系实际生活,从而得到合理的需求分析的结论。

1. 游戏概述

该软件为用户提供一个在Windows系统上运行的猜数字游戏,其使用者只有玩家: 玩家在运行该程序时,可以浏览游戏自最近一次重置数据记录以来,所保存的游戏记录: 分为“排行榜记录”和“成功情况”。玩家可清空排行榜数据,以重新开始记录游戏成绩。参加游戏后,游戏将自动刷新游戏记录,重新排行排行榜。玩家参加游戏前,可浏览帮组功能,了解游戏规则。

2. 系统运行环境

(1) 硬件环境

? 处 理 器:Intel Pentium 166或更高 ? 内 存:32MB以上 ? 硬盘空间:2G以上

? 显 卡:SVGA显示适配器 (2) 软件环境

? 操作系统:Windows98/Me/2000/XP/vista/7

3. 功能需求描述

猜数字游戏是用来进行娱乐、消遣活动的应用软件。可进行游戏功能、浏览游戏记录功能和查看游戏帮助功能。

(1) 游戏功能需求如下:

? 进行游戏:在游戏提示下输入所要猜测的游戏数字,即可完成游戏。

? 重新开始游戏:在游戏进行中,因不同原因玩家要求输入特定字符串以重新游戏,

或放弃游戏且返回主菜单。

? 刷新排行榜:游戏结束后,若玩家成功猜的答案,玩家要求记录自己的用户名和

记录,参与新排行榜的排行。

? 输出答案:当玩家在规定次数中不能猜出答案,则玩家要求在游戏结束后得知正

确答案。

? 计算赢得游戏所用时间:玩家猜出数字后,要求显示所用时间并记录到排行榜中,

以便与其他玩家进行比较和检查自己的提升。 (2) 浏览游戏记录功能需求如下:

? 查看排行榜:游戏结束后,玩家需要查看自己的成绩排位,和了解其他玩家的游

戏情况。在不同情况下,玩家想依据成绩循序、用户名循序、所用时间多少进行输出排行榜。

? count文件:玩家需要查看游戏次数与成功次数的记录。

? 清空排行榜:玩家在一定情况下,要求重新开始记录游戏信息。 ? 清空count文件:玩家在一定情况下,要求重新开始记录游戏信息。 (3) 帮组功能需求如下:

? 输出游戏规则:玩家需要了解游戏规则。

? 游戏说明:玩家要求更了解游戏的各种功能,以更方便操作程序。

4

二、总体设计

题目要求

(1)按照分析、设计、编码、调试和测试过程完成应用程序; (2)学习并使用流程图等工具,并在撰写论文中使用;

(3)程序的各项功能在程序运行时,以菜单方式选择并执行;

(4)要求用户输入数据时,要给出清晰、明确的提示,包括:输入数据的内容、格

式及结束方式等

(5)所有的信息存储在文件中,并实现文件读写操作。

1. 开发和设计的总体思想

猜数字游戏是一个简易的娱乐游戏,开发设计的重点在于排行榜的跟新。每次游戏结束后都要对排行榜进行跟新,不可漏掉任何一次跟新。解决这个问题的方法是将跟新的过程单独写成一个可以独立完成得函数,在每次游戏结束后都必须调用该函数。

关于排行榜的输出问题,游戏将把成绩排行在前十名的玩家信息输出,当排行在十名后的玩家的成绩与第十名的成绩相同,则把与第十名的玩家的成绩相同的用户信息一同输出。

对于排行榜的容量问题,游戏采用自动增删的方法进行处理。当排行榜存有的用户信息多于十五名时,排行榜将自动删除第十六条用户信息。

对菜单的选择判断要用到程序设计思想中的选择结构,对大量数据的处理要用到循环和文件处理等基本技术。

系统采用结构化的设计方法进行设计,采用C语言进行开发。

2. 程序模块结构图

依据需求分析结果,猜数字游戏的程序可分为3个模块:游戏区、游戏记录和帮助。程序模块结构图如图1所示。

游戏区 猜数字游戏 游戏记录 帮助

图1 程序模块功能图

3. 模块设计

(1) 游戏区模块

该模块为进入游戏,玩家进入后可按照游戏提示完成游戏,和刷新游戏记录、排行榜。

(2) 游戏记录模块

游戏记录模块的作用是为了保障系统的安全性和系统使用人员角色的区分。该模块需要从输入设备获取用户输入的用户名和密码,判断是否为合法身份,其次要判断用户权限,从而决定其能使用的系统功能,其模块功能图如图2所示。

5

按排名浏览排行榜 按姓名浏览排行榜 排行榜 按用时浏览排行榜 清空排行榜 显示count文件信息 清空count文件 图2 游戏记录模块功能图

(3) 帮助模块

该模块主要实现常规的管理功能,如投票人的初始化,即创建投票人文件、投票人信息的增加、删除、修改和查询等。该模块主要用结构体类型的数组和文件的读写来完成对大量数据的管理操作,其功能图如图3所示。

游戏规则 帮助 游戏说明 图3帮助模块功能图

游戏记录 count文件 4. 程序流程描述

程序的主体处理流程如图8所示。

6

Y Y N Y

开始 进入程序 进入游戏 游戏记录 退出重新游戏 排行榜 count文件 程序 游戏规按排名浏览排行榜 按姓名浏览排行榜 按用时浏览排行榜 清空排行榜 清空排行榜 则 游戏说明 返回主菜单 帮助 N 返回菜单 重置count显示countN 赢得游戏 Y 刷新排行榜 文件 文件信息 Y 输出排行榜 N 继续游戏 同时重置count同时清空排行榜 清空count文件 N 文件 结束 图4 程序流程图

5. 界面设计

应遵循简洁美观、方便使用的原则。 (1) 主菜单界面设计

充分考虑界面易于操作的系统需求,其他的的功能调用采用类似于菜单的功能选择方式实现。用printf语句构造简单的文字界面,具体功能选择界面设计效果如图5所示。

图5 主菜单界面设计效果图

(2) 游戏区界面设计

7

8

游戏区界面设计注重界面的简洁性,要求玩家在游戏时可在游戏提示下完成游戏,重新游戏,放弃游戏回到主菜单,游戏后刷新排行榜,浏览排行榜或继续游戏。具体设计效果如组图6所示。

图6.1

图6.2

图6.3

组图6 游戏区界面设计效果图

(3) 数据记录菜单界面与其他菜单界面设计

充分考虑界面易于操作的系统需求,其他的的功能调用采用类似于菜单的功能选择方式实现。用printf语句构造简单的文字界面,具体菜单选择界面设计效果如图7~图12所示。

图7 数据记录菜单界面设计效果图

图8 排行榜菜单界面设计效果图

图9 重置排行榜菜单界面设计效果图

图10 count文件菜单界面设计效果图

图11 重置count文件菜单界面设计效果图9

图12 帮助菜单界面设计效果图

(4) 排行榜输出界面、显示count文件界面、游戏规矩和游戏说明的输出界面设计

这些界面设计主要考虑玩家在浏览信息的清晰和易读性。以防数据输出的排版长度大于窗口的长度,在输出所有数据后使光标回到窗口的最上端,利于玩家从数据的起始端开始浏览数据。

排行榜的输出中,将名次、用时、成绩(次数)和用玩家姓名列表显示。具体排行榜输出界面设计效果如图13~图15所示。

图13 按排名顺序输出排行榜界面设计效果图

图14 按姓名次序输出排行榜界面设计效果图

10

图15按所用时间排序输出排行榜界面设计效果图count文件的输出界面设计效果如图16所示。

图16 count文件的输出界面设计效果图

游戏规则的输出界面设计效果如图17所示。

图17 游戏规则界面设计效果图

游戏说明的输出界面设计效果如组图18所示。

图18.1

11

图18.2

图18.3

组图18 游戏说明的输出界面设计效果图

(5) 退出游戏界面设计

具体退出游戏界面设计效果如图19所示。

图19 退出游戏界面设计效果图

6. 数据结构设计

(1) 玩家用户数据结构

描述玩家用户的用户名、猜出数字所用次数和游戏所用时间,作为一整条记录存放在文件中。 typedef struct a {

char name[22]; //玩家用户名 int t; //猜数字所用次数 int sj; //游戏所用时间 struct a *next; } player;

12

(2) “胜利”信息数据结构

记录玩家赢得游戏次数与猜正确平均所需次数,作为一整条记录存放在文件中。 struct winave {

int wintime; //总共赢的次数 float ave; //才正确平均所用次数 };

三、详细设计

基于系统需求分析与系统总体设计的结果,本系统采用Visaul C++ 6.0实现各模块的功能,下面阐述系统的详细设计和实现过程。

1.文件及函数组成 源文件 start.h start.c 函数名或其他成分 结构声明 库函数及函数原型声明 main mainmenu menu2 phbmenu qkmenu countmenu rscountmenu menu3 move rulemenu explainmenu endmenu mianzone.c main1 liulan paihangbang qk qingkong pn countwork printcount st setcount sc help gamezone.c checkcount closecount 结构声明 主函数 主菜单 游戏记录菜单 浏览排行榜菜单 清空排行榜菜单 浏览count文件菜单 重置count文件菜单 帮助菜单 “到达”函数 游戏规则 游戏说明 结束菜单 被主函数调用,用以开始进入游戏 进入浏览排行榜功能 进入排行榜功能 清空排行榜功能 进入重置排行榜功能 进入重置排行榜和count文件功能 进入count文件浏览功能 输出count文件数据函数 进入重置count文件 进入清空count文件功能 进入重置count文件和排行榜 进入帮助功能 检查count的情况,且读取count中数据 更新count中的数据 13

功能 creat checknum Time_get gamezone refreshline.c reset.c print.c refresh note resetline resetcount printline printname printtime count_num.c intset – del.c imageline.c countnum inset del pl; pl0; 生成游戏所需猜的数字 检查输入的数字是否符合规定 计算完成游戏所用时间 进行游戏 更新排行榜 记录或输出记录起始时间 清空或重置排行榜 重置或清空count.txt文件 按成绩输出排行榜 按姓名输出排行榜 按用时输出排行榜 计算及输出平均成功率 插入新纪录链表 删除链表中的第十六个记录 2.函数设计 (1) 头部文件

文件名称:start.h

功 能:声明函数原型,宏定义包含头文件及定义数据结构。 要 求:完成所需函数的原型声明。 (2) 进入游戏函数

函数原型:main()

功 能:调用mian1函数 参 数:void 返 回 值:void

要 求:开始程序,使游戏顺利开始。 (3) 进入游戏函数

函数原型:void main1() 功 能:进入游戏主菜单 参 数:void 返 回 值:void

要 求:如果游戏者没有进行等级设定,则默认初级进行游戏。 (4) 菜单函数

函数原型: void mainmenu() void menu2() void phbmenu() void qkmenu() void countmenu() void menu3() 功 能:输出菜单选项 参 数:void 返 回 值:void

14

主菜单 游戏记录菜单 浏览排行榜菜单 清空排行榜菜单 浏览count文件菜单 帮助菜单函数 void rscountmenu() 重置count文件菜单

要 求:明确显示菜单选项,使玩家准确进入相应的游戏功能。 (5) “到达”函数

函数原型:void move(int i,int j)

功 能:使光标回到窗口的特定位置。 参 数:int i和int j:特定位置的坐标 返 回 值:void

要 求:实现程序所需功能。 (6) 游戏规则和游戏说明函数

函数原型:

void rulemenu() void explainmenu() 游戏规则函数 游戏说明函数 功 能:输出游戏规则和游戏说明 参 数:void 返 回 值:void

要 求:使玩家清楚游戏的玩法,是玩家可以了解本程序的功能。 (7) 结束函数

函数原型:void endmenu() 功 能:输出结束界面 参 数:void 返 回 值:void

要 求:感谢玩家使用本软件。 (8) 检查count函数

函数原型:void checkcount (char count[ ])

功 能:检查count的情况,且读取count中数据 参 数:char count[]:需要读取的数组 返 回 值:void 要 求:检查count的情况,若存在,则读取其中的数据;若不存在,则重置count

文件。

(9) 更新count函数

函数原型:void closecount (char count[ ]) 功 能:将count [ ]数组中的数据存储到

参 数:char count[]:需要存储到文件的数组 返 回 值:void

要 求:更新count数据。 (10) 生成随机数函数

函数原型:void creat (char key[ ]) 功 能:生成游戏所需猜的数字

参 数:char key[]:存储答案的数组 返 回 值:void

要 求:生成4个不重复的数字。 (11) 检查输入函数

函数原型:void checknum (char guess[ ]) 功 能:检查输入的数字是否符合规定

参 数:char guess[]:需检查的玩家猜测的数组

15

返 回 值:void

要 求:检查输入的数字是否符合规定,不合规定的要求玩家重新输入;若和规

则的,检查与答案的不同,输出提示。

(12) 算时函数

函数原型:int Time_get checknum(time_t first, time_t second) 功 能:计算完成游戏所用时间

参 数:time_t first, time_t second:游戏开始的时间与游戏结束的时间 返 回 值:int a: second与first相差的秒数

要 求:计算second与first相差的秒数并返回。 (13) 游戏函数

函数原型:void gamezone() 功 能:进行游戏 参 数:void; 返 回 值:void;

要 求:顺利进行游戏。 (14) 更新排行榜函数

函数原型:void refresh(char name [ ],int t, int sj) 功 能:更新排行榜

参 数:char name [ ],int t, int sj :需要插入的玩家信息(玩家姓名,所用次数,

所用时间)

返 回 值:void;

要 求:若排行榜不存在,则新建排行榜;若存在,则将新加入的信息插入到排

行榜中。

(15) 记录函数

函数原型:void note(int i)

功 能:记录或输出记录起始时间 参 数:int i:所需进行的功能 返 回 值:void;

要 求:i=1(2)时,输出排行榜(count文件)记录起始时间;i=3(4)时,记

录排行榜(count文件)重置时间。

(16) 重置排行榜函数

函数原型:FILE *resetline(FINE *fp) 功 能:清空或重置排行榜

参 数:FILE *fp:重置文件的指针

返 回 值:FILE *fp;用“r”打开的处理后的排行榜文件

要 求:若排行榜不存在,新建排行榜;若存在,则清空排行榜。 (17) 重置count文件函数

函数原型:void resetcount(void ) 功 能:重置或清空count.txt文件 参 数:void 返 回 值:void

要 求:若count文件不存在,新建count文件;若存在,则清空count文件。 (18) 按成绩输出排行榜函数

函数原型:void printline(void )

16

功 能:按成绩先后输出排行榜 参 数:void 返 回 值:void

要 求:若排行榜不存在,新建排行榜;若存在,则按成绩先后输出排行榜。 (19) 按姓名输出排行榜函数

函数原型:void printline(void ) 功 能:按姓名顺序输出排行榜 参 数:void 返 回 值:void

要 求:若排行榜不存在,新建排行榜;若存在,则按姓名顺序输出排行榜。 (20) 按用时输出排行榜函数

函数原型:void printline(void ) 功 能:按用时多少输出排行榜 参 数:void 返 回 值:void

要 求:若排行榜不存在,新建排行榜;若存在,则按用时多少输出排行榜。 (21) 计算及输出平均成功率函数

函数原型:void countnum(void ) 功 能:计算及输出平均成功率 参 数:void 返 回 值:void

要 求:若count文件不存在,新建count;若存在,则计算及输出平均成功率。 (22) 插入链表函数

函数原型:player *inset(player *head,player *stud) 功 能:插入新纪录链表

参 数:player *head,player *stud:需要被插入的链表的头指针和需要插入表 返 回 值:player *head:处理后的链表的头指针

要 求:将新纪录插入到比起大或与之相等的记录前。 (23) 删除记录函数

函数原型:player *inset(player * head,int n) 功 能:删除链表中的第十六个记录

参 数:player *head,int n:需要被处理的链表的头指针和链表跟新前的记录个

返 回 值:player *head:处理后的链表的头指针

要 求:若n=15,是第十六个表中的next的值赋为NULL。 (24) 表链函数

函数原型:pl(); pl0() 功 能:输出特定的表链 参 数:void 返 回 值:void

要 求:完成输出。

四.程序代码

17

1. start.h

#include\#include #include #include\#include\#include //定义player数组 typedef struct a {

char name[22]; //玩家用户名 int t; //猜数字所用次数 int sj; //游戏所用时间 struct a *next; } player;

//定义struct winave数组 struct winave {

int wintime; //总共赢的次数 float ave; //才正确平均所用次数 };

//函数声明

void refresh(char name[],int t,int js); void note(int i); FILE *resetline(FILE *fp); //…… void resetcount(void); //初始化记录文件的函数 void printline(); void printname(); void printtime(); void pl(); void pl0(); void gamezone(); void checkcount(float count[]); player *inset(player *head,player *p2); player *del(player *head,int n); void main1(); void liulan(); void qk(); void qkmenu(); void qingkong(); void pn(); void rscountmenu(); void setcount(); void sc(); void st(); void printcount(); void help(); void end();

void mainmenu(); void menu2(); void menu3(); void rulemenu();

void paihangbang(); void phbmenu(); void countwork(); void countmenu(); void explainmenu();

18

void endmenu();

int Time_get(time_t first,time_t second); void countnum();

void check(); //检查函数 void move(int i,int j); //“到达”函数

2. start.c

#include\void main() //开始程序 {

printf(\ pl();

printf(\ 欢迎来到猜数字游戏!!!\\n\\n\\n\\n\\n\\n\\n\ pl0();

printf(\ (请按任意键进入菜单)\ getch(); main1(); }

void mainmenu() //主菜单 {

system (\

printf(\

***************\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\ 1.开始游戏\\n\\n\ printf(\ 2.游戏记录\\n\\n\ printf(\ 3.帮助\\n\\n\ printf(\ 4.退出游戏\\n\\n\

printf(\ 请按键选择,回车确定\\n\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\

***************\

}

void menu2() //游戏记录菜单 {

system (\

printf(\

***************\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

19

printf(\ 1.排行榜\\n\\n\ printf(\ 2.count文件\\n\\n\ printf(\ 3.返回主菜单 \\n\\n\

printf(\ 请按键选择,回车确定\\n\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\

***************\

return ; }

void phbmenu() //浏览排行榜菜单 {

system (\

printf(\

***************\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\ 1.按排名浏览排行榜\\n\\n\ printf(\ 2.按姓名浏览排行榜\\n\\n\ printf(\ 3.按用时浏览排行榜\\n\\n\ printf(\ 4.重置排行榜\\n\\n\ printf(\ 5.返回上一菜单 \\n\\n\ printf(\ 6.返回主菜单 \\n\\n\

printf(\ 请按键选择,回车确定\\n\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\

***************\

return ; }

void countmenu() //浏览count文件菜单 {

system (\

printf(\

***************\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\ 1.显示count文件信息 \\n\\n\ printf(\ 2.清空count文件 \\n\\n\ printf(\ 3.返回上一菜单 \\n\\n\ printf(\ 4.返回主菜单 \\n\\n\

printf(\ 请按键选择,回车确定\\n\

20

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\

***************\

return ; }

void qkmenu() //清空排行榜菜单 {

system (\

printf(\

***************\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\ 1.清空排行榜\\n\\n\

printf(\ 2.同时重置count文件\\n\\n\

printf(\请按退格键返回上一菜单,请按键选择(不需回车确定)\\n\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\

***************\

return ; }

void rscountmenu() //重置count文件菜单 {

system (\

printf(\

***************\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\ 1.重置count文件数据\\n\\n\ printf(\ 2.同时清空排行榜\\n\\n\

printf(\请按退格键返回上一菜单,请按键选择(不需回车确定)\\n\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\

***************\

return ; }

void menu3() //帮助菜单

21

{

system (\

printf(\

***************\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\ 1.游戏规则\\n\\n\ printf(\ 2.游戏说明\\n\\n\ printf(\ 3.返回主菜单 \\n\\n\ /*printf(\ 4.重置排行榜\\n\\n\

printf(\ 请按键选择,回车确定\\n\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^ ^_^ ^_^*\

printf(\

***************\

return ; }

void move(int i,int j) //“到达”函数 {

COORD c;//声明坐标变量 c.X=i;//横坐标为x-1 c.Y=j;//纵坐标为y-1

SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c); //使光标返回

开头

return ; }

void rulemenu() //游戏规则 {

int i,j;

system (\

printf(\游戏规则:\\n\

printf(\ printf(\ printf(\①:游戏开始,系统随机产生一位不重复的4位数字。\\n\ putchar('\\n');

printf(\ ▲ ②:游戏者输入所猜的不重复数字,并按回车提交(直接输入,不

\\n\

printf(\可用空格隔开)。\\n\ putchar('\\n');

printf(\③:系统将提交的数与它自动产生的数进行比较,输出结果\\n\

printf(\“*A*B”形式。其中A代表数字正确相应位置也正确,B代表数字正\\n\ printf(\确但位置不正确。如:1A3B表示游戏者有1个数字的位置正确且数值\\n\

22

printf(\也正确,除此以外,游戏者还猜对了3个数字,但位置不对,即游戏\\n\ printf(\者已经猜出4位数据,但有3个数据位置不对!\\n\ putchar('\\n');

printf(\④:游戏者有限的十次数的猜测机会,在规定次数内完成,则游戏\\n\ printf(\成功。否则,游戏失败。其中,猜测次数与成绩有关:\\n\ printf(\次数越少,成绩越高。\\t\\n\ putchar('\\n');

printf(\⑤:游戏排行榜中名次,只决定于成绩。\\n\

printf(\ printf(\ printf(\

printf(\按退格键返回帮助菜单,其他键返回主菜单。\ i=10; j=0; move(i,j); //光标回到窗口的顶端 if(getch()==8) help(); else main1(); }

void explainmenu() {

int i,j,k=0; char A;

system (\

printf(\游戏说明:\\n\k++;

printf(\

k++;

printf(\

k++; printf(\①:此游戏有计时功能。进入游戏后开时计时,猜正确后计时结束。

\\n\

k++; printf(\游戏过程中不显示时间,只有成功猜出数字后才会提示所用时间。\\n\k++; putchar('\\n');

k++; printf(\②:进入游戏后,可输入“rt”可返回主菜单;输入“rp”可\\n\k++; printf(\重新开始游戏 。\\n\k++; putchar('\\n');

k++; printf(\③:游戏中有浏览排行榜功能。\\n\

k++; printf(\可分别按照成绩、用户名、所用时间的顺序进行浏览。\\n\k++; printf(\其中只显示前十名成绩的记录,且最多显示15名玩家。\\n\

k++; printf(\按用户名名输出排行版功能中,数字优先于字母,字母优先于文字的

\\n\

k++; printf(\规则进行排序。\\n\k++; putchar('\\n');

k++; printf(\④:在浏览表最后,显示最近一次重置排行榜或第一次游戏以来所有

\\n\

23

k++; k++; k++; k++;

算\\n\

printf(\玩家猜正确的总共人次和所有玩家猜正确的平均所用次数\\n\printf(\则游戏成功。否则,游戏失败。其中,猜测次\\n\putchar('\\n'); printf(\⑤:所有玩家参与游戏后,分别以1到10次猜正确的平均成功率的计

k++; printf(\公式为:\\n\

k++; printf(\ 用1次猜中数字的成功率+用2次猜中数字的成功率+…+用十次猜

中数\\n\

k++; printf(\字的成功率的和除以10。\\n\k++; putchar('\\n');

k++; printf(\⑥:count储存信息请查看其输出。(在游戏记录选项中)\\n\k++; printf(\其中“所占比例”表示占成功次数的比例\\n\k++; putchar('\\n');

k++; printf(\⑦:在主菜单下,选择菜单5(菜单上未显示)。可检查count文件中

\\n\

k++; printf(\数据,和排行榜的起始时间与count文件中数据的起始时间。\\n\k++;

printf(\

k++;

printf(\

k++; printf(\ 游戏设计者:华南农业大学 09级软件工程R3 谢泽雄\\n\k++;

printf(\

k++;

printf(\

k++; printf(\

k++; printf(\是否顶端开头(Y/N)? \//k用以统计输出的行数 i=10; j=0; move(i,j); //光标回到窗口的顶端 A=getch();

i=19; move(i,k); //光标回到最下方输出处 while(A!='Y'&&A!='y'&&A!='N'&&A!='n') { putchar(A); k++; printf(\★☆输入错误☆★ 请输入Y/N: \ A=getch(); }

if(A=='Y'||A=='y') { if(A=='y') printf(\ else printf(\ explainmenu(); //回到开头 }

i=0; move(i,k); //光标回到最下方输出处

24

//再次实现move(i)是为了应对输入错误的情况 printf(\按退格键返回帮助菜单,其他键返回主菜单。\ if(getch()==8) help(); else main1(); }

void endmenu() //结束菜单 {

system (\ printf(\

printf(\** ** **** ** ** ** **

*** \\n\

printf(\** ** ** ** **** ** ** **

***** \\n\

printf(\ ** ** ** ** ** ** ** ** ** **

******* \\n\

printf(\ ** ** ** ** ** ** ** ** ** **

******* \\n\

printf(\ ** *********** ************* ** ** ** ****

***** \\n\

printf(\ ** *********** ************* ** ** ** ****

***** \\n\

printf(\ ** ** ** ** ** ** ** ** ** **

***** \\n\

printf(\ ** ** ** ** ** ** ** ** ** **

*** \\n\

printf(\ ** ** ** ** ** ** **** ** **

*** \\n\

printf(\ ** ** ** ** ** ** ** ** **

*** \\n\

printf(\ Byebye...\ printf(\ 欢迎使用本软件!!!\ getch(); }

3. mianzone.c

#include\

void main1()//被主函数调用,用以开始进入游戏 {

char choose[10]; mainmenu(); gets(choose);

while(strlen(choose)!=1) { printf(\请只选择一项进行操作:\

25

gets(choose); }

while(choose[0]!='1'&&choose[0]!='2'&&choose[0]!='3'&&choose[0]!='4'&&choose[0]

!='5')

{ printf(\请选择正确选项:\ gets(choose);

}/*也可用default:printf(\实现*/

switch(choose[0])//功能函数选择 {

case '1':gamezone();break; case '2':liulan();break; case '3':help();break; case '4':end();

case '5':check();break; } }

void liulan() //进入浏览排行榜功能 {

char choose; menu2();

choose=getchar();getchar(); switch(choose)//功能函数选择 {

case '1':paihangbang();break; case '2':countwork();break; case '3':main1();break;

default:printf(\请重新输入:\ } }

void paihangbang() //进入排行榜功能 {

char choose; phbmenu();

lp: choose=getchar();getchar(); switch(choose)//功能函数选择 {

case '1':printline();break; case '2':printname();break;

26

case '3':printtime();break; case '4':qk();break; case '5':liulan();break; case '6':main1();break;

default:printf(\请重新输入:\ goto lp; } }

void countwork() //进入count文件浏览功能 {

char choose; countmenu();

lp: choose=getchar();getchar(); switch(choose)//功能函数选择 {

case '1':printcount();break; case '2':st();break; case '3':liulan();break; case '4':main1();break;

default:printf(\请重新输入:\ goto lp; } }

void qk() //清空排行榜功能 {

char choose; int t=0; qkmenu();

lp: choose=getch();

if(choose==8) paihangbang(); switch(choose) //功能函数选择 {

case '1':qingkong();break; case '2':pn();break;

default:printf(\请重新输入:\ } }

void pn() //进入重置排行榜和count文件功能 {

FILE *fp; char A;

27

printf(\是否重置排行榜和count文件(Y/N)?\ A=getch();

while(A!='Y'&&A!='y'&&A!='N'&&A!='n') { printf(\★☆输入错误☆★ 请输入Y/N:\ A=getch(); }

if(A=='Y'||A=='y') { if(A=='y') printf(\ else printf(\ fp=fopen(\ fp=resetline(fp); //重置排行榜 fclose(fp); resetcount();//重置count文件(无厘头出问题)***************************** printf(\重置成功!!\\n请按任意键返回主菜单\ getch(); main1(); }

else liulan(); }

void qingkong() //进入重置排行榜功能 {

FILE *fp; char A;

printf(\是否重置排行榜(Y/N)?\ A=getch();

while(A!='Y'&&A!='y'&&A!='N'&&A!='n') { printf(\★☆输入错误☆★ 请输入Y/N:\ A=getch(); }

if(A=='Y'||A=='y') { if(A=='y') printf(\ else printf(\ fp=fopen(\ fp=resetline(fp); //重置排行榜 fclose(fp); printf(\重置成功!!\\n请按任意键返回主菜单\ getch(); main1(); }

28

else liulan(); }

void st() //进入重置count文件 {

char choose; int t=0;

rscountmenu();

lp: choose=getch();

if(choose==8) countwork(); switch(choose) //功能函数选择 {

case '1':setcount();break; case '2':sc();break;

default:printf(\请重新输入:\ } }

void sc() //进入重置count文件和排行榜 {

FILE *fp; char A;

printf(\是否重置count文件和排行榜(Y/N)?\ A=getch();

while(A!='Y'&&A!='y'&&A!='N'&&A!='n') { printf(\★☆输入错误☆★ 请输入Y/N:\ A=getch(); }

if(A=='Y'||A=='y') { if(A=='y') printf(\ else printf(\ fp=fopen(\ fp=resetline(fp); //重置排行榜 fclose(fp); resetcount(); printf(\重置成功!!\\n请按任意键返回主菜单\ getch(); main1(); }

else liulan();

29

}

void setcount() //进入清空count文件功能 {

char A;

printf(\是否清空count文件(Y/N)?\ A=getch();

while(A!='Y'&&A!='y'&&A!='N'&&A!='n') { printf(\★☆输入错误☆★ 请输入Y/N:\ A=getch(); }

if(A=='Y'||A=='y') { if(A=='y') printf(\ else printf(\ resetcount();//重置count文件 printf(\重置成功!!\\n请按任意键返回主菜单\ getch(); main1(); }

else liulan(); }

void printcount() //输出count文件数据函数 {

float count[13]; int i;

float sum=0; system(\ pl();

checkcount(count); for(i=1;i<11;i++) sum+=count[i];

printf(\玩家参加游戏次数:%2.0f(次)\\n\ for(i=1;i<11;i++) { printf(\在第-次得到准确答案的玩家人数:%2.0f(名)\ if(count[0]>0) printf(\所占比例为: %6.2f%c\

加上小数点有 六 位!

putchar('\\n'); } pl0(); i=4;

30

note(i);

printf(\(请按任意键返回主菜单)\ getch(); main1(); }

void help() //进入帮助功能 {

char choose; int t=0; menu3();

choose=getchar();getchar(); switch(choose)//功能函数选择 {

case '1':rulemenu();break; case '2':explainmenu();break; case '3':main1();break;

/*case '3':qingkong();break;*/

default:printf(\请重新\ help(); } }

void end() //进入结束功能 {

char A;

system(\

printf(\ 是否退出游戏(Y/N)?\ A=getch();

while(A!='Y'&&A!='y'&&A!='N'&&A!='n') { printf(\★☆输入错误☆★ 请输入Y/N:\ A=getch(); }

if(A=='Y'||A=='y') { if(A=='y') printf(\ else printf(\ endmenu(); exit(0); }

else main1(); }

31

void check() {

FILE *fp; int i;

float count[13]; for(i=0;i<13;i++) count[i]=0;

count[i]='\\0';//初始化count[]数组

printf(\ ***恭喜您,进入了测试功能!***\\n\ printf(\文件的数据:\\n\ fp=fopen(\

if(fp==NULL) printf(\文件不存在!!!\\n\ else { for(i=0;i<13;i++) fscanf(fp,\ for(i=0;i<12;i++) printf(\ fclose(fp); }

printf(\接下来,测试数据记录最近初始化的时间:\\n\

printf(\请输入i(3/4),不需回车确定:(3是排行榜,4是count文件)\ scanf(\ while(i!=3&&i!=4) { printf(\请重新输入:\ scanf(\ }

note(i);

printf(\按任意键退出该功能!\ getch(); main1(); }

4. gamezone.c

#include\

void checkcount(float count[]) //检查count的情况 且 读取count中数据 {

FILE *fp; int i; char A;

fp=fopen(\

32

if(fp==NULL) //count文件不存在或打开失败 { lp: printf(\数据初始化失败,游戏将强制初始化!\\n\ printf(\是否强制初始化游戏数据(Y/N)?\ A=getch(); while(A!='Y'&&A!='y'&&A!='N'&&A!='n') { printf(\★☆输入错误☆★ 请输入Y/N:\ A=getch(); } if(A=='Y'||A=='y') { resetcount(); fp=fopen(\ } //初始化count文件 else main1(); }

for(i=0;i<12;i++) { fscanf(fp,\ if(feof(fp)) goto lp; } //读取count文件数据 fclose(fp); }

void closecount(float count[]) //存储count中的数据 { int i;

FILE *fp;

fp=fopen(\ for(i=0;i<13;i++) fprintf(fp,\//将新的count[]数组的值写入文件 fclose(fp); }

void creat(char key[]) //定义生成随机数函数 {

int i,j;

loop: srand((unsigned int)time(0)); for(i=0;i<4;i++) key[i]=rand();

for(i=0;i<3;i++) //判断生成的答案中是否有重复数字 for(j=i+1;j<4;j++) if(key[j]==key[i]) goto loop;

33

}

void checknum(char guess[]) //定义检查输入函数 {

int i,j;

printf(\请输入四个数字(0~9):\ gets(guess);

if(strlen(guess)==2) //判断guess[]的长度是否为2,而进行特殊处理 { if(!strcmp(guess,\//重新开始游戏 if(!strcmp(guess,\//返回主菜单 }

while(strlen(guess)!=4) //判断输入的guess[]的长度是否为4 { printf(\★☆输入无效,请重新输入!☆★\ checknum(guess);break; }

for(j=0;j<4;j++) //判断输入的guess[]是否存在非数字字符 if(guess[j]>'9'||guess[j]<'0') { printf(\★☆输入无效!存在非数字字符。请重新输入!☆★\ checknum(guess);break; }

for(i=0;i<3;i++) //判断输入的guess[]是否存在重复数字 for(j=i+1;j<4;j++) if(guess[i]==guess[j]) { printf(\★☆输入无效!数字有重复。请重新输入!☆★\ checknum(guess);break; } }

int Time_get(time_t first,time_t second) //计算所用时间 { int a;

a=(int)difftime(second,first); //difftime()的返回值为double类型 return a; }

void gamezone() //游戏函数 {

char key[5],guess[5]; //定义答案与输入数组

34

char A,B;

char win=0; //标记是否赢得游戏 char name[22]; //记录玩家用户名 int sj; //记录所用时间 int i,j;

int t=1; //记录所用次数 time_t first,second; //获取时间

float count[13]; //定义count[]数组 for(i=0;i<12;i++) count[i]=0;

count[i]='\\0';//***初始化count[]数组*** key[4]='\\0';

printf(\ 游戏初始化,请稍等!!!\生成随机数函数 的运行用时不顶 checkcount(count); //检查count.txt的情况 creat(key); //生成随机数(运行时间不定) system(\清屏 for(i=0;i<4;i++) { key[i]+='0'; printf(\测试用*/ }

//将key[]转化为对应的数字字符 pl();

printf(\ 游戏开始!\

printf(\(重新开始请输入“rp”,返回主菜单请输入“rt”)\fflush(stdin); //清除内存中所保存的输入数据

first=time(NULL);//************计时开始************ for(t=1;t<11;t++) { checknum(guess); //检查输入 if(t==3) //增加玩家游戏次数 { count[0]++; closecount(count); } if(!strcmp(key,guess)) { win=1;break; } else { for(i=0,A=0;i<4;i++) if(key[i]==guess[i]) A++; //统计完全正确的数字个数 for(i=0,B=0;i<4;i++) for(j=0;j<4;j++) if(key[i]==guess[j]) B++; //统计数值正确的数字个数 printf(\第%d次猜数,您的输入有 ú ?\

35

} if(t==7) printf(\剩下3次机会,加油!!!加

油!!!->_<-_*********************\

}

second=time(NULL);//************计时结束************ if(win==1) { if(t==11) t=10; if(t<3) count[0]++; count[t]++; closecount(count); //保存count.txt的数据 printf(\ sj=Time_get(first,second); //计算用时 printf(\您本次游戏所用时间为:%d分钟%d秒\\n\\n\ printf(\请输入用户名(1~20个字符):\ gets(name); //获取用户名 while((i=strlen(name))>20||i<1) { printf(\★☆您输入的用户名长度>20\\n\ printf(\★☆请重新输入:\ gets(name); } //检查用户名格式 refresh(name,t,sj); //刷新排行榜记录 { printf(\是否浏览排行榜(Y/N)?\ A=getch(); while(A!='Y'&&A!='y'&&A!='N'&&A!='n') { printf(\★☆输入错误☆★ 请输入Y/N:\ A=getch(); } if(A=='Y'||A=='y') { printf(\ printline(); } else printf(\ } { printf(\是否继续游戏(Y/N)?\ } } else

36

{ printf(\ Game over!\ printf(\本次答案为:\ puts(key); //输出正确答案 printf(\是否继续(Y/N)?\ }

A=getch();

while(A!='Y'&&A!='y'&&A!='N'&&A!='n') { printf(\★☆输入错误☆★ 请输入Y/N:\ A=getch(); }

if(A=='Y'||A=='y') { printf(\ gamezone(); } else { printf(\ main1(); } }

5. refreshline.c

#include\

void refresh(char name[],int t,int sj) {

FILE *fp; int i=0;

player record,*p1,*p2,*head;

struct winave jilu; //包含int wintime和float ave在其中 int n=0; //用来记录有几个排名者 fflush(stdin); pl0();

fp=fopen(\

if(!fp) //如果打开文件失败 { printf(\无法找到排行榜记录\\n\\n\ printf(\游戏将重新设置排行榜\\n\\n\ /*fclose(fp);因为打开失败,fp无指向,并没有赋予有意义的值。 在运行fclose()时要读取fp,但fp无效。所以运行错

误!*/

fp=fopen(\fp=resetline(fp);

37

printf(\请按任意键继续。\ getch(); } if(fread(&jilu,sizeof(struct winave),1,fp)==0) { printf(\排行榜错误,请重置排行榜!(按任意键继续)\ getch(); liulan(); }

jilu.ave=(jilu.ave*jilu.wintime+t)/(++jilu.wintime);

head=p1=(player *) malloc(sizeof(player));//分配sizeof(player)大小 while(fread(p1,sizeof(player),1,fp)) { p2=p1; p1=(player *) malloc(sizeof(player)); p2->next=p1; n++; //记数 }

p2->next=NULL; fclose(fp); p1=head;

strcpy(record.name,name);record.t=t;record.sj=sj; head=inset(head,&record);/*从第三次开始,只要t>之前的最大值就无法成功插入(在

实验楼)*/

head=del(head,n); p1=head;

fp=fopen(\

fwrite(&jilu,sizeof(struct winave),1,fp); while(p1!=NULL) { fwrite(p1,sizeof(player),1,fp); p1=p1->next; }

fclose(fp); i=1; note(i); }

void note(int i) {

FILE *fp;

38

int j;

int sign=0;

time_t time0[2];

char tmp[64]; fp=fopen(\

if(fp==NULL) //count文件丢失 { //重置count文件 time0[0]=time(0); fp=fopen(\ for(j=0;j<2;j++) fwrite(&time0[0],sizeof(time_t),1,fp); fwrite(&sign,sizeof(int),1,fp); fclose(fp); fp=fopen(\ }

for(j=0;j<2;j++) fread(&time0[j],sizeof(time_t),1,fp); fread(&sign,sizeof(int),1,fp); fclose(fp);

if(sign==0&&i>2) { printf(\数据起始时间丢失***\\n\

printf(\***********\

} else { switch(i) //功能函数选择 { case 1: //更新排行榜重置时间 case 2: //更新count重置时间 fp=fopen(\ time0[--i]=time(0); sign++; for(j=0;j<2;j++) fwrite(&time0[j],sizeof(time_t),1,fp); fwrite(&sign,sizeof(int),1,fp); fclose(fp); break; case 3: //输出排行榜重置时间 case 4: //输出count重置时间

39

fp=fopen(\ i=i/2-1; strftime(tmp,sizeof(tmp),\ %X %A 本年第%j

天 %z\

printf(\以上数据记录起始时间为:\\n\\t \ puts(tmp);

printf(\***********\

fclose(fp); break; } } }

6. reset.c

#include\

FILE *resetline(FILE *fp)//清空或重置排行榜 {

struct winave jilu; //定义jilu变量 int i; player p;

jilu.wintime=0; jilu.ave=0.0;

strcpy(p.name,\谢泽雄(无效)\p.t=11; p.sj=360; //初始化数值 fwrite(&jilu,sizeof(struct winave),1,fp);

fwrite(&p,sizeof(player),1,fp); //写入数据 fclose(fp);

i=1; note(i); //记录初始化时间 fp=fopen(\ return fp;

}//返回以\打开的文件指针

void resetcount(void) //重置count.txt文件 {

float count[13];

/*count[0]存储游戏总次数;

count[1]到count[10]储存相对应的赢游戏所需次数的总数; 其他无用。 */

FILE *fp; //定义文件指针 int i;

for(i=0;i<12;i++) { count[i]=0.0; }

40

count[i]='\\0'; //初始化数值 fp=fopen(\ for(i=0;i<13;i++) fprintf(fp,\ fclose(fp);

i=2; note(i); //记录初始化时间 return ;

}//不返回文件指针

print.c

#include\

void printline() //按成绩输出排行榜 {

int i,score;

FILE *fp=NULL; player r;

struct winave jilu; int paiming; char goon; char choice; system(\ pl();

if((fp=fopen(\//判断排行榜是否存在 { printf(\打开排行榜失败,是否重新建立排行榜(Y/N)?\ choice=getch(); while(choice!='y'&&choice!='Y'&&choice!='n'&&choice!='N') { printf(\★☆输入无效☆★请重新输入:\ choice=getch(); } if(choice=='Y'||choice=='y') { fp=fopen(\ fp=resetline(fp); printf(\重新建立成功!\\n\ fclose(fp); } printf(\请按任意键返回主菜单。\ getch(); main1(); } else {

41

7. if(fread(&jilu,sizeof(struct winave),1,fp)==0) { printf(\排行榜错误,请重置排行榜!(按任意键继续)\ getch(); liulan(); } if(jilu.wintime==0) { printf(\排行榜未有记录!\\n\ printf(\请参加游戏刷新排行榜!\\n\ printf(\按任意键返回主菜单)\ getch();fclose(fp); main1(); } else { printf(\ ***按排名顺序输出排行榜***\\n\\n\ printf(\行数\\t排名\\t次数\\t 所用时间 \\t 玩家姓名\\n\ for(i=0,score=0,paiming=0,goon=0;i<10;i++) //输出排行榜 { fread(&r,sizeof(player),1,fp); if(feof(fp)) break; //feof()是否结束,结束为1,否则为0 (也可以放在

上面的for()中)

else { if(score==r.t) goon=1; //判断paiming是否应加1 else { paiming++;goon=0; } printf(\ %d\\t %d\\t %d\\t %d分钟-秒

\\t %s\\n\

score=r.t; } } while(!feof(fp)) //判断是否输出排名在十名后的玩家信息,是则输出,

否则结束

{ fread(&r,sizeof(player),1,fp); if(score!=r.t) break; printf(\ %d\\t %d\\t %d\\t %d分钟-秒

\\t %s\\n\

score=r.t; i++; } fclose(fp); //关闭文件 putchar('\\n');

42

pl0(); printf(\ 所有玩家猜正确的总共人次: %d (人次)

\\n\

printf(\ 所有玩家猜正确的平均所用次数: %.4f(次)\\n\

printf(\***********\

countnum(); //输出平均成功率 pl(); i=3; note(i); //输出排行榜数据其实时间 printf(\按任意键返回主菜单\ i=0; move(i,i); //光标回到窗口的顶端 i=0; score=4; move(i,score); //光标榜头 getch(); main1(); } } }

void printname() //按姓名输出排行榜 {

int i,score;

FILE *fp=NULL; int k,j;

player r,plr[17];

struct winave jilu;/*int wintime; float ave;(在其中)*/ int paiming,pm[17]; char goon; char choice; system(\ pl();

if((fp=fopen(\//判断排行榜是否存在 { printf(\打开排行榜失败,是否重新建立排行榜(Y/N)?\ choice=getch(); while(choice!='y'&&choice!='Y'&&choice!='n'&&choice!='N') { printf(\★☆输入无效☆★请重新输入:\ choice=getch(); } if(choice=='Y'||choice=='y') { fp=fopen(\ fp=resetline(fp);

43

printf(\重新建立成功!\\n\ fclose(fp); } printf(\请按任意键返回主菜单。\ getch(); main1(); } else { if(fread(&jilu,sizeof(struct winave),1,fp)==0) { printf(\排行榜错误,请重置排行榜!(按任意键继续)\ getch(); liulan(); } if(jilu.wintime==0) { printf(\排行榜未有记录!\\n\ printf(\请参加游戏刷新排行榜!\\n\ printf(\按任意键返回主菜单)\ getch();fclose(fp); main1(); } else { printf(\按姓名次序排序输出排行榜***\\n\\n\ printf(\行数\\t排名\\t次数\\t 所用时间 \\t 玩家姓名\\n\ for(i=0,score=0,paiming=0,goon=0;i<10;i++) { fread(&r,sizeof(player),1,fp); /*{printf(\ if(feof(fp)) break;//feof()是否结束,结束为1,否则为0 (也可以放在上

面的for()中)

/*if(r.t==11) break;*/ else { if(score==r.t) goon=1;//判断paiming是否应加1 else { paiming++;goon=0; } strcpy(plr[i].name,r.name);plr[i].t=r.t;pm[i]=paiming; plr[i].sj=r.sj; score=r.t; } } while(!feof(fp)) { fread(&r,sizeof(player),1,fp);

44

if(score!=r.t) break; strcpy(plr[i].name,r.name);plr[i].t=r.t;pm[i]=paiming; plr[i].sj=r.sj; score=r.t; i++; } fclose(fp); //关闭文件 k=i; for(j=0;j

换“用户名”数据

r.t=pm[i];pm[i]=pm[i+1];pm[i+1]=r.t; //交

换“排名”数据

r.t=plr[i].t;plr[i].t=plr[i+1].t;plr[i+1].t=r.t; //交换“成绩”

数据

r.sj=plr[i].sj;plr[i].sj=plr[i+1].sj;plr[i+1].sj=r.sj; //交换“用时”

数据

} for(i=0;i

\\t %s\\n\

putchar('\\n'); pl0(); printf(\ 所有玩家猜正确的总共人次: %d (人次)

\\n\

printf(\ 所有玩家猜正确的平均所用次数: %.4f(次)\\n\

printf(\***********\

countnum(); //输出平均成功率 pl(); i=3; note(i); //输出排行榜数据其实时间 printf(\按任意键返回主菜单\ i=0; move(i,i); //光标回到窗口的顶端 i=0; score=4; move(i,score); //光标榜头 getch(); main1(); } }

45

}

void printtime() //按用时输出排行榜 {

int i,score;

FILE *fp=NULL; int k,j;

player r,plr[17];

struct winave jilu;/*int wintime; float ave;(在其中)*/ int paiming,pm[17]; char goon; char choice; system(\ pl();

if((fp=fopen(\//判断排行榜是否存在 { printf(\打开排行榜失败,是否重新建立排行榜(Y/N)?\ choice=getch(); while(choice!='y'&&choice!='Y'&&choice!='n'&&choice!='N') { printf(\★☆输入无效☆★请重新输入:\ choice=getch(); } if(choice=='Y'||choice=='y') { fp=fopen(\ fp=resetline(fp); printf(\重新建立成功!\\n\ fclose(fp); } printf(\请按任意键返回主菜单。\ getch(); main1(); } else { if(fread(&jilu,sizeof(struct winave),1,fp)==0) { printf(\排行榜错误,请重置排行榜!(按任意键继续)\ getch(); liulan(); } if(jilu.wintime==0) {

46

printf(\排行榜未有记录!\\n\ printf(\请参加游戏刷新排行榜!\\n\ printf(\按任意键返回主菜单)\ getch();fclose(fp); main1(); } else { printf(\按所用时间排序输出排行榜***\\n\\n\ printf(\行数\\t排名\\t次数\\t 所用时间 \\t 玩家姓名\\n\ for(i=0,score=0,paiming=0,goon=0;i<10;i++) { fread(&r,sizeof(player),1,fp); if(feof(fp)) break;//feof()是否结束,结束为1,否则为0 (也可以放在上

面的for()中)

else { if(score==r.t) goon=1;//判断paiming是否应加1 else { paiming++;goon=0; } strcpy(plr[i].name,r.name);plr[i].t=r.t;pm[i]=paiming; plr[i].sj=r.sj; score=r.t; } } while(!feof(fp)) { fread(&r,sizeof(player),1,fp); if(score!=r.t) break; strcpy(plr[i].name,r.name);plr[i].t=r.t;pm[i]=paiming; plr[i].sj=r.sj; score=r.t; i++; } fclose(fp); //关闭文件 k=i; for(j=0;jplr[i+1].sj) { strcpy(r.name,plr[i].name); strcpy(plr[i].name,plr[i+1].name); strcpy(plr[i+1].name,r.name); //交

换“用户名”数据

r.t=pm[i];pm[i]=pm[i+1];pm[i+1]=r.t; //交

换“排名”数据

r.t=plr[i].t;plr[i].t=plr[i+1].t;plr[i+1].t=r.t; //交换“成绩”

47

数据

数据

} for(i=0;i

\\t %s\\n\

putchar('\\n'); pl0(); printf(\ 所有玩家猜正确的总共人次: %d (人次)

\\n\

printf(\ 所有玩家猜正确的平均所用次数: %.4f(次)\\n\

printf(\***********\

countnum(); //输出平均成功率 pl(); fclose(fp); //关闭文件 i=3; note(i); //输出排行榜数据其实时间 printf(\按任意键返回主菜单\ i=0; move(i,i); //光标回到窗口的顶端 i=0; score=4; move(i,score); //光标榜头 getch(); main1(); } } }

r.sj=plr[i].sj;plr[i].sj=plr[i+1].sj;plr[i+1].sj=r.sj; //交换“用时”

8. count_num.c

#include\

void countnum() //计算及输出平均成功率 {

float count[13]; float shuanshu=0; int i;

for(i=0;i<12;i++) count[i]=0;

count[i]='\\0';//***初始化count[]数组*** checkcount(count); if(count[0]==0.0) printf(\所有玩家参与游戏后,分别以1到10次猜正确的平均成功率为:(暂

无记录)\\n\

else { for(i=1;i<11;i++)

48

{ shuanshu+=count[i]; } shuanshu=shuanshu/count[0]; printf(\所有玩家参与游戏后,分别以1到10次猜正确的平均成功率

为:%.2f%c\Ⅱ码中37代表百分号

putchar('\\n');

} //计算公式为{ (count[1]+…+count[10])/count[0] } / 10 * 100% } //赢得次数总和 除以 参加游戏总次数 再除以10求平均 最后

乘以100% 得

9. intset – del.c

#include\

player *inset(player *head,player *stud) //插入新纪录链表 {

player *p0,*p1,*p2; p1=head; p0=stud;

if(head==NULL)

{ head=p0;p0->next=NULL; } else { while((p0->t>p1->t)&&(p1->next!=NULL)) { p2=p1;p1=p1->next; } if(p0->t<=p1->t) { if(head==p1) head=p0; else p2->next=p0; p0->next=p1; } else { p1->next=p0;p0->next=NULL; } }

return(head); }

player* del(player * head,int n) //定义删除链表中的第十五个表的函数 {

player *p1,*p2;

if(n=15) { p1=head; while(p1->next) {

49

p2=p1; p1=p1->next; } p2->next=NULL; }

return head; }

10. imageline.c

#include\void pl() {

***\

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^

^_^*\

} void pl0() {

***\

}

printf(\ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ printf(\

^_^*\

printf(\

五.运行结果

以下为运行程序的流程:

进入进入界面,按任意键继续,进入“主菜单”:

1. 选择菜单1,开始游戏。玩家可按照游戏提示输入猜测的数字进行游戏。若在猜数字过程中输入“rt”字符串,可放弃游戏返回主菜单;若输入“rp”字符串,可放弃该次游戏重新开始游戏。

2. 选择菜单2,进入“数据记录”菜单:选择菜单1,进入“排行榜”菜单: 2.1. 选择菜单1,进入“排行榜”菜单:

2.1.1 选择菜单1,按排名次序浏览排行榜。浏览排行榜信息,最近一次重置排行榜或第一次游戏以来所有玩家猜正确的总共人次和所有玩家猜正确的平均所用次数以及所有玩家参与游戏后,分别以1到10次猜正确的平均成功率以及排行榜记录的起始时间

2.1.2 选择菜单2,按姓名顺序浏览排行榜。同上。 2.1.3 选择菜单3,按所用时间多少浏览排行榜。同上。 2.1.4 选择菜单4,进入“重置排行榜”菜单:

2.1.4.1 选择菜单1,清空排行榜。

2.1.4.2 选择菜单2,同时重置count文件记录。 2.1.4.3 按退格键,返回“排行榜”菜单。

50