学习时段:2019/10/30 晚上9:00-11:00
学习内容:对扫雷游戏的总体进行设计,采用一个二维数组表示扫雷的棋盘
收获内容:在数组之中数字1表明该位置周围存在一个地雷,以此类推,数字0表明该位置不存在地雷。玩家经过选取数组的元素来进行扫雷的操做。若是选取的元素是数字1则游戏结束,若是通过屡次选取以后若是棋盘上显示的剩余地雷(未展开区域)数目等于游戏设置的地雷数目时,断定游戏完成,并存储游戏成绩(所耗费的时间)。
自我效率评价:较高
学习时段:2019/11/01 晚上7:00-11:00
学习内容:具体代码的编写,完成扫雷的基本功能,例如扫雷函数,打印初始化扫雷数组函数,扫雷的棋盘,随即设置雷的位置,设置布雷函数,编写空白区域展开函数,位置四周地雷数目统计函数,避免第一次选取失败函数。
学习时段:2019/11/02 上午8:00-10:00
学习内容:对编写的代码进行完善
收获内容:增长一些本身要实现的新功能,引用头文件time.h,调用clock()函数计时,成功完成游戏时输出所花费的时间。
自我效率评价:通常
学习时段:2019/11/03 上午8:00-10:00
学习内容:开始撰写博客
收获内容:因为掌握的知识不够全面,有些老师提出的撰写博客的要求可能没达到
自我效率评价:通常
4.解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。
在老师布置做业后,咱们为了异于其余小组,选了扫雷这个游戏,咱们首先是玩了一下电脑上自带的扫雷游戏,在使用者的角度去考虑本身还须要一些什么功能,而后一块儿商议,上课的时候老师还教咱们进行了需求分析,排除一些对咱们这个项目没有实际意义的功能,而且咱们上网查找了实现基本扫雷功能的代码,而后再通过本身努力,增长代码来实现本身所须要实现的新的功能。
5.设计实现过程。设计包括代码如何组织,好比会有几个类,几个函数,他们之间关系如何,关键函数是否须要画出流程图?单元测试是怎么设计的?分析单元测试的合理性与充分性
1. 打印玩家棋盘函数,经过两层for循环对设定的二维数组中的元素进行选取,并x坐标y坐标进行打印,打印设计者所需棋盘与玩家棋盘相似。
2. 布雷函数的编写采用while循环,首先设置棋盘之中雷的总数,以后经过rand()函数随机生成一对x,y坐标,并对预设的real_mine数组之中的[x][y]进行赋值,将该元素赋值为1,表示在该位置进行布雷。完成一次while循环执行一次count--直到最后跳出循环为止。
3. 检测四周位置的地雷总数函数,对周围八个区域也就是二维数组该元素周围的八个元素利用if条件判断进行遍历,一个位置存在地雷就运行自增运算符使得count加1,若是最后运行结果是count=7即为该点周围有七个地雷。
4. 坐标展开函数,对设计者棋盘数组该点周围的八个元素进行遍历,利用if条件判断对该点周围八个位置进行条件判断,同时调用检查四周位置地雷总数的count函数,将count函数的输出结果赋值到玩家数组的相应元素处。
5. 避免第一次被炸死函数,根据输入的坐标对应的设计者棋盘数组中的元素,若是为地雷,采起补救措施,将该元素更改成“0”也就是出去该店的地雷,随后在利用随机数生成函数,在一个没有地雷的位置进行布雷,以后跳出函数。若是第一次输入的坐标对应设计者棋盘数组中的元素不是地雷,则继续执行函数。
6. 判断未知区域地雷个数函数,经过对整个玩家棋盘数组进行遍历,对地雷位置进行计数,若是技术结果等于预先设定地雷个数则断定玩家胜利。
7. 扫雷函数,首先判断输入的坐标是否符合预设要求,若是符合进行下一步操做,若是输入坐标对应设计者棋盘数组之中元素为0,则为踩到雷,以后将玩家数组的对应元素变为“0”,随后调用坐标展开函数,调用坐标展开函数后判断未知区域的地雷个数,若是等于预设的地雷个数,则断定为玩家胜利
6.记录
在改进程序性能上所花费的时间,描述你改进的思路,并展现一张性能分析图(由性能分析工具自动生成),并展现你程序中消耗最大的函数。
改进思路主要是在实现现有扫雷基础上增长一个计时功能,而且可以存储,同时游戏进行时第一次踩雷保证本身不会被炸死
性能分析图以下:
7.代码说明。展现出项目关键代码,并解释思路与注释说明
保证第一次不被炸死,代码以下:
void safe_mine()//避免第一次炸死
{
int x = 0;
int y = 0;
char ch = 0;
int count = 0;
int ret = 1;
printf("输入坐标扫雷\n");
while (1)
{
scanf("%d%d", &x, &y);//只能输入1到10,输入错误从新输入
if ((x >= 1 && x <= 10) && (y >= 1 && y <= 10))//判断输入坐标是否有误
{
if (real_mine[x][y] == '1')//第一次踩到雷后补救
{
real_mine[x][y] = '0';
char ch = count_mine(x, y);
show_mine[x][y] = ch + '0';//数字对应的ASCII值和数字字符对应的ASCII值相差48,即'0'的ASCII值
open_mine(x, y);
while (ret)//在其他有空的地方设置一个雷
{
int x = rand() % 10 + 1;//产生1到10的随机数,在数组下标为1到10的范围内布雷
int y = rand() % 10 + 1;//产生1到10的随机数,在数组下标为1到10的范围内布雷
if (real_mine[x][y] == '0')//找不是雷的地方布雷
{
real_mine[x][y] = '1';
ret--;
break;
}
}break;//跳出此函数
}
if (real_mine[x][y] == '0')
{
char ch = count_mine(x, y);
show_mine[x][y] = ch + '0';//数字对应的ASCII值和数字字符对应的ASCII值相差48,即'0'的ASCII值
open_mine(x, y);
break;
}
}
else//坐标错误
{
printf("输入错误从新输入\n");
}
}
}
}
将扫雷成功后所用时间存储进data.txt文件之中。具体代码以下:
int fileopen()
{
FILE* fp;//文件指针
/*文件的打开*/
fp = fopen("data.txt", "a");//fopen打开文件,这个文件能够是当前不存在的。“a”以写入的形式打开,“r”以读的形式打开
if (fp == NULL) //判断若是文件指针为空
{
printf("File cannot open! ");
exit(0);//在以0的形式退出,必须在文件开头有#include <stdlib.h>,stdlib 头文件即standard library标准库头文件
}
//写入东西
fprintf(fp, "用时:%u 秒\n", clock() / CLOCKS_PER_SEC);//写入指针fp,写入的东西就是刚才的用户输入的d,注意这里的fp和d没有引号
//关闭文件
fclose(fp);
return 0;
}
8.结合在构建之法中学习到的相关内容与我的项目的实践经历,撰写解决项目的心路历程与收获。
在这几天的学习过程之中,采用了许多方案,曾经想要采起c#语言编写扫雷项目,可是从新学习一门语言的成本过高,加上本身自己对编程并非太擅长,就沿用旧方案采用C语言编程,开始一天根据扫雷的功能构思所须要的函数。接下来四天都在编码的过程之中,学习实现相应功能所须要的知识,因此效率并非很高。具体学习的内容是循环与数组相关的知识,在编写随机布雷的函数过程之中也学习了随机数函数的用法。在存储游戏成绩的模块之中我也自学了文件打开与关闭、文件读写相关的C语言知识。在这段实践的过程当中,第一次对编码与软件工程有了比较系统的认识,最珍贵不是学习到的编程知识,而是动手去作的勇气,就在一周之前编一个能够运行的游戏对我来说难如登天,更别说加上本身设想的功能了。在编码的过程之中,老是会由于一个小小的问题无法解决,就卡在原地好几个小时,好比在编写游戏成绩记录相关函数的时候,文件存储模式选取为"w"模式这就致使每次的成绩写入都会覆盖上一次的成绩,后来在搜索引擎的帮助下,在百度知道上得知须要将“w”更改成"a",没想到简简单单的一个字母就可使程序功能有天翻地覆的改变。