[](C:\Users\admin\Desktop\新建文本文档. html.txt)
第一部分 技术调研部分
一、第一周学习总结
1.1任务分配
截止到2021年7月2日星期五,我已经进入小学期学习有一周了,这周我复习了C++/C相关内容,学习了标准模板库STL的部分基本原理以及基本操作,通过马瑞新老师初步了解了软件开发的流程和作为一名程序员所要具备的素质等,所选择做的项目是贪吃蛇游戏。
星期一 | 了解了一下STL是什么,复习C/C++的基础知识 |
---|---|
星期二 | 主要学习了容器的相关知识以及应用 |
星期三 | 完成老师布置的练习题,确定项目,完成了部分技术调研 |
星期四 | 敲老师布置的小测题,期间学习到了约瑟夫算法,以及排序的一些方法如,快排 |
星期五 | 了解了企业项目开发的流程以及开发人员要具备的素质 ,学习了迭代器的相关知识 |
2.对C/C++语言的复习
2.1 在上机测试当中学习到了约瑟夫环递归算法
2.1.1 题目 :n个人围成一圈(编号从1到n),从第1个人开始报数,报到m的人出列,从下一个人再重新报数,报到m的人出列,如此下去,直至所有人都出列。求最后一个出列的人的编号。
- 举例 n=5,m=3
初始 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
第一轮 | 1 | 2 | 4 | 5 | |
第二轮 | 2 | 4 | 5 | ||
第三轮 | 2 | 5 | |||
第四轮 | 4 | ||||
最终这个人的编号是4 | |||||
既然是递归,那么前一个和后一个肯定有关系的,我设为f(n,m)和f(n-1,m)之间的关系。通过规律的总结发现了递推规律为f(n,m)=[f(n−1,m)+m]%n。 | |||||
万物有其根本,其背后的思想 |
- 举例n=5,m=4
初始 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
第一轮 | 1 | 2 | 4 | 5 |
由于已经将3号排除在外,所以此时已经不能构成一个环了
- 问题1 :如何避免产生的空位对报数造成的影响?
由于3号已经排除了,相当于一次循环结束 ,那么可重新开始一个循环,将剩下的人组成一个新的循环(4,5,1,2)
- 问题2:如何避免重新构成的循环造成的编号不连续而导致无法用递归的方式处理?
1) 借助储存结构得知下一个报数的现存人员编号
2) 将剩余的人进行新的编号,新的编号和旧的编号之间有一种映射关系
初始 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
第一轮 | 1 | 2 | 4 | 5 | |
旧编 | 1 | 2 | 4 | 5 | |
新编 | 3 | 4 | 1 | 2 |
这样的新环解决了之前旧环不连续的问题,又解决了旧编和新编的映射关系
(旧的编号)=[(新的编号)+m]%(旧的人数n)
用C++来求解这个问题代码如下:
C++
#include <iostream>
using namespace std;
int josephus(int n, int m)
{
if(n == 1) return 0;
else return ( josephus(n-1,m)+m ) % n;
}
int main()
{
int n, m;
cin >> n >> m;
int result = josephus(n, m);
cout << result+1 << endl;
}
2.2 快排
头文件是#include<cstdlib>
(C++头文件没有.h从中导入的名称位于作用域std中,当中包含的名称使用std::
来访问,但是使用了using namespace std
; 所以可以省略std::
)
2.2.1 qsort 函数模型
void qsort(void*base, size_t num, size_t width, int( * compare)(const void*,const void*))
函数中的各个参数
1.待排序数组的首地址
2.数组中待排序元素的数量
3.数组中每一个元素占的空间
4.指向函数的指针,用于确定排序的顺序(compare)
2.2.2 Compare函数原型:
compare( (void *) & elem1, (void *) & elem2)
compare函数的返回值 | 备注 |
---|---|
<0 | elem1将被排 elem2前面 |
>0 | elem1将被排elem2后面 |
=0 | 位置不变 |
- 代码表示:
C++
//由小到大排序
int comp(const void*a,const void *b){
return *(int*)a-*(int*)b;
}
//由大到小排序
int comp(const void*a,const void *b){
return *(int*)b-*(int*)a;
}
- qsort函数的应用实例(二维数组)
C++
#include <stdio.h>
#include <stdlib.h>
int comp(const void*a, const void*b) {
return((int*)a)[0]-((int*)b)[0];
}
int main() {
int i=0;
int *array;
int n;
scanf("%d",&n);
array=(int*)malloc(n*sizeof(int));
for(; i<n; i++) {
scanf("%d",(array+i));
}
qsort(array,1000,sizeof(int)*2, comp);
for(i=0;i<n;i++) {
printf("%d\t",array[i]);
}
return 0;
}
3. STL的学习
简介: STL(Standard Template Library)即标准模板库,是C++标准程序库(C++ Standard Library)中,大约占百分之70 左右,该库包含了诸多在计算机领域里所常用的基本数据结构和算法,高度体现了软件的可复用性。
特点:
1.STL是数据结构和算法的分离
2.STL不面向对象
内容(六大组件):
容器(Container) | 分配器(allocator) |
---|---|
迭代器(Iterator) | 仿函数(Functor) |
算法(Algorithm) | 适配器(Adaptor) |
3.1 容器
STL中容器分为序列式容器和关联式容器
3.1.1 序列式容器(Sequence containers)
- Vector
头文件是#include<vector>
3.1.1.1 Vector初始化
-
方式一:
vector<int>a(10)
//其中的 int 可以换成其他类型,这种初始化定义了该容器具有10整形元素的向量,不具有初值。 -
方式二:
Vector<int>a(5,1);
//具有五个初值,每个初值都为1 -
方式三:
Vector<int>a(b);
//将b给向量a赋值 -
方式四:
Vector<int>a(b.begin(),b.begin+3)
//将向量b中从0-2的 元素都赋值给a。 -
方式五:
int b=[7]={1,2,3,4,5,6,7};
vector<int>a(b,b+7);
3.1.1.2 访问vector
-
向向量a中添加元素
vector<int>a;
for(int i=0;i<10;++i){a.push_back(i);} -
从数组中选择元素向向量中添加
int a[6]={1,2,3,4,6};
vector<int> s;
for(i=0;i<=3;i++){
s.push_back(a[i]);} -
从现有的向量中选择元素向向量中添加
C++
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int a[6]={1,2,3,4,5,6};
vector<int>b;
vector<int>c(a,a+4);
for(vector<int>::iterator it=c.begin();it<c.end();++it)
{
b.push_back(*it);
}
for(vector<int>::iterator it=c.begin();it!=c.end();++it)
{
cout<<*it;
}
return 0;
}
3.1.2 关联式容器
3.1.2.1 set
头文件#include<set>
1.set中的元素都是排好序的
2.set中没有重复的元素
3.set插入和删除的效率比其他容器高
原因是,对于关联容器来说,不需要做内存拷贝和内存移动,所有的操作都是指针之间的交换和内存没有关系。
4.set中所采用的是二分法,通过了解时间复杂度,二分法的时间复杂度是log(n),即使搜索内容很大,搜索速度较快。
5.set中的常用用法
begin() | 返回set容器第一个元素的迭代器 |
---|---|
end() | 回一个指向当前set末尾元素的下一位置的迭代器 |
clear() | 删除set容器中的所有的元素 |
empty() | 判断set容器是否为空 |
max_size() | 返回set容器可能包含的元素最大个数 |
size() | 返回当前set容器中的元素个数 |
rbegin() | 返回的值和end()相同 |
3.1.2.2 Map/Multimap:
Map的元素是成对的键值/实值,内部的元素依据其值自动排序,Map内的相同数值的元素只能出现一次,Multimaps内可包含多个数值相同的元素,内部由二叉树实现,便于查找;
3.2 迭代器
迭代器iterator是C++ STL的组件之一,作用是用来遍历容器,而且是通用的遍历容器元素的方式,无论容器是基于什么数据结构实现的,尽管不同的数据结构,遍历元素的方式不一样,但是用迭代器遍历不同容器的代码是完全一样的。经典的迭代器遍历容器的代码如下:
vector<int>::iterator it = vec.begin();
for (; it != vec.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
4. 项目确立
贪吃蛇需求分析和技术调研
4.1
贪吃蛇的特点是随机产生食物后,然后通过上下左右地方向键来控制贪吃蛇的移动,当碰到食物时,便把它吃掉,从而身体长度增加一个,这里便采用"#"作为蛇头,"*"作为蛇身和食物。因此我便想到,产生的食物,是如何达到随机的目的呢?通过查阅资料得知,在time.h头文件中,定义了通过rand()函数来产生随机数。
4.2
吃食问题:当蛇头遇到一个食物时(食物在贪吃蛇前进的方向上),便将该食物变为蛇头,然后将原先的蛇头变为蛇身,从而达到了吃食的目的。
4.3
如何将每个动态都展现出来呢?这里应该使用clock()函数。
4.4
为增加游戏的娱乐性,打算从中加入等级选择功能,通过输入数字来选择等级,等级越高,贪吃蛇移动速度越快,而且得分越高,考虑到游戏的功能性,在游戏结束后输出得分情况,并提示是否继续游戏,而不是直接退出游戏,这样用户就不必每次游戏失败后重新打开程序进行游戏,而是通过选择的方式决定继续游戏或者退出游戏。而且加入暂停功能,当玩家玩累了,需要暂停的时候,按下空格(space)键实现暂停
二、第二周实习总结报告
1.总结贪吃蛇制作思路
1.1 绘制API,所以需要引入graphics.h这个图形界面库。
1.2游戏规则
- 蛇是一节一节的,每吃掉一个事物都会长一节
- 蛇吃食物需要移动,如果需要移动那么就会有坐标的变化。
- 蛇没吃掉一个事物都会随机产生一个食物,所以食物也是由坐标表示。
- 如果在蛇移动吃食物的时候与便捷或者自己的身体发生碰撞,则gameover。
- 进行操作则需要通过键盘来操作来改变蛇的方向。
2.介绍graphics.h图形库
2.1基本说明
- 坐标:定为以左上角开始,水平向右为X轴,竖直向下为Y轴,建立坐标系
- getch() :图形关闭之前通常要键盘获得一个字符,否则图形一闪就没了。
- closegraph() :关闭图形窗口函数。
- cleardevice() :清空屏幕,之后会界面内容全部清空,显示为默认背景颜色。
2.2颜色模型
首先:此图形库中采用的是RGB 颜色。*RGB 色彩模式 是工业界的一种颜色标准,是通过对红 ®、绿 (G)、蓝 (B)三个颜色 通道 的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,*是运用最广的 颜色系统之一。
2.2.1 设置颜色模型(常用)
stebkcolor()
:设置背景颜色,参数颜色
setfillcolor
:设置填充绘制图形形式所用的颜色
2.2.2 设置风格样式的模型
setfillstyle():设置填充样式,比如竖线,横线,方格填充。
setlinestyle():设置线的填充样式
setbkmode():图案,或文字填充的背景模式(背景色,透明)。
2.2.3 图形的绘制
ine(x1,y1,x2,y2) :直线。两端点坐标
rectangle(x1,y1,x2,y2) :空心矩形。左上角坐标,右下角坐标 。
circle(x,y,r) :空心圆。圆心坐标,半径。
ellipse(x1,y1,x2,y2) :椭圆。外切矩形左上角坐标,外切矩形右下角坐标
如果想要将绘制的图形填充 可以用前缀fill
,如果想要清除一个图形区域可以用前缀clear
2.2.4 文字输出
outtextxy(x,y,color)
在(x,y)位置输出字符串str。(个人觉得够用了)
2.2.5 图像处理
IMAGE img;
loadimage(&img,path[, width , height]) :图像读取。 IMAGE对象地址,路径。扩展参数,已制定宽高,拉伸读取。
putimage(x0,y0,&img) :图像展示。图形窗口左上角坐标处开始展示img图形。
putimage(x0,y0,w,h,&img,x,y) :图像展示。和上面相比,w,h为要展示多少像素图形,x,y为img对象从该位置开始展示。
2.2.6 鼠标处理
首先,鼠标对象MOUSEMSG是一个结构体。内部有参数,x,y表示坐标,uMsg。
uMsg的类型:
- WM_ L \color{#0000FF}{L} L B O T T O N \color{#FF3030}{BOTTON} BOTTON D O W N \color{#00FF00}{DOWN} DOWN
前面的WM_是一个固定形式,后面三部分是可变的。左边蓝色的值分别为L,M,R分别代表鼠标左键,中键,右键。右边绿色的值分别为DOWN,UP,DBLCLK代表按下,松起,双击信息。
3.此项目关于graphics.h图形库的接口
3.1 绘制一个窗口的API
void initgraph(int weith,int height)//创建一个宽为X长为Y的图形窗
3.2 清楚窗口的所有绘制
void cleardevice ()//清空整个窗口的绘制
3.3 在指定位置输出文字
void settextxy (int x,int y,LPCTSTR str)//坐标为(x,y)处输出字符
3.4 绘制图形
fillrectangle(int left, int top, int right, int bottom) //画填充矩形,从起点(left,top)到终点
(right,bottom)
3.5 绘制圆角矩形
fillroundrect(int left, int top, int right, int bottom, int ellipsewidth, int ellipseheight)
//画填充矩形,从起点(left,top) 到终点(right,bottom)
//ellipsewidth构成圆角矩形的圆角的椭圆的宽度。ellipseheight构成圆角矩形的圆角的椭圆的高度。
//若后两个相当相当于绘制一个圆形 不过不是以圆心的 是按照矩形的。
3.6 设置当前文字填充色
settextcolor(COLOR color) //设置当前文字也就是下一行文字的颜色 宏定义RED,BLUE,YELLOW等
4.如何创建蛇和食物
蛇和食物都有一个共同的特点,就是都有坐标
//创建坐标
struct Coor{
int x;
int y;
};
创建蛇和食物的具体结构
//蛇
struct Snake{//蛇的结构
int n;//蛇当前的长度
Coor szb[SNAKELENGTH]//蛇的坐标
Ch ch;//蛇移动的方向
}snake;
//食物
struct Food
{
Coor fzb;//食物的坐标
int flag;//标记食物是否被吃掉
}
移动的方向
enum Ch
{
up = 72;
down = 80;
left = 75;
right = 77;
};
5.游戏的流程
6.实验手册操作截图
C++
- 斐波那契数列程序
- 配置文件参数读写
- 开元tesseract语言文字识别系统
- 学生管理系统
C
- 平方根求和程序
- 函数指针使用
- 动态库编写使用
- 学生成绩管理系统
- Tcp通讯
7.鲲鹏学习完成度
项目简介
- 引入
graphics.h
图形库构成了游戏的页面。 - 贪吃蛇游戏设计与实现,主要分为以下三个模块:游戏主界面模块、游戏控制模块和游戏菜单模块。在此只实现游戏的游戏主界面模块、游戏控制模块和游戏菜单模块,并且只是实现开始、暂停、退出等最基本简单的功能。
- 贪吃蛇游戏是一-个经典小游戏,一条蛇在封闭围墙里,围墙里随机出现一个食物,通过按键盘四个光标键控制蛇向上下左右四个方向移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或身体交叉蛇头撞倒自己身体游戏结束。
第二部分 项目分析报告
1.需求分析
1.1 用户的特点:
此游戏主要是面向小朋友,所以本游戏的界面操作简单适合小朋友玩。
1.2 功能需求:
- 蛇是一节一节的,每吃掉一个事物都会长一节
- 蛇吃食物需要移动,如果需要移动那么就会有坐标的变化。
- 蛇没吃掉一个事物都会随机产生一个食物,所以食物也是由坐标表示。
- 如果在蛇移动吃食物的时候与便捷或者自己的身体发生碰撞,则gameover。
- 进行操作则需要通过键盘来操作来改变蛇的方向。
1.3 游戏的流程
2.总体设计
2.1 创建蛇和食物
蛇和食物都有一个共同的特点,就是都有坐标
//创建坐标
struct Coor{
int x;
int y;
};
创建蛇和食物的具体结构
//蛇
struct Snake{//蛇的结构
int n;//蛇当前的长度
Coor szb[SNAKELENGTH]//蛇的坐标
Ch ch;//蛇移动的方向
}snake;
//食物
struct Food
{
Coor fzb;//食物的坐标
int flag;//标记食物是否被吃掉
}
移动的方向
enum Ch
{
up = 72;
down = 80;
left = 75;
right = 77;
};
)
2.2蛇判断方向,需要引入头文件 <conio.h>
//*****这是判断按键 来改变方向
int move = _getch();
switch (move)
{
case up: //不能向下走
if(snake.ch!=down)
snake.ch = up;
break;
case down:
if (snake.ch != up)
snake.ch = down;
break;
case right:
if (snake.ch != left)
snake.ch = right;
break;
case left:
if (snake.ch != right)
snake.ch = left;
break;
}
//***********/
//********根据方向变化来移动蛇头
//先将后一节的坐标等于前一节的坐标
for (int i = snake.n - 1; i > 0; i--)
{
snake.szb[i].x = snake.szb[i - 1].x;
snake.szb[i].y = snake.szb[i - 1].y;
}
switch (snake.ch)
{
case up:
snake.szb[0].y -= NUM;
break;
case down:
snake.szb[0].y += NUM;
break;
case right:
snake.szb[0].x += NUM;
break;
case left:
snake.szb[0].x -= NUM;
break;
}
//********/
2.3 蛇的碰撞部分代码
if (snake.szb[0].x < 0 || snake.szb[0].x >= WINDOW_WIDTH || snake.szb[0].y >= WINDOW_HEIGHT || snake.szb[0].y < 0)
{
return true;
}
4.详细设计与实现
见源代码链接(C:\Users\admin\Desktop\新建文本文档. html.txt)