Creative Commons License
本Blog采用 知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议 进行许可。 —— Fox <游戏人生>

游戏人生

游戏人生 != ( 人生 == 游戏 )
站点迁移至:http://www.yulefox.com。请订阅本博的朋友将RSS修改为http://feeds.feedburner.com/yulefox
posts - 62, comments - 508, trackbacks - 0, articles - 7

本文同步自游戏人生

现在有些年轻人的心态比较浮躁,大致总结以下『四点表现』:

1. 眼高过顶;

2. 垂手过膝;

3. 期望值高;

4. 积极性低。

深层次的客观原因大致是『四个没有』:

1. 没有吃过苦;

2. 没有干过活;

3. 没有说过话;

4. 没有当过家。

一般都具有『四个特征』:

1. 独生子女;

2. 毕业新人;

3. 沉默寡言;

4. 半瓶开水。

---------------------------------

1. 你想要什么?

参考:一个有影响力的人。(@李开复

2. 那是否是你想要的?

参考:你的眼光有多远,决定了你能走多远。(@Fox

3. 你需要做什么?

参考:高筑墙,广积粮,缓称王。(朱元璋)

4. 你还需要做什么?

参考:平和的心态,进取的态度,坚定的目标,不懈的努力。(@Fox

5. 你是否做到了?

参考:没有,但我一直在努力。(@Fox

posted @ 2009-08-17 16:31 Fox 阅读(1960) | 评论 (4)编辑 收藏

本文同步自游戏人生

-----------------------读书-----------------------

想读《UNIX Network Programming》很久了,只是这种愿望一直没有特别强烈。用的笔记本换了之后强迫自己只是装了cygwin,没有安装VS,平时写些代码就只能在cygwin下用gcc了。最近对UNIX环境编程和网络基础比较感兴趣,于是读这本书终于提上了议事日程,可是大多数书店都没有这本书了。

工作之后,对于自己喜欢的书,就很少会去看电子版,觉得还是捧卷在手的感觉舒服一些,想怎么看怎么看,享受拿笔在上面写写画画的感觉。因此对于想读但买不到的书,第一反应是等待。在翻电脑上面一些资料的时候才反应过来我已经很久没有down过电子书了,结果就从网上down了很多想读(豆瓣)的书,forgive me, Richard Stevens and anybody.

-----------------------动手-----------------------

之前只是在Windows下用过ACE,因为ACE提供了VS各种版本的解决方案,编译过程比较简单。这次放在cygwin下编译的时候,因为环境变量设置问题,并不是非常顺利,参照了源码目录下的ACE-INSTALL.html的描述才将问题解决。现在将过程给出来,仅供google到这里的同学参考:

友情提示:我目前对于cygwin和UNIX类系统的了解停留在知其然(还是在google之后)的水平。

1. 增加环境变量

o 修改/etc/profile文件读写属性:

$ chmod 777 /etc/profile

cygwin下的环境变量可以在该文件中配置,由于该文件默认具有写保护属性,因此需要修改使之可写,修改完成之后应该记得对其进行写保护:

$ chmod 555 /etc/profile

o 打开profile文件(本人使用emacs进行编辑,读者也可以使用vi、vim等,在此不再赘述):

$ emacs /etc/profile

o 往profile中修改和添加环境变量:

将以下五行添加到文件中,ACE_ROOT为ACE源码目录,本文用到的目录是/usr/share/ace:

ACE_ROOT=/usr/share/ace
export ACE_ROOT

LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH

# export PATH=$ACE_ROOT/ace:$PATH

这个操作等同于在VS下修改库文件目录,我是直接修改了PATH变量的:

PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:$ACE_ROOT/ace:$PATH

o 执行/etc/profile

$ /etc/profile

执行修改后有可能需要重启cygwin,可使用下面的命令查看ACE_ROOT设置是否正确:

$ echo $ACE_ROOT

2. 创建若干文件:

o 在$ACE_ROOT/ace 文件夹中创建名为 config.h 的文件,并加入以下内容后保存关闭:

#include "ace/config-cygwin32.h"

o 在$ACE_ROOT/include/makeinclude 文件夹中创建名为 platform_macros.GNU 的文件,并加入以下内容保存关闭:

include $(ACE_ROOT)/include/makeinclude/platform_cygwin32.GNU

3. 编译ACE:

$ cd $ACE_ROOT/ace
$ make

大概会花掉十几分钟时间吧。

4. 测试ACE:

$ cd $ACE_ROOT/tests
$ make

大概又会花掉十几分钟时间吧。

接下来就可以使用perl脚本完成所有测试,我没有使用过perl,临时安装了一下。

$ perl run_test.pl

这个脚本在我一位同事的机器上跑了很久(十几分钟 or 几十分钟?),不幸的是,Windows竟然抛出了一个内存读写错误,更加不幸的是,我现在没有能力去确定。

结果周末后面的时间又花在熟悉EMacs上了,还没有看ACE的代码,只有下周才能看了。

-----------------------结束-----------------------

这种小学生的东西拿出来讲确实是很难为情的,然而,于我现在却又算是极大的一个收获。真等我熟悉了其中的很多内容,又未必会再有耐心说了。所以还是记录一下,既是鼓励,也是督促。

晚上睡觉之前翻了一下《ACE程序员指南:网络与系统编程的实用设计模式》,发现里面2.3节也讲到了怎么安装。

posted @ 2009-08-17 09:52 Fox 阅读(2212) | 评论 (2)编辑 收藏

在一个稍微上规模(怎么也有几十个类吧)的C++程序中,继承和组合的使用比比皆是。虽然GoF提出了OOD的两个原则,第二个谓之『优先使用对象组合,而不是继承』,但这绝不意味着不使用继承,正因如此,第一个原则才是『针对接口编程,而不是针对实现编程』,这两个原则清楚的表达了软件工程中『低耦合』的思想。

模板方法(Template Method)的意图正是『定义一个操作中的算法的框架,而将一些步骤延迟到子类中』。

注意,这里有个关键词『一些』,既然是『一些』,就意味着父类的的接口中已经实现了『一些』步骤,否则,父类便只提供了抽象接口。

这一情况是我们在编码时时常遇到的,父类实现了部分算法中的通用行为,子类根据自己的需求可对其进行必要扩充。

class CBase
{
public:
    // Default done
    virtual void Operation(void)
    {
        ...
    }
};

class CDerive :
    public CBase
{
public:
    virtual void Operation(void)
    {
        switch( ... )
        {
        case A: ...
        case B: ...
        case c: ...
        default:
            CBase::Operation();
        }
    }
};

因为对父类的不了解或是对子类的太了解,你以为CDerive::Operation()做了足够多,不需要CBase::Operation(),但实际上仍然需要的情况总在发生。

换一种方式,把Operation()作为模板方法,把DoOperation()作为可扩展的接口提供给子类实现:

class CBase
{
public:
    void SetFocus(void) { ... }
    void ResetFocus(void) { ... }
    // Call by user
    void Operation(void)
    {
        SetFocus();
        DoOperation();
        ResetFocus();
    }
    // Default done
    virtual void DoOperation(void) = 0;
};

class CDerive :
    public CBase
{
public:
    virtual void DoOperation(void)
    {
        ...
    }
};

模板方法只是提供了一个简单的封装技巧,当然不是所有的虚接口都这么写:)。


更多内容请移步我的个人主页

posted @ 2009-02-11 01:46 Fox 阅读(1888) | 评论 (2)编辑 收藏

VS2005下使用VC,部分断点无效,显示『当前不会命中断点。还没有为该文档加载任何符号』。

试过以下一些方法:

1、无效断点所在的项目和启动项目的设置:项目->属性->配置属性->C/C++->常规->调试信息格式,这里不能为『禁用』;

2、项目->属性->配置属性->链接器->调试->生成调试信息,这里设为『是』;

3、C/C++->优化->优化选择『禁用』;

4、删除解决方案下的.ncb文件;

5、工具->选项->调试->『要求源文件与原始版本完成匹配』去掉勾;

6、最后在上述设置的情况下,重新编译整个解决方案;

7、回过头来,发现原来是一段不会被执行到的代码……

看来,除了VS本身会有bug,自己的代码还是要多检查一下。

posted @ 2009-01-04 11:04 Fox 阅读(14504) | 评论 (26)编辑 收藏

本文最早发布于我的个人主页

一般的RPG游戏中,玩家角色、NPC、物品、场景等一般都具有为数众多的各种属性,使用C++编码时,很容易考虑设计成为大量的成员变量和相应的存取函数:

class CObject
{
public:
    long GetAttrA(void) const { return m_lAttrA; }
    void SetAttrA(long lVal) { m_lAttrA = lVal; }
    long GetAttrB(void) const { return m_lAttrB; }
    void SetAttrB(long lVal) { m_lAttrB = lVal; }
    ...
    long GetAttrN(void) const { return m_lAttrN; }
    void SetAttrN(long lVal) { m_lAttrN = lVal; }

private:
    long m_lAttrA;
    long m_lAttrB;
    ...
    long m_lAttrN;
};

乍一看,非常清晰明了。在一个稍显复杂的项目中,想记住、甚至找到每一个属性是非常难的,况且除了属性,还有大量的逻辑处理,甚至是不同项目间的数据交互,比如将属性的数据库存取。这么做的缺点大致有这么几点:

1. 属性没有明确分门别类,尤其在多人协作、多模块编写时,往往上面一批、下面一批,甚至有重复属性、废弃属性,难于管理和把握;

2. 对于数据库存取,需要写单独的存取接口,而且一旦属性有增减、修改,存取接口要随之修改;

3. 通过接口函数进行简单的属性存取面临大量的堆栈保存,即使使用内联或宏定义,也是治标不治本。

针对上述问题,我的思路也比较简单:对基本类型数据进行二次封装。

struct tagDBAttrs
{
    long lA;
    long lB;
    ...
    long lN;
};

class CObject
{
public:
    const tagDBAttrs& GetDBAttrs(void) const { return m_DBAttrs; }
    void SetDBAttrs(const tagDBAttrs& rDBAttrs)
    {
        memcpy(&m_DBAttrs, rDBAttrs, sizeof(m_DBAttrs));
    }

private:
    tagDBAttrs    m_DBAttrs;
    string        m_strA;
    CObject*      m_pObjB;
    CShape*       m_pShapeC;
    ...
};
 

之所以提到基本类型数据,主要缘于基本类型构成的结构可以通过sizeof运算符直接确定,而像类对象等组合类型,其深拷贝、赋值、操作及赋值等逻辑则较为复杂,一般无法统一处理。

以上面的tagDBAttrs为例,对于基本类型数据处理具有非常大的优势,尤其在数据整体存取时,此外,增减基本类型属性也比较简单,而且不需要重写Get/Set接口,同时方便了对属性的分门别类处理。


此处顺便谈谈关于开发中的一些杂的体会。

对于工作不久的同学而言,拿到一个任务有可能出现以下两种情况:

1. 以快速开发为重,前期进展较快,在小型模块开发中顺风顺水,但在面对复杂任务时,因为对前期设计重视不足,后期会不断调整代码,甚至在基本功能开发结束后,因为逻辑架构问题,导致bug隐患较多较深,容易陷入泥沼,痛苦挣扎;

2. 随时随处追求代码结构的优美和执行效率的优化,精益求精,往往在前期设计上花费过多的心思,以达到较合理的逻辑结构,甚至拖延整个项目的开发进度,这种同学一般说来,代码质量较高,后期bug较少。

其实,上面说的就是我自己,我刚开始工作的时候,上面给我一个编写独立工具的任务,当时急于表现,缺乏项目实战经验,为编码而编码,逻辑结构不注重扩展性,设计不合理,在进行到后期时,面对出现的新需求无法应对,导致最后推到重来。

后来,慢慢接受了注重前期设计的观念,更因为自己的完美情结和代码洁癖,不仅经常调整自己编码中不优美的片段,甚至越俎代庖去修改其他同事的代码,追求处处的高效,耗费大量时间精力,难以自拔。

在任何一个项目中,都有轻重主次之分,也就是所谓的『8020原则』,关于『8020原则』怎么理解都行,我的理解就是,每个项目中的效率瓶颈是20%的核心代码,80%的时间和工作重心应该放到这20%的核心代码上。放到一个小的模块中也是这样,应该确定工作重心,在开发进度的限制下,对核心代码精益求精,对非效率瓶颈可以适当减少侧重。

对于新人,最难的就是从整体的高度确定20%的工作重心,这主要依赖于自身素质的提高和开发经验的积累。而对需求深入细致的分析和对逻辑精益求精的设计本身可以训练一个人分析问题、解决问题的能力。

总结一下的话,也正是我们项目组历来所倡导和坚持的:

1. 精益求精;

2. 细节决定成败,态度制约能力。

posted @ 2008-12-28 02:44 Fox 阅读(1923) | 评论 (4)编辑 收藏

不知道Singleton算不算用的最多的,平时用的时候,往往都是直接敲下面一段:

……

不是不想改,就是懒,敲多了已经不觉得这么写多浪费时间了,按大家的说法,这样写至少有这么几个缺点:

1. 必须在程序结束前手动释放,这不仅是RP问题,如果你借了内存不主动还,说明你RP差,但被别人搞丢了(宕机)导致你还不上,说明别人RP差?所以,这还是个问题;

2. 线程同步问题,如果Singleton实例跨线程使用,上例不安全,在Initial和Release时加锁可以解决;

3. 最大的问题:不能重用。

阅读全文

posted @ 2008-11-19 23:37 Fox 阅读(1915) | 评论 (4)编辑 收藏

State模式对应到C++的多态特性。

State模式适用较广,这儿给出比较常见易懂的三种情况:

1. 当怪物在面对不同职业和特性的玩家时对应不同的AI处理和技能释放:

CSkill* pAttackSkill;

if( pPlayer->MagicImmune() ) pAttackSkill = SomePhysicalAttackSkill;

else if( pPlayer->PhysicalImmune() ) pAttackSkill = SomeMagicAttackSkill;

...

pAttackSkill->Begin();

...

或者使用分支结构:

CSkill* pAttackSkill;

switch( pPlayer->GetOccupation() )

{

  case WARRIOR: pAttackSkill = SomeLongRangeSkill; break;

  case MAGICIAN: pAttackSkill = SomeForceSkill; break;

  case NIMROD: pAttackSkill = SomeMagicSkill; break;

...

}

pAttackSkill->Begin();

...

阅读全文

posted @ 2008-11-19 00:57 Fox 阅读(1835) | 评论 (3)编辑 收藏

因站点迁移。请订阅本博的朋友将RSS修改为http://feeds.feedburner.com/yulefox

个人主页地址:http://www.yulefox.com

posted @ 2008-11-10 11:17 Fox 阅读(801) | 评论 (4)编辑 收藏

之所以要写这个东西,是因为由最近发生的腾讯竞业禁止案发散思维了。借机反思一下员工对企业认同的源与流

之所以要写Google,Google是我的梦,正像我当初在一份简历中写道的:

Game is my interest, so I like developing my game; Google is my life, so I love enjoying my life.

我的工作、学习、生活离不开Google:My indispensable tools: Gmail, G.cn, Code, iGoogle, Picasa, Reader, Talk, Notebook, Map, Calendar, Documents, Google Pinyin, Chrome, etc.

不煽情了,坊间流传的最多的就是富有传奇色彩Google的工作环境和待遇,下图可以说明很多问题了:

阅读全文……

posted @ 2008-11-10 00:13 Fox 阅读(2487) | 评论 (9)编辑 收藏

现在每天的工作主要是为了满足项目需求和进度而不停的思考、敲键盘。有时候也确实需要抽点时间来思考思考那些看上去用不到的一些东西,又想起了Fibonacci数

之前曾经三次写过Fibonacci数:2007年4月的我的Fibonacci数列,2007年12月的也说说级数求和(1+2+3…N)和其他,2008年5月的动态规划算法,但给出的都不是非常优的算法。

上次回去把同学借的《编程之美》偷过来还没怎么看,晚上翻了一下,看到有讲Fibonacci数,想起来的The Art of Computer Programming Vol.1也讲过,觉得有必要对Fibonacci数做个了断。

诚如在The Art of Computer Programming Vol.1所述,是中世纪以来欧洲最伟大的数学家,他关于al-Khwarizmi的研究催生了算法(algorithm)一词。

阅读全文

看到这些,我又激动了,数学之美,不正是美在这些地方吗?我们不是要做数学家,但这并不妨碍我们站在门口向里张望……

posted @ 2008-11-06 00:34 Fox 阅读(2025) | 评论 (2)编辑 收藏

仅列出标题
共7页: 1 2 3 4 5 6 7