- 浏览: 42488 次
- 性别:
- 来自: 上海
最新评论
-
御风夜辰:
辛苦老师了,希望老师出第二季吧~~
俄罗斯方块(一)纯C++方块类 -
shenyu:
想起了分段事务的代码,不知道这样写可以不? //申请资源,如 ...
JDBC tutorial from SUN(3) -
shenyu:
从橘子老师这里真是学到了不少东西。不过有些E文看不明白,还是要 ...
JDBC tutorial from SUN(3) -
shenyu:
努力学习中。希望LZ加油
JDBC tutorial from SUN(一)
文章列表
简易内存数据库(七)CREATE
- 博客分类:
- CPP
这是CREATE 最后一个需要实现的函数了
/*
* 描述:4)或者100)把括号前的数字返回
* 参数:string -- 整体字符串
* 返回:返回解析后的数字
*/
int getLength(char * string)
{
//找到')'的位置
char * end=string;
while( *end !=')' ) end++;
//把')赋值成'\0'
*end='\0';
//把字符串转成数字
return atoi(string);
}
有个函数是atoi,可以把字符串转成数字。比如atoi("100&q ...
前面CREATE完成。当中有一个细节我想你应该已经注意到了。
就是当读到 float(4)或者char(100) 时,我们知道这个字符串中需要保存2个内容。一个是column类型,一个是column长度。
我就用了getColumnTypeLength(buffer, &column->type, &column->length); 这个函数,希望把buffer中读到的这两个内容,分别保存到column->type和column->length中。
显而易见,我把解析这种字符串的事情交给了getColumnTypeLength这个函数来做。
...
接下来就是一行行读column了。
因为column有多个,所以我们需要写循环语句 while(...)
循环语句的结束条件是什么呢,读到什么时候column就算读完了呢?
当然是要么文件结束,要么读到‘)’啦。
所以我们可以开头这样写
fscanf(fp,"%s",buffer);
while (!feof(fp) && strcmp(buffer,")")) {
while循环中每读到一次column就创建一个column对象。填充好。
而且column结构设计的时候我用链表结构。所以还要把每次创建的co ...
因为整个程序都是围绕Table的,为了方便起见,我申明了一个全局变量
Table t;
我们一个单词一个单词的读取文件内容。然后一个单词一个单词的进行比较。
临时的内容保存在char buffeer[100]中。
有时候需要的内容就直接保存在相应的table内存块中。
创建代码如下
/*
* 描述:根据给定文件,在内存里填充数据库格式
* 参数:已经打开的文件
* 返回:返回0说明创建失败。返回1则创建成功
*/
int createTable(FILE *fp)
{
//先把要填充的内容清空
memset(&t, 0, sizeof ...
那我们来试试CREATE吧。
CREATE语句可以建立一个表头,表头的信息包括表的名字,表所包含的列。我打算用这样一个结构来保存表的信息
struct Table
{
char name[50];//表的名字
Column * columns;//表的列
int columnCount;//列的个数
};
表名我用的是普通数组。也就是说,在这个系统中,表名的长度不能超过49个字节。
列用的是指针。我将要用链表形式保存所有列的信息。
额外用一个变量保存列的个数。
列的结构如下:
struct Column
{
char name[50];//列名
...
简易内存数据库(二)保存一组数据
- 博客分类:
- CPP
还有一件事情我需要重申一下:
我们在保存一组数据时会使用以下三种方式:静态数组,动态数组和动态链表
1)当我们预先知道一组数据的长度,或者是最大长度的时候,可以用静态数组,在程序编译的时候就确定了保存这一组数据的内存大小。用int作为基础类型,代码如下:
int array[MAX_COUNT];
2)当我们在程序运行时才能知道一组数据的长度,或者是最大长度的时候,可以用动态数组,在程序运行时一一次性分配一整块内存。用int作为基础类型,代码如下:
//申明
int * array;
//实现
array = (int*)malloc(sizeof(int)*MA ...
项目的要求是:
需要接受create,insert,select, update,delete等语句,在内存中建立一个数据库表。并对这个表进行相应的操作。
动手之前有一些提示。
不管我们处理哪一种语句,要做的都是2件事:1)解析相关的语句。2)把语句所表述的内容保存在内存中。
我先解释一下这两点:
首先,你的程序是运行在内存中,程序所要处理的内容当然需要预先保存在内存中,这样你才可以进行内容操作。
保存在内存中,换句话说你可以申明变量,把文件中所表述的内容赋值到变量中。
那么这个或这些变量应该是什么类型的呢。
你第一个想到的,既然是文本形式读到的内容 ...
最后,我们来处理一下游戏结束。
先在Panel中增加一个游戏结束标志
class Panel : public CWnd
{
private:
bool gameover;
构造函数的时候设定他为true;
Panel::Panel()
{
...
gameover = true;
}
游戏开始时,设定他为false;
void Panel::start()
{
....
gameover = false;
然后游戏开始正常运行。那什么时候游戏结束呢?看上去应该是障碍块累计到Panel的顶上。再仔细一想,应该是没有办法再增加新的方块的 ...
现在为止,一直都是通过键盘向下键往下移动方块的。实际游戏当中方块自己会往下掉。这又是怎么做的呢。
像这样自动的行为,从开发的角度来说,就是定时运行一段代码。
那我们就是需要在一定的时间间隔运行让方块下落的代码。
一定的时间间隔是怎么做的呢?首先我们要告诉系统我需要一个定时。这个函数是SetTimer。每次游戏开始的时候,也就是点了开始按钮的时候,我告诉系统说我需要一个定时器。
void Panel::start()
{
this->SetTimer(ID_TIMER,100,NULL);
...
}
SetTimer第一个参数是给定一个Timer的ID号。 ...
方块沉底后,如果能整齐的垒满一整行,则这行就可以被消除。
那我们把销行的代码写在哪里呢?我想应该在每次加上障碍块的时候看看是不是满行了。
void Panel::ElementDead()
{
for (int i=0; i<4; i++)
{
body[element->body[i].getY()][element->body[i].getX()] = true;
}
delete (element);
//销行
randomCreate();
}
好吧,那我们开始销行。由于我们用的是stl的容器类vector,所 ...
俄罗斯方块(十二)方块沉底
- 博客分类:
- CPP
边界处理完成后,我们运行程序,可以看到方块只能在Panel的区域内移动或旋转。不过因为没有障碍块,所以不能验证对障碍块的处理是否正确。
障碍块是怎么形成的呢?-- 方块沉底以后就变成了障碍了。
方块什么时候算沉底呢?--落到无法再下落的时候就沉底了。
因此我们可以在moveDown中增加这么一段代码
void Element::moveDown()
{
Box newBody[4];
for (int i=0; i<4; i++)
{
newBody[i].setX(body[i].getX());
newBody[i].setY(body[i].getY ...
俄罗斯方块(十一)处理边界续
- 博客分类:
- CPP
上次我们解决了moveDown的边界处理。这次我们可以依样画葫芦,把moveLeft,moveRight的边界处理都完成。
每次边界处理也同样是3步:1)确定新的位置。2)查看新位置是否可行。3)如果可行,把新的位置替代旧的位置。
void Element::moveLeft()
{
Box newBody[4];
for (int i=0; i<4; i++)
{
newBody[i].setX(body[i].getX()-1);
newBody[i].setY(body[i].getY());
}
if (!ifOccupied(newBody) ...
俄罗斯方块(十)处理边界
- 博客分类:
- CPP
当俄罗斯方块移动的时候,需要判断边界,来确定是不是可以移动。
判断边界有两个因素要考虑:1)是不是超过Panel边线,包括最大值和最小值。2)是不是有障碍块。
因为Panel边线和障碍块都是Panel的属性,也就是Panel的成员变量,所以,我们可以把确定边界的函数写成Panel的成员函数。
bool Panel::isUnavailable(int w, int h)
{
if (w<0 || h<0) return true;
if (w>=getWidth() || h >= getHeight()) return true;
return ...
一开始我们做纯C++俄罗斯方块构架的时候,并没有让大家考虑Panel里面的障碍方块。
现在我们来添加一下。在Panel里面增加一个成员变量,来记住一组障碍方块。
我第一个想法是用一个容器保存一组Box,比如说set<Box>,(set代表说里面的box都不能重复)。不过这样做销行的时候可能有点复杂。
比较常见的做法是用一个bool的二维数组。二维数组代表整个Panel的平面。bool来表示平面中哪个点有障碍块,哪个点没有。
不过,为了练习容器类,bool的二维数组,我们也可以用vector<vector<bool>>来代替。
里面的vec ...
windows程序最根本就是消息机制。按键盘也会得到相应的消息。我们现在需要让Panel处理相应的键盘消息,使俄罗斯方块可以左右移动,翻转或者往下。
跟处理显示消息的方式类似。打开类视图(大部分的视图或窗口可以在菜单中“视图”菜单项内找到),选中Panel类,打开属性视图,选择上方的消息按钮。找到WM_KEYDOWN消息,添加对KeyDown消息的处理函数 OnKeyDown
OnKeyDown有三个参数,第一个说明按了那个键,第二个是按键次数,第三个参数是一些额外信息。
void Panel::OnKeyDown(UINT nChar, UINT nRepCnt, UINT n ...