博文

我的新博(2009-12-27 11:17:00)

此博有些功能不太方便,希望以后管理员能升级后台系统。

新博移居于此http://linyinhu.blog.com.cn/

虽然我本性更愿意用日记本写日记、用笔写信。实际上也一直是这么做的。

写博更多用于记录学习和工作…


阅读全文(140) | 评论:0 | 复制链接

09年的生日(2009-11-16 22:55:00)

我一直觉得我是一个命好的人,当然了,如果有人真的知道我是怎样一个人,他们会笑我只是一个人自娱自乐穷得瑟,因为觉得我并不是一个命好的人,甚至可以说是个命背的人,而我仍然觉得我是个命好的人。

 

今年生日刚过,第一次在生日的时候狂下雪,西安的雪除了考研时的大雪纷飞后,再也没有下得这么淋漓尽致了,打小喜欢下雪,好像至少有一大半的人是这样的吧,都喜欢乐呵呵的在雪里跑来跑去,特别喜欢过年下雪,好像那样,才有过年的气氛。生日,告诉自己又长了一岁,要做的要承担的事也多了一分,其实吧,能有几个人记住你的生日已经很好了。

 

蓝是会永远记得我的生日的,我是这么觉得,我也同样会这样记得。

 

那天一大早,我去了师大,那边的天气好冷,被雪盖着很安静的感觉,路上没几个人,车站也是。在600路下车了,竟然那里的土渣烧饼还在卖,其实也就只有他一个摊还在卖了,往常都是六七个摊位的。没吃早饭,蛮饿的,蓝出来了,穿着上次买得大衣,很好看,脸红扑扑的,她也饿,呵呵,又蹦又跳的说要吃烧饼。

 

结果吃了烧饼又马上搭600去了东大街的傣妹,去的时候觉得还早,应该没什么人,等电梯上去的时候,一脸失望,座位倒是有,没有靠窗户的了,蓝最喜欢窗户,呵呵,任何地方都是,教室要做靠窗的,吃饭要做靠窗的,。。最后坐了个还好的位置的,只能说是还好,因为没有靠窗。

 

后来去买衣服,这大雪天的,确实蛮冷的,蓝说要跟我买件“排骨”,她对羽绒服的称呼都是“排骨”,-_-。开始在以纯,森马啥的转了好大阵,都没有蛮满意的,后来决定去羽绒服专卖场去买,东大街旁一点的六楼。终于在里面买了件,400多大洋,好贵呀,我是从来没买过这么贵的衣服的,琢磨研究了好阵,就买下了。蓝给我的生日礼物。

 

下午回师大,蓝有点事。师大因为甲流封校封得严,出来的时候从栅栏里拱出来,呵呵,看栅栏的保安刚跑到屋里去,我俩看他跑了,趁机溜走。在师大围墙旁边的灌木上铺着一层雪,我俩路过,偶然看见,灌木上的雪上写有字“丽丽,我爱你”,狂汗,佩服这位仁兄的创意。

 

突然感觉,这怎么是小时候的事,其实才是前天。

 

回师大的那天,下着很大的雪,师大的新校区,又大,又白的,。就着雪花在师大的图书馆前的树林里照了几张相,背景里的超大雪人很好看,还有据说得过“鲁班奖”的宏伟的师大图书馆,在图书馆的下午三个多小时里发现,自己学校的图书馆跟师大的图书馆的差距呀,让我感觉如果我在师大,让我天天呆在图书馆,我也认了,呵呵。

 

有蓝陪伴的生日真好。


阅读全文(157) | 评论:0 | 复制链接

停下手头的工作,给自己几分钟(2009-9-18 17:50:00)

距最近的博文都有一年又半了,都说我废弃了这个博客,其实只是我没有想到要写,因为我并没有其它的博客。

 

这一年都在干什么呢,其实什么也没干。上研了,研一都已经过去了,刚开始研二的生活,总觉得刚到一个环境的时候,人都会忙着适应环境,没有很多的心情去思考,去反省。

 

现在,人都这个样子,当下的时候,都是传说中的“很忙”,现在这个社会,谁不忙呢,忙学习,忙恋爱,忙工作,我们都乘着小木伐在生活的激流里急驰而下,来不及思考,来不及反省,而等到开始反省的时候,大多的时候都有点晚了,大多数的我们,忙得时候想闲,闲的时候闲不住,其实这个现实是,你真的很忙吗?而闲得时候你真的就没事可做吗?现在我们都耐不住寂寞,害怕安静,如果没地方去,再怎么也得上个网,逛逛网页,泡泡论坛来得实在,就这样在浑噩与清醒,忙碌和空虚中年复一年。

 

我时常在想,我到底要做什么,做什么才是有意义的,“有意义”这个词语太模糊了,每个人的标准也都不一样,有的人上班的时候上上班,下班的时候逛逛网,已经很满足了,不求最优,不为最后,日子也过得自在。我总想做点什么,而我开始莫名的发现,这个信息社会的过量信息,已经开始慢慢地在淹没我们的思维和判断,有人告诉我,这就是传说中的开始成熟。

 

Stop Working,
thinking

 

玩一个开源网游时,一个阿外跟我说的,

 

玩网游的外国人感觉普通跟玩网游的国人,还蛮大差异的,前阵偶尔上上个国服,进去就有人要跟我PK,然后一个劲跟我说,他的那些啥啥咐装备是花了多少货真价实的RMB买来的,瀑布汗。后来,对国内的网游实在没有兴趣了,全是一种模式,都是现在流行的“永久免费”,主营卖道具等等,游戏路线也都是如此,唉,再也找不回以前打魂斗罗时,那种新奇,发自内心的快乐了,记忆犹新的几张灿烂的笑脸,好久远的样子了。

 

The Mana World 一个开源网游,我想国内应该没多少关心,也没多少人玩吧,想想也是,这游戏最高在线,就我自己登陆来看的话,最多的时候,我看到的是185人,呵呵,也难怪,一个开发中的游戏,里面基本都是外国人,也不知道是哪些国家的,本来这是发自于LINUX阵营里的游戏,也难怪国内人少,其实我最初的目的只是想看看网游C/S模式的源代码,偶尔实验室无聊上上也还好,第二天登陆,有个家伙就主动要跟我交易,然后发给我四五件装备,我就纳闷了,我一句话还没跟他说呢,后来再看了会,发现,他连续给了三四个人东西,我笑了笑:呵呵,碰到财神了。总体感觉那游戏里氛围还好,蛮友好的感觉,有的奇怪的是,那里面的人都不着急打怪升级,都喜欢窝在一堆围个圈聊天。这可能是我发现的差异蛮大的地方吧。

 

最近其实还在看源代码,只是觉得思维层次还不够高,容易被淹没在细节中,常对自己说,忘掉细节,忘掉细节,思维和框架设计才是最重要的。慢慢习惯吧,呵呵,这是条很长的路,

 

实验室里的项目一上研就开始在做,一直到现在,一个军用视频编解码系统,带我的老师出国已经半年了,一直觉得遇到对的人对一个人发展轨迹有着莫大的作用,他带我其实就是把他的软件拿给我看,我不懂去问,这个专用的编解码算法让我忙活了好阵,呵呵,不过也很远的事情了,这个已经被摸了几十遍的软件,我实在是提不起兴趣去弄它了。因为他会更加加速我“码男”(以前的兄弟经常开玩笑说我是码男)的轨迹,我想要的不是实现算法的“码男”。往更加抽象更加理论的方法发展,这样才能看得更远,而不是一个关在写字楼里狂写代码的“码男”。

 

九一八,西安上空的防空警报响了好久,铭记那段历史。。

 


阅读全文(186) | 评论:0 | 复制链接

我的零八愿望结局(2008-3-4 20:24:00)

以前跟人说过,我希望我的零八愿望能在新的一年里实现…

那是元旦的前一天晚上,听完新年的音乐会,我不懂艺术,可怜的那些人算是对牛弹琴了吧,我很开心地望着天空说,我希望我在零八年里过掉六级,考上研究生,

然后很执著的傻笑的那种,呵呵…

有个人很开心的咯咯的笑我…因为我六级算上这次考了已经四次,

"你六级要考六次才能过",呵呵,可爱的神奇咒语…

我这次六级没过,413分,…,有点失望,因为有希望才会有失望,

希望的越多,失望才越多~

回想我的六级历程,…,346,383,413,每次其实我都在很努力,

我也知道我英语烂,要比别人付出的多…

也怪不了谁,谁让自己大学里不好好学英语呢~

跟自己说,下次我一定可以,再接再厉……呵呵…

幸运的是我的另一个愿望应该是可以实现的吧,初试成绩也出来了,

402,比较意外,也很开心,呵呵,大概是因为上帝不会同时关上两扇门吧……



阅读全文(943) | 评论:7 | 复制链接

大学,我得到了什么?(2007-12-14 16:49:00)

昨天考完了《微波》,大学里最后一次必修课考试。辅导员也意思就是,选完毕设题和照完毕业照的没其它事的可以回家了,而我就是属于那种“有其它事的”,考研。

大学实质上已经上完了,过去的三年多里我都得到了些啥呢?有快乐的,有无措的,更多的是迷茫与激情的交织。

大 一刚来的时候,什么都不懂,就是土包子,发现很多新奇的东西。电子方面最让我着迷,倒不是爱玩游戏。我就成天在那琢磨,电脑这个冷冰冰的东西是怎么运转起 来的呢?那硬盘的磁头是怎么读写信息的呢?显示器上的点都是怎么描绘出来的呢?刚来没电脑,成天泡图书馆,吃完饭有时候回宿舍都省了,直接奔图书馆。把能 看懂的看不懂的计算机硬件方面的书几乎全部给看了个遍。想来,求知若渴的感觉大概就是那样吧。计算机体系结构,硬件方面的知识大概就那时建立起来的。那时 的我大概是我大学中进步最快的一段时间吧。

而接下的路我确实走错了,大一下买了个电脑,说要DIY自己装机,到电脑城里东买个CPU,西买个显 卡,回来兴奋得不行,当然了,机器是很容易装的,很快就装好了,立马装了个XP,点来点去地也不知道要干嘛,最热心的东西就是咋样咋样优化它了,使它启动 时间更短,跑得更快。这时期我也看书,不过不泡图书馆了,都是借了书出来读。而我竟然读得是应用软件方面的书,学过3DMAX,ACDSEE,MAYA, FRONTPAGE…这学期开了C语言,我很上心,学得还过得去,这学期我的收获大概就是学了C…还学了点WINDOWS编程,做了几个画图程序。虽然当 时有点小成就感,马上就开始感到,真TDM无聊,全是函数调用来调用去地,谁能告诉我它的来龙去脉,其实我那时连自己想知道什么都不知道…

大二我认识了UNIX,我意外的发现这世界上原来除了WINDOWS还有其它的操作系统,我喜欢新鲜的东西,而我恰恰又犯了一个现今大学生的通病,浮躁…

我 几乎把大部分的LINUX发行版全体验了个遍,还把BSD的三分支给装了通,Solairs因为下不回来没装过。那时最热心的东西就是咋样把这系统的字体 显示得好看点呢?咋样让它编译得更适合我的机器,让它跑得更快呢?这段时期就学到了UNIX的体系结构和基本概念和一些常用的命令,基本是浮躁当头,有时 候一个版本还没装热立马换掉,浪费了N多N多(N>半年左右)时间,能说什么呢,过去的事情了,后悔也没用。这期间我也在编程,我不用再像以前写程 序一样调用那继承了N道又重载的函数了,看到MFC我就晕,可我发现我还是得调用函数,最起码操作系统内核的接口你还是必须得调用。我很郁闷,也很迷茫, 自己编程算个鸟呀,自己写的几句全是没一点有思考性的东西,老在调用函数,无聊地呀。

大概不知道什么时候了,我学习了数据结构和算法,我才发现这 才叫有点思考性的东西嘛,原来程序并不总是这么无聊地调用别人的东西,我去北大ACM网上做程序题,解决了问题我会很开心,比那做什么画图有意思多了。这 期间我感兴趣的东西太多了,图形学,操作系统,编译原理,汇编,计算机体系结构,算法,协议栈…。我好像同时在学本专业通信和计算机两专业的课程。每次放长假回家我都会带N多大砖块书回去看,而我在家里也确实 是没日没夜地看书,像一天看七八个小时的书的时候很多,过年除了走亲访友其它时候也不例外。而就算这样,我也感觉不到我的进步,我发现我更无知了,不知道 的东西更多了,我迷茫了…

我开始不知道我要干什么了,什么东西好像都知道,而又好像不知道,有时候静也静不下来,有时候卯足了劲却又不知道要干嘛,我迷失了…在 这个迷失的时期我认识了篮子,呵呵,一可爱的小女子,很有激情的,我看到了以前的我。可我的激情现要从何而来呢?我到底要干什么呢?苦笑…我开始胡逛网 了,以前基本不会去逛网的,以前逛网就是打开GOOGLE搜索我想知道的东西。在天涯社区里我遇到了很多人,有学生,有老板,有技术员,有销售兵,我的茫 然也在他们当中绝大多数中得到了体现,现今一个浮躁的社会…

我走上了考研路,可就是这难得的静下心来的时间却让我体会到了我以前从未想到过的东 西。你还在天天换LINUX发行版或汉化你的LINUX吗?你还会认为改注册表,编辑音频,使用黑客软件啥地很牛B么?你还在那因为看到每天蹦出来的高新 技术名词而激动不已,进而想要投身进去当做你的终身职业么?这都是因为浮躁而做得些SB事情,当然了,以前的我占了八成。我现只想告诫我自己几条,静下心 来拒绝浮躁,电脑只是工具,没必要重新发明轮子,学好自己的本专业分清主次,在技术和销售两分的转型期中国学好技术是必要的但技术不是全部。你说呢?

我现其实也只是刚刚从迷失中走出的小P孩,我走出了茫然,走出了浮躁,我也走完了大学…
不过,没关系,这只是新的开始…

阅读全文(1350) | 评论:14 | 复制链接

Tortoise And Rose(2007-10-25 13:09:00)

小乌龟的那只腿还是断的,

不想人为地粘起来,

附加的结合玷污心中的纯洁。

残缺也是一种美。

 

正儿八经地折过几朵纸玫瑰,

只有这朵最好,一直放在抽屉,

总会在打开抽屉时不经意地看到。

没有玫瑰的清香扑鼻,

也没有玫瑰的娇艳多姿,

只是安然地躺在抽屉的角落,

尘封心的气息。

 

有个人说,小乌龟像我,傻愣愣地~

我想永远是这只傻不啦叽地断腿小乌龟。

 

我们每个人都是只有一只翅膀的天使,

只有互相拥抱才会飞翔。

Only you can see...


阅读全文(1158) | 评论:6 | 复制链接

SDL在WINDOWS环境下的设置(DevCpp)(2007-10-23 10:35:00)

好多人问关于SDL在WINDOWS环境下的编译环境设置,

最近我有点“功课”,也必须在WINODWS下编译SDL程序,

有点心得,致那些热心于SDL 的朋友们。

以下是在DevCpp环境下的SDL设置(至于VC环境,没有实践,就不敢写了):

1.下载http://www.libsdl.org/release/SDL-1.2.12-win32.zip运行库,

运行SDL程序时压缩包里的sdl.dll要和程序在同一目录下。

2.下载http://www.libsdl.org/release/SDL-devel-1.2.12-mingw32.tar.gz开发库,

将解压后的SDL-1.2.xx目录下的include\SDL文件夹,及lib\*.*(下的所有文件)

分别拷到C:\devcpp(假设DevCPP装在C盘)文件夹下的include,lib文件夹下。

3.设置下DevCpp的连接器,写入 -lmingw32 -lSDLmain -lSDL -mwindows

就可以编译运行SDL程序了,头文件包含应该是<SDL/SDL.h>。


阅读全文(2101) | 评论:4 | 复制链接

单词表逆序程序(2007-6-13 20:15:00)

以前地ACM同胞现全有自己地事去了,继续搞ACM的现当然几乎成领军人物了,只有我这烂人还在这准备考研地说,正经程序就再没写几个,方便背单词的小程序倒自己写了N(N>10)个……哈哈,都笑我没品位呀……,其实都是些自己实用的程序,这个逆序程序好像还比较有用的……,背单词换个口味呢……

#include <iostream>
#include <string.h>

using namespace std;
const int N=8000;    //偶最多也只背这么多个

int cmp(char *a,char *b)
{
 char ta,tb;
 int la=0,lb=0;
 while(a[la]!='\0' && a[la]!=9 && a[la]!=' ' && a[la]!=','
    && a[la]!='(' && a[la]!= '[' && a[la]!='/' && a[la]!='.')
  la++;
 while(b[lb]!='\0' && b[lb]!=9 && b[lb]!= ' ' && b[lb]!=','
  && b[lb]!='(' && b[lb]!= '[' && b[lb]!='/' && b[lb]!='.')
  lb++;
 la--;
 lb--;
 while(la!=-1 || lb !=-1)
 {
  if(a[la]>='A' && a[la]<='Z')
   ta=a[la]+32;
  else ta=a[la];
  
     if(b[lb]>='A' && b[lb]<='Z')
   tb=b[lb]+32;
  else tb=b[lb];
  
  if(ta>tb)
   return 1;
  else if(ta<tb)
   return -1;
  else
  {
   la--;
   lb--;
  }
 }
}

int main()
{
 FILE *fp;
 int i,j,p=0,min;
 char ch[N][100]={0};
 char tmp[100];
 if((fp=fopen("in.csv","r"))==NULL)
 {
  cout << "read error" <<endl;
  return 1;
 }
 while(!feof(fp))
 {
  i=0;
  while( !feof(fp) 
    && (ch[p][i++]=fgetc(fp))!='\n');
  ch[p][i-1]='\0';
  p++;
 }
 p--;
 for (i=0;i<p;i++)
 {
  min = i;
  for (j=i+1;j<p;j++)
  {
   if(cmp(ch[j],ch[min])<0)
    min=j;
  }
  if(min != i)
  {
   strcpy(tmp,ch[min]);
   strcpy(ch[min],ch[i]);
   strcpy(ch[i],tmp);
  }
 }
 fclose(fp);
 fp=fopen("out.csv","w+");
 for (i=0;i<p;i++)
 {
  fprintf(fp,"%s\n",ch[i]);
 }
 fclose(fp);
}


阅读全文(1923) | 评论:2 | 复制链接

GBK点阵字体的显示(2007-1-18 20:17:00)

下文转自SOHU论坛   ,   软件开发   ->   C/C++版原著者为该版副版主     爱在远方  

一、汉字在计算机中的编码形式  
          我们都知道,在计算机中英文字符是用一个字节的ASCII码表示,该字节最高位一般用做奇偶校验,故实际是用7位码来代表128个字符的,但是对于众多的汉字,只有用两个字节才能表示,这样用两个字节来表示一个汉字的体制,国家制定了统一的标准,称为国标码。国标码规定,组成两个汉字代码的各字节最高位为0,这和英文字符表示方法相同,这就有可能把汉字的国标码看作两个ASCII码,为此又规定在计算机里表示汉字时,把最高位置1,表示该码是汉字,这种最高位为1的代码称为机器内的汉字代码,简称内码。计算机里汉字就是用内码表示的。  
          例如:“大”这个汉字,  
                  国标码   3473             00110100   01110011  
                  内码       B4F3             10110100   11110011  
          知道汉字在计算机里是用内码表示的以后,还需要知道具体汉字的结构。我国在1981年公布了《通讯用汉字字符集及其交换码标准》GB2312-80方案,里面规定了高频字、常用字、次常用字集合成汉字基本字符集(共6763个),再加上一些西文字母,希腊字母、日文字符、图形符号等一共700个。国家标准的汉字字符集在汉字操作系统中是以汉字库的形式提供的。汉字库规定,把字库分为94个区(区号),每个区有94个汉字(位号),这就是所谓的区位码(区位码第一字节是区号,第二字节是位号,因为知道了区位码就等于知道了该汉字在字库中的位置)。每个汉字在字库中是以点阵字模形式存储的,如一般采用16*16点阵形式,这样就需要32字节。在16*16点阵里,存1的点在显示时为一个亮点,存0的点不显示,这样汉字就显示出来了。简单写一下“大”这个字的字模:  
    0000001100000000  
    0000001100000000  
    0000001100000000  
    0000001100000010  
    1111111111111110  
    0000001100000000  
    0000001100000000  
    0000001100000000  
    0000001100000000  
    0000001110000000  
    0000011001000000  
    0000110000100000  
    0001100000010000  
    0001000000011000  
    0010000000001110  
    1100000000000100  
          这样当需要显示“大”这个汉字时,首先把这个字模取出,然后逐位显示,1显示0不显示,屏幕上就会出现“大”这个汉字。  
          那么我们怎么知道汉字的区位码呢?前面说了,汉字在计算机里是用内码存储的。内码和区位码的转换关系是(还以“大”为例):  
                  区号:B4-A0               位号:F3-A0  
          也就是说,把内码减去A0就是区位码,那么“大”这个汉字的区位码就出来了,是在14H区53H号,也就是第20区第83号。那么由于每个区有94个汉字,“大”这个字应该就是在汉字库的第(20-1)*94+(83-1)个汉字位置(每个汉字字模占32字节)。那么现在又要问了,内码又是怎样得到的呢?看下面的程序:  
                  main()  
                  {  
                          unsigned   char   *s="大";  
                          printf("%x,%x\n",s[0],s[1]);  
                          getch();  
                  }  
          运行程序发现,输出就是b4,f3。  
   
  二、西文方式下显示中文  
          说到这儿,大家应该有个思路了吧。要想显示汉字:  
              (1)   获得汉字内码  
              (2)   换算成区位码  
              (3)   在字库中取出该汉字的字模(共32字节)  
              (4)   1显示0不显示  

以下为自己写的小程序:

#include <iostream>
#include <SDL/SDL.h>

using namespace std;

char shape[32], in[256] = "中华人民共和国";
SDL_Surface *screen;
FILE *fp;

void
putpixel (SDL_Surface * img, int x, int y, Uint32 pixel)
{
 int bpp = img->format->BytesPerPixel;
 Uint8 *p = (Uint8 *) img->pixels + y * img->pitch + x * bpp;

 switch (bpp)
 {
 case 1:
  *p = pixel;
  break;
 case 2:
  *(Uint16 *) p = pixel;
  break;
 case 3:
  if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
  {
   p[0] = (pixel >> 16) & 0xff;
   p[1] = (pixel >> 8) & 0xff;
   p[2] = pixel & 0xff;
  }
  else
  {
   p[0] = pixel & 0xff;
   p[1] = (pixel >> 8) & 0xff;
   p[2] = (pixel >> 16) & 0xff;
  }
  break;
 case 4:
  *(Uint32 *) p = pixel;
  break;
 };
}

void
PutShape (unsigned char left, unsigned char right, int x, int y)
{
 unsigned char bits[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };
 int pos = 32 * ((left - 161) * 94 + (right - 161)), i, j;
 Uint32 pixel = SDL_MapRGB (screen->format, 255, 255, 255);

 fseek (fp, pos, SEEK_SET);
 fread (shape, 32, 1, fp);
 for (i = 0; i < 16; i++)
  for (j = 0; j < 8; j++)
  {
   if (shape[2 * i] & bits[j])
    putpixel (screen, x + j, i + y, pixel);
   if (shape[2 * i + 1] & bits[j])
    putpixel (screen, x + j + 8, i + y, pixel);
  }
}

void
PutStr (int x, int y)
{
 int length = strlen (in), i;

 for (i = 0; i < length; i += 2)
 {
  PutShape (in[i], in[i + 1], x, y);
  x += 16;
  if (x > 640)
  {
   x = 0;
   y += 16;
  }
 }
}
void
loop ()
{
 SDL_Event event;
 int running = 1;

 while (running)
 {
  SDL_Delay (50);
  while (SDL_PollEvent (&event))
  {
   switch (event.type)
   {
   case SDL_QUIT:
    running = 0;
    break;
   };
  }

  SDL_UpdateRect (screen, 0, 0, 0, 0);
 }
}

int
main ()
{
 if (SDL_Init (SDL_INIT_VIDEO) < 0)
  fprintf (stderr, "init error\n");
 if ((screen =
   SDL_SetVideoMode (640, 480, 32,
         SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL)
  fprintf (stderr, "setvideomode error\n");
 if ((fp = fopen ("HZK16", "r")) == NULL)
  fprintf (stderr, "open HZK16 error\n");
 atexit (SDL_Quit);
 PutStr (32, 2);
 loop ();
 fclose (fp);
 return 0;
}


阅读全文(2464) | 评论:2 | 复制链接

SDL版本的扫雷程序(2007-1-1 23:53:00)

元旦才刚放假,说实话,我很闲……
所以又写了个扫雷,这个扫雷程序其实真要算是“初学者”级的了……
里面就用到了一个比较像样的算法,…
就是点一个空的时候把邻近的所有连通的空格全部显出……
其实聪明人一下子就知道是搜索了,深搜广搜都可以了……我用的是深搜……
呵呵,程序很简单,但我还是写了这么长,不知怎么搞地……
可能很多地方还可以精简吧……我没刻意去怎么精简它……
因为反正是好玩呀……呵呵,关键的深搜算法写得好一点就差不多了……
正好温习一下落了些时日的算法了……

程序运行状态:


源程序:bomb.cc

/***************************************************************************
 *            bomb.cc
 *       扫雷
 *  Mon Jan  1 15:29:38 2007
 *  Copyright  2007  HuYinLin
 *  Email huyinlin@126.com
 ****************************************************************************/

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <iostream>

using namespace std;

#define FrameW 3  //边框厚
#define BASE_W 20  //小方块大小
#define LINE 16  //行数
#define COL  30 //列数
#define BOMB_NUM 80 //雷数
#define UP  30 //上方还有的其它东东
#define HW   FrameW*2+COL*BASE_W //屏幕宽
#define HH  FrameW+LINE*BASE_W+UP //屏幕高

#define FontW  10  //字体高度和宽度
#define FontH 18

int bomb[LINE][COL] = { };
int temp[LINE][COL] = { };

int frame[8][2] = {
 -1, 0, 1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, 1, 1, -1
};

int alive = 0, TIME;

SDL_Surface *screen,  //屏幕
 *nobomb,   //没有雷的区域
 *font,    //字体
 *dead,    //雷
 *flag,    //旗帜
 *error,   //错误标志
 *newgame,   //新游戏
 *back,    //小背景
 *cover;   //默认的图

SDL_Surface *
LoadIMG (const char *name)
{
 SDL_Surface *tmp, *final;
 if ((tmp = IMG_Load (name)) == NULL)
  fprintf (stderr, "load %s error\n", name);
 final = SDL_DisplayFormat (tmp);
 SDL_FreeSurface (tmp);
 SDL_SetColorKey (final, SDL_SRCCOLORKEY | SDL_RLEACCEL,
    *(Uint32 *) final->pixels);
 return final;
}

void
LoadData ()
{
 nobomb = LoadIMG ("nobomb.png");
 font = LoadIMG ("font.gif");
 dead = LoadIMG ("dead.png");
 cover = LoadIMG ("cover.gif");
 error = LoadIMG ("error.png");
 flag = LoadIMG ("flag.png");
 newgame = LoadIMG ("new.jpg");
 back = LoadIMG ("back.png");
}

int
over (int x, int y)  //测试是否超出边界
{
 if (x < 0 || x >= LINE || y < 0 || y >= COL)
  return 1;
 else
  return 0;
}

int
gameover ()
{
 int flag = 1;
 for (int i = 0; i < LINE; i++)
  for (int j = 0; j < COL; j++)
   if (bomb[i][j] == -1 && temp[i][j] != 1)
    flag = 0;
 return flag;
}

void
drawnum (int num)  //显示时间
{
 SDL_Rect dst, src;
 dst.x = FrameW, dst.y = FrameW;
 dst.w = FontW;
 dst.h = FontH;
 src.w = FontW;
 src.h = FontH;
 src.y = 0;
 int s[3] = { }, i = 2;
 while (num)
 {
  s[i--] = num % 10;
  num /= 10;
 }
 for (i = 0; i < 3; i++)
 {
  src.x = s[i] * FontW;
  SDL_BlitSurface (back, &src, screen, &dst);
  SDL_BlitSurface (font, &src, screen, &dst);
  SDL_UpdateRects (screen, 1, &dst);
  dst.x += FontW;
 }
}

void
creatbomb ()   //绘制雷区
{
 TIME = 0;
 drawnum (0);
 alive = 1;
 int i, j, x, y, num, k;
 for (i = 0; i < LINE; i++)
  for (j = 0; j < COL; j++)
  {
   bomb[i][j] = 0;
   temp[i][j] = 0;
  }
 for (i = 0; i < BOMB_NUM; i++)
 {
  x = rand () % LINE;
  y = rand () % COL;
  bomb[x][y] = -1; //-1表示此地有雷
 }
 for (i = 0; i < LINE; i++) //填其它的数
  for (j = 0; j < COL; j++)
   if (bomb[i][j] != -1)
   {
    num = 0;
    for (k = 0; k < 8; k++)
    {
     x = i + frame[k][0];
     y = j + frame[k][1];
     if (!over (x, y) && bomb[x][y] == -1)
      num -= bomb[x][y];
    }
    bomb[i][j] = num;
   }
}

void
initdraw ()   //初始时的画片
{
 int i, j;
 SDL_Rect src, dst;
 src.x = src.y = 0;
 src.w = back->w;
 src.h = UP;
 dst.y = dst.x = 0;
 dst.w = back->w;
 dst.h = UP;
 for (i = FrameW; i < HW; i += back->w)
 {
  SDL_BlitSurface (back, &src, screen, &dst);
  SDL_UpdateRects (screen, 1, &dst);
  dst.x += back->w;
 }

 dst.x = (HW - newgame->w) / 2;
 dst.y = (UP - newgame->h) / 2;
 dst.w = newgame->w;
 dst.h = newgame->h;
 SDL_BlitSurface (newgame, NULL, screen, &dst);
 SDL_UpdateRects (screen, 1, &dst);

 dst.w = dst.h = BASE_W;
 for (i = FrameW; i < HW - FrameW; i += BASE_W)
  for (j = UP; j < HH - FrameW; j += BASE_W)
  {
   dst.x = i;
   dst.y = j;
   SDL_BlitSurface (cover, NULL, screen, &dst);
  }
 SDL_UpdateRect (screen, FrameW, UP, COL * BASE_W, LINE * BASE_W);
}

void
FreeData ()
{
 SDL_FreeSurface (nobomb);
 SDL_FreeSurface (font);
 SDL_FreeSurface (dead);
 SDL_FreeSurface (cover);
 SDL_FreeSurface (flag);
 SDL_FreeSurface (error);
 SDL_FreeSurface (newgame);
 SDL_FreeSurface (back);
}

void
init ()
{
 if ((SDL_Init (SDL_INIT_AUDIO | SDL_INIT_VIDEO)) < 0)
  fprintf (stderr, "init error\n");
 if ((screen =
      SDL_SetVideoMode (HW, HH, 32,
          SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL)
  fprintf (stderr, "set video mode error\n");
 atexit (SDL_Quit);
 SDL_WM_SetCaption ("hard bomble", "");
 LoadData ();
 initdraw ();
 srand (time (NULL));
}

int
returnx (int a)   //真实坐标到数组坐标
{
 if (a < FrameW)
  return -1;
 return (a - FrameW) / BASE_W;
}

int
returny (int b)
{
 if (b < UP)
  return -1;
 return (b - UP) / BASE_W;
}

void
drawsurface (SDL_Surface * img, int x, int y)
{
 SDL_Rect dst;
 dst.x = y * BASE_W + FrameW;
 dst.y = x * BASE_W + UP;
 dst.w = img->w;
 dst.h = img->h;
 SDL_BlitSurface (img, NULL, screen, &dst);
 SDL_UpdateRects (screen, 1, &dst);
}

void
Bomb ()    //碰到雷了
{
 int i, j;
 alive = 0;
 SDL_Rect dst;
 dst.w = dst.h = BASE_W;
 for (i = 0; i < LINE; i++)
  for (j = 0; j < COL; j++)
  {
   if (temp[i][j] == 1 && bomb[i][j] != -1)
   {
    drawsurface (nobomb, i, j);
    drawsurface (error, i, j);
   }
   if (bomb[i][j] == -1)
   {
    dst.x = j * BASE_W + FrameW;
    dst.y = UP + i * BASE_W;
    drawsurface (nobomb, i, j);
    SDL_BlitSurface (dead, NULL, screen, &dst);
    SDL_UpdateRects (screen, 1, &dst);
   }
  }
}

void
drawchar (int num, int x, int y) //在图片上画雷的个数
{
 temp[x][y] = -1;
 SDL_Rect src, dst;
 src.w = FontW;
 src.h = FontH;
 src.x = num * FontW;
 src.y = 0;
 dst.w = FontW;
 dst.h = FontH;
 dst.x = y * BASE_W + FrameW + (BASE_W - FontW) / 2;
 dst.y = UP + x * BASE_W + (BASE_W - FontH) / 2;
 drawsurface (nobomb, x, y);
 SDL_BlitSurface (font, &src, screen, &dst);
 SDL_UpdateRects (screen, 1, &dst);
}

void
testvast (int x, int y)  //对一个非雷区进行递归搜索
{
 SDL_Rect dst;
 int a, b, k;
 dst.w = dst.h = BASE_W;
 dst.x = y * BASE_W + FrameW;
 dst.y = UP + x * BASE_W;
 SDL_BlitSurface (nobomb, NULL, screen, &dst);
 SDL_UpdateRects (screen, 1, &dst);
 bomb[x][y] = 10;
 for (k = 0; k < 4; k++)
 {
  a = x + frame[k][0];
  b = y + frame[k][1];
  if (!over (a, b) && temp[a][b] == 0)
  {
   if (bomb[a][b] == 0)
    testvast (a, b);
   else if (bomb[a][b] != -1)
    drawchar (bomb[a][b], a, b);
  }
 }
}

/* type=-1 左键
 type=0 中键
 type=1  右键
*/
void
handleevent (int type, int x, int y)
{
 if (alive)
 {
  switch (type)
  {
  case -1:
   if (temp[x][y] == 0)
   {
    if (bomb[x][y] == -1)
     Bomb ();
    else if (bomb[x][y] != 0)
     drawchar (bomb[x][y], x, y);
    else if (bomb[x][y] == 0)
     testvast (x, y);
   }
   break;
  case 0:
   if (bomb[x][y] != 0 && bomb[x][y] != -1
       && temp[x][y] == -1)
   {
    int k, num = 0, a, b;
    for (k = 0; k < 8; k++)
    {
     a = x + frame[k][0];
     b = y + frame[k][1];
     if (!over (a, b) && temp[a][b] == 1)
      num++;
    }
    if (num == bomb[x][y])
    {
     for (k = 0; k < 8; k++)
     {
      a = x + frame[k][0];
      b = y + frame[k][1];
      if (!over (a, b))
      {
       if (temp[a][b] != 1)
        handleevent
         (-1,
          a,
          b);
      }
     }
    }
   }
   break;
  case 1:
   if (temp[x][y] == 1)
   {
    drawsurface (cover, x, y);
    temp[x][y] = 0;
   }
   else if (temp[x][y] == 0)
   {
    drawsurface (flag, x, y);
    temp[x][y] = 1;
    if (gameover ())
    {
     alive = 0;
     for (int i = 0; i < LINE; i++)
      for (int j = 0; j < COL; j++)
      {
       if (bomb[i][j] == 0
           && temp[i][j] !=
           10)
        handleevent
         (-1,
          i,
          j);
       else if (bomb[i][j] !=
         -1
         && temp[i][j]
         != -1)
        drawchar (bomb
           [i]
           [j],
           i,
           j);

      }
    }
   }
   break;
  };
 }
}

int
pointatnew (int x, int y) //sdl坐标
{
 if (x < (HW - newgame->w) / 2
     || x > (HW - newgame->w) / 2 + newgame->w
     || y < (UP - newgame->h) / 2
     || y > (UP - newgame->h) / 2 + newgame->h)
  return 0;
 else
  return 1;
}

void
wait ()
{
 SDL_Delay (50);
}

void
rungame ()
{
 SDL_Event event;
 int timeisok = 0;
 Uint32 thistime, nexttime = 0;
 int run = 1, x, y;
 drawnum (0);
 while (run)
 {
  wait ();

  if (alive)
  {
   thistime = SDL_GetTicks ();
   if (thistime >= nexttime)
   {
    timeisok = 1;
    nexttime = thistime + 1000;
   }

   if (timeisok)
   {
    drawnum (TIME++);
    timeisok = 0;
   }
  }
  while (SDL_PollEvent (&event))
  {
   switch (event.type)
   {
   case SDL_QUIT:
    run = 0;
    break;
   case SDL_MOUSEBUTTONDOWN:
    x = returny (event.button.y);
    y = returnx (event.button.x);
    if (!over (x, y))
    {
     switch (event.button.button)
     {
     case SDL_BUTTON_LEFT:
      handleevent (-1, x, y);
      break;
     case SDL_BUTTON_RIGHT:
      handleevent (1, x, y);
      break;
     case SDL_BUTTON_MIDDLE:
      handleevent (0, x, y);
      break;
     };
    }
    else if (pointatnew
      (event.button.x, event.button.y))
    {
     creatbomb ();
     initdraw ();
    }
   }
  }
 }
}
int
main ()
{
 init ();
 rungame ();
 FreeData ();
}


阅读全文(2650) | 评论:3 | 复制链接