迷宫探险游戏,威老迷宫探险第二季--更面向对象

话说在第一季中,威老探访了乾陵,并成功地取回了大量的宝藏。
这次,威老卷土重来,前往***。。等待他的将是什么样的危险呢?
去***的人,都再也没有回来过,相传在那里生活着一群吃人的Monster,它们每天都在四处游荡。任何访客一旦碰上Monster,就会立马被吃掉!
OK,这就是我们这次的迷宫。
经过分析,我们可以发现,Monster和Explorer是有许多的共性的。他们都能够做简单判断,看四周的情况,并且都能够移动。这些所以这些函数我们可以提取出来,做成类供Monster和Explorer调用,以提高代码的可重用性。
我首先想到创建一个名为"RouteChecker"的类,然后把IsEastWalkAble()、IsSouthWalkAble()、IsWestWalkAble()、IsNorthWalkAble()、IsWalkAble()这几个函数通通装到 "RouteChecker" 里。这样一来就算要添加新品种的Monster也都
可以调用这个类来判断其周围的情况了。
但是光是这样明显存在很大的缺陷,如果我现在想要扩展一下RouteChecker类,那我就只能打开RouteChecker的代码进行修改,这明显违背了面向对象的基本原则之一:开放封闭原则。为了尽量封闭原本的代码,我引入了简单工厂模式。
以下便是使用了简单工厂模式之后的类图。
对RouteChecker类应用简单工厂模式之后获得的类图
迷宫探险游戏,威老迷宫探险第二季--更面向对象

根据这个模型获得代码。
以下是RouteChecker类:
/*routeChecker.h*/ /*路径检查类 功能: //检查是否已经到达终点 //检查东面是否可行走 //检查南面是否可行走 //检查西面是否可行走 //检查北面是否可行走 */ #ifndef _ROUTECHECKER_H #define _ROUTECHECKER_H #include"maze.h" /* 类名:RouteChecker 功能:检查路况 */ class RouteChecker { private: public: RouteChecker(){}; RouteChecker(Maze * Checked_Maze, int x, int y); virtual bool Check(){return true;}; //检查 void setCheckedMaze(Maze * ch_Maze) //设置要检查的迷宫 { checked_Maze = ch_Maze; }; void setCheckedPosition(int ch_x, int ch_y)//设置要检查的位置 { checked_x = ch_x; checked_y = ch_y; }; // int searchAround(); //搜索四周,以寻找下一个路径点。四个方向东、南、西、北。 //分别返回1、2、3、4,无路可走返回-1,到达终点返回0。 protected: Maze * checked_Maze; int checked_x,checked_y; bool checkWalkable(int x, int y); //检查指定位置是否可行走 }; /* 类名:ExitChecker 功能:检查是否已经到达终点 */ class ExitChecker : public RouteChecker { public: ExitChecker(){}; bool Check(); }; /* 类名:EastChecker 功能:检查东面是否可行走 */ class EastChecker : public RouteChecker { public: EastChecker (){}; bool Check(); }; // //。。。。。略去一些代码 // /* 类名:NorthChecker 功能:检查北面是否可行走 */ class NorthChecker : public RouteChecker { public: NorthChecker(){}; bool Check(); }; #endif
/*routeChecker.cpp*/ /*路径检查类 功能:分别检查各个方向是否可以行走。 */ #include"routeChecker.h" RouteChecker::RouteChecker(Maze * Checked_Maze, int x, int y) { checked_Maze = Checked_Maze; checked_x = x; checked_y = y; } /* 功能:检查位置(x,y)是否可行走 */ bool RouteChecker::checkWalkable(int x, int y) { if(checked_Maze->getSquareType(x, y) == '0') return true; else return false; } /* 功能:检查是否已经到达终点 */ bool ExitChecker::Check() { if( (checked_Maze->getexit_x() == checked_x) && (checked_Maze->getexit_y() == checked_y) ) { return true; } else return false; } /* 功能:检查东面是否可行走 */ bool EastChecker::Check() { if(checkWalkable(checked_x+1, checked_y)) { return true; } else return false; } // //。。。。。略去一些 // /* 功能:检查北面是否可行走 */ bool NorthChecker::Check() { if(checkWalkable(checked_x,checked_y-1)) { return true; } else return false; }
以下是工厂类:
/* 类名:RouteCheckerFactory 功能:RouteChecker工厂类,负责创建具体类型的RouteChecker */ #ifndef _ROUTECHECKERFACTORY_H #define _ROUTECHECKERFACTORY_H #include"routeChecker.h" class RouteCheckerFactory { public: RouteChecker* Create(int direction); }; #endif
/* 类名:RouteCheckerFactory 功能:RouteChecker工厂类,负责创建具体类型的RouteChecker */ #include"RouteCheckerFactory.h" RouteChecker* RouteCheckerFactory::Create(int direction) { RouteChecker *rc; switch(direction) { case 0: rc = new ExitChecker(); break;//出口 case 1: rc = new EastChecker(); break;//东 case 2: rc = new SouthChecker(); break;//南 case 3: rc = new WestChecker(); break;//西 case 4: rc = new NorthChecker(); break;//北 } return rc; };
修改了Explorer类:
这几个方法注释掉
/* bool IsInExit(); //检查是否已经到达终点 bool IsEastWalkable(); //检查东面是否可行走 bool IsSouthWalkable(); //检查南面是否可行走 bool IsWestWalkable(); //检查西面是否可行走 bool IsNorthWalkable(); //检查北面是否可行走 bool checkWalkable(int x, int y); //检查指定位置是否可行走 */
修改了searchAround()改为:
int Explorer::searchAround() { RouteChecker * rc; RouteCheckerFactory rcf; for(int i=0; i<=4; i++) { rc = rcf.Create(i); rc->setCheckedMaze(explored_Maze); rc->setCheckedPosition(current_x,current_y); if(rc->Check() == true) return i; } return -1; }

当然,程序的运行结果跟之前是完全一样的,但是就代码的质量来讲,这是上一个版本所无法比拟的。
做完这一切之后。。。我才发现又囧了searchAround()似乎也应该提取出来封装进RouteChecker.h里才好。而WalkTo()、walkToNext()、walkTowards(int direction)、goBack()这些也应该一并封装才是。
想到这里,我崩溃了。。。要知道我光是封装、测试Routechecker就搞了5个小时啊。。。
Monster还未出现,威老就要挂了!@#¥%……
不行,得想些其他的办法。。。
Tags:  面向对象程序设计 什么是面向对象 面向对象 迷宫探险 迷宫探险游戏

延伸阅读

最新评论

发表评论