C ++中的面向对象文本星际迷航游戏(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/the-object-oriented-text-star-trek-game-in-c-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 9 分钟阅读 - 4291 个词 阅读量 0C ++中的面向对象文本星际迷航游戏(译文)
原文地址:https://www.codeproject.com/Articles/28399/The-Object-Oriented-Text-Star-Trek-Game-in-C
原文作者:James Curran
译文由本站 robot-v1.0 翻译
前言
The Classic Super Star Trek Game rewritten in modern Object-oriented C++
用现代的面向对象C ++重写的经典超级星际迷航游戏
------*------
------------- `--- ------'
`-------- --' / /
\\------- --
'-----------'
The USS Enterprise --- NCC - 1701
Your mission begins with your starship located
in the galactic quadrant Canopus.
Your orders are as follows:
Destroy the 24 Klingon warships which have invaded
the galaxy before they can attack Federation Headquarters
on stardate 3732. This gives you 32 days. There are
3 starbases in the galaxy for resupplying your ship.
Hit any key to accept command.
------------------------
. . . . * . . . Stardate 3700
. . . . . . . . Condition GREEN
. * . . . . . . Quadrant (5, 4)
. . . * . . . . Sector (5, 2)
. <E> . . . . . . Photon Torpedos 10
. * . . . . . . Total Energy 3000
* . * * . . . . Shields 0
. . . . . . . * Klingons 24
------------------------
Command?
介绍(Introduction)
这是我参加2008年夏季代码项目随机编程竞赛的入口.似乎迈克尔`伯肯(Michael Birken)击败我,成为第一位发布<星际迷航>文章的人.由于这两个程序具有相同的历史记录和游戏玩法,他在文章中对此进行了广泛介绍,因此最好先阅读一个. (没关系..我等.)(Here is my entry into The Code Project Random Programming Competition for Summer 2008. It seems that Michael Birken beat me to being the first to post a Star Trek article. Since the two programs have a shared history and game play, which he covers extensively in his article, it’s best if you read that one first. (It’s OK…. I’ll wait.))
- 星际迷航1971文字游戏(Star Trek 1971 Text Game) 我将只专注于设计上的差异.(I’ll just concentrate on the difference in my design.)
背景(Background)
该港口绕过了CodeProject页面.正如Birken先生所描述的那样,Mike Mayfield的程序已由Creative Computing Magazine移植到PC上,并在1970年代后期出现在David Ahl的"基本计算机游戏,个人计算机版"中(我仍然签名).由于语言的限制,这是意大利面条代码的噩梦.然后,在1996年,一个名叫克里斯`尼斯特罗姆(Chris Nystrom)的人把该代码移植到了标准C.然而,这是一个非常直观的移植(很像伯肯先生的C#版本):几乎所有变量都是全局变量,保持其隐含的或两个字母名称,几乎所有函数都使用全局变量传递其参数并返回值.(This port took a roundabout journey to the pages of CodeProject. As Mr. Birken describes, Mike Mayfield’s program was ported to PCs by Creative Computing Magazine, and appeared in David Ahl’s “Basic Computer Games, Personal Computer Edition” (I still have my autographed copy) in the late 1970s. Due to the limitations of the language, it was a nightmare of spaghetti code. Then, in 1996, a man named Chris Nystrom took that code, and ported it to Standard C. However, it was a very literal port (much like Mr. Birken’s C# version): virtually all variables are global, maintaining their cryptic one or two letter names, and nearly all functions pass their parameters and return values using global variables.) 我喜欢这个主意,但是自从我们有了一种强大的语言可以使用它以来,我们应该充分利用它.因此,在1997年,我开始编写一个完全面向对象的版本.目标是使其具有与原始外观相同的外观,感觉和游戏方式,但具有现代的OO设计.(I liked the idea, but figured since we now had a powerful language to work with, we should use it to its full advantage. So, in 1997, I set out to write a fully object-oriented version. The goal was for it to have the same look & feel and game-play as the original, but with a modern OO design.) 不幸的是,那时的Visual C ++ 5.0有点不足-模板有点夸张,而STL根本无法工作.经过一天的工作,我放弃了.一年后,现在有了更加稳定的Visual C ++ 6.0,我花了整整三天的时间进行工作,然后又无聊又放弃了.(Unfortunately, Visual C++ 5.0 was a bit lacking back then – templates were a bit flakey, and the STL didn’t work at all. I gave up after a day’s work. A year later, now armed with the more stable Visual C++ 6.0, I put in all of three days work, before getting bored and abandoning it again.) 当比赛宣布时,我想起了这个长期被遗忘的项目,令我惊讶的是,我能够在我的家庭网络中的一台PC上找到代码(旧计算机永远不会消失,它们只是被重新利用了).(When the contest was announced, I remembered this long forgotten project, and to my surprise, I was able to find the code on one of the PCs on my home network (old computers never die, they are just repurposed).) 因此,凭借10年以上的OO设计经验(如果有些生锈的C ++技能)和可以正常工作的C ++编译器(Visual Studio 2008随Microsoft C ++ v15一起提供),我着手最终完成任务.(So, with 10 years more experience with OO design (if somewhat rusty C++ skills) and a C++ compiler that mostly works (Visual Studio 2008 comes with Microsoft C++ v15), I set out to finally complete the task.)
使用代码(Using the Code)
该代码没有什么特别值得注意的,除非您想跟踪我多年来对匈牙利符号和实例成员前缀的看法如何变化.或者我的本机C ++编码看起来很像带有接口和属性之类的托管C#代码.(There’s nothing particularly notable about the code, unless you want to track how my views on Hungarian notation and instance member prefixes changed over the years. Or how my native C++ coding looks a lot like managed C# code with things like Interfaces and Properties.)
关键的设计原则是关注点分离.游戏的整个宇宙被划分为小物体,它们处理了这个小世界的所有事物,并且除少数例外,对它之外的任何事物一无所知.(The key design principle is Separation of Concerns. The whole universe of the game is divided up into little objects, and they handle everything about their little piece of the world, and, with few exceptions, know nothing about anything outside of it.)
它的核心是一个自然而然地称为的对象,(At the heart of this is an object called, naturally enough,) Game
.的(. The) Game
对象知道我们的(object knows about our) Ship
,(, the) Galaxy
,以及当前时间,仅此而已.它的主要任务是处理游戏设置,确定游戏何时获胜以及接受玩家的命令.它还可以处理设计中的主要"骗局"-让敌人对(, and the Current Time, and not much else. It’s major task is to handle setting up the game, determining when the game is won, and accepting the players commands. It also handles the major “cheat” in the design – having the Enemy respond to something the) Ship
做到了.(did.)
接下来我们有(Next we have the) Ship
目的.的(object. The) Ship
知道的更多,但只有与整个船有关的事物.它知道它在银河系中的位置,知道它有多少能量,以及它是否停靠在星基上.它还知道它有几个子系统,每个子系统都派生自基类.(knows a bit more, but only things related to the ship as a whole. It knows its position in the galaxy, how much energy it has, and if it is docked to a starbase. It also knows that it has several subsystems, each of which derived from the base class) ShipSystem
.(.)
ShipSystem
它的派生类是游戏的核心.游戏的每个命令都有一个派生类. (其中一个命令是"辞职",这实际上不是船舶的系统,而是一个(and its derived classes are the core of the game. There is one derived class for each of the game’s commands. (One of those commands is “Resignation” which is not really a ship’s system, but is a) ShipSystem
派生类,因此类推有点中断,但我们将忽略它).(derived class, so analogy breaks a bit, but we’ll ignore that).)
通过基类,每个(Via the base class, each) ShipSystem
知道它的名称,描述(当您键入错误的命令时用于显示帮助输出),它的命令关键字以及拥有它的人.(knows its name, description (these are used to display the help output when you type a bad command) and its command keyword, and what ship owns it.) Ship
甚至不知道它有多少个子系统,或者它们的关键字是什么-它只是依次询问每个子系统,用户输入是否激活了它们.(doesn’t even know how many subsystems it has, or what their keywords are – It just asks each, in turn, if the user’s input activates them.)
的(The) ShipSytem
基类还负责管理每个系统的损坏和修复.(base class also handles the managing of damage and repairs to each system.)
然后,派生的类处理其特定系统的详细信息.例如,(Then, the derived classes handle the details of their own particular system. For example, the) Engines
对象接受行进的方向和距离,然后询问(object accepts a direction and distance to travel, and then asks the) Quadrant
反对移动它.的(object to move it. The) Quadrant
对象报告其到达的位置,以及沿途发生了什么(它撞到了什么东西吗?它是否进入了新象限?)(object reports back where it arrived, and what happened to it along the way (did it hit something? did it enter a new quadrant?))
同样,(Similarly, the)
LongScan
物体将注视星系的一小部分并显示其发现的内容.您可能会认为(object would look at a small part of the galaxy and display what it finds. You might think that for the) LongScan
看一下(to look at the) Galaxy
对象破坏了封装,但这正是该系统在现实生活中会做的事情(如果您将"星际迷航"视为"现实生活").(object is breaking encapsulation but it is exactly what that system would do in real life (if you consider Star Trek “real life”).)
另外两个基本类也很有趣:(Two other base classes are of interest:) ILocatable
和(and) IDisplayable
.(.) IDisplayable
功能类似于.NET世界中的接口;它只有一种方法,并且是纯虚拟的:(functions like an Interface in the .NET world; it has only one method and it’s pure virtual:) DisplayOn()
.基本上,(. Basically,) obj.DisplayOn(cout);
会将对象以其自己的唯一格式写入到(would write the object, in its own unique format, onto) cout
.然后我可以定义(. I can then define) operator<<
对于(for) ostream
和(&) IDisplayable
.(.)
ILocatable
是一个实现的基类,尽管其名称如此.它被用作在某个扇区中具有位置的任何对象的基类:您的船,克林贡,星星和鱼雷.(is a implemented base class, despite its name. It’s used as the base class for any object that has a position in a sector: your ship, the klingons, stars and torpedos.)
注意(Note):我用过一些(: I’ve used pieces of the)提升图书馆(Boost Libraries)((() www.boost.org(www.boost.org) ),因此您需要安装它们以重新编译源代码. Boost是一个由C ++类组成的广泛开放源代码库,由该领域的一些资深人士编写.如果您进行任何C ++编码,则无论如何都应该安装它.(), so you’ll need to have those installed to re-compile the source code. Boost is an extensive open-source library of C++ classes written by some of the best minds in the field. If you do any C++ coding, you should have it installed anyway.)
Command? srs
-----------------------
. . . . . . . . Stardate 2800
. . . . . . . . Condition GREEN
. . . . . . . . Quadrant (7, 8)
. . . . * . * . Sector (6, 7)
. . . * . . . . Photon Torpedos 10
. . . . . .<e /><E>. Total Energy 3000
. . . . . . . . Shields 0
. . . . . . . . Klingons 17
------------------------
Command? lrs
Long Range Scan for Quadrant (7, 8)
--------------------
: 004 : 208 : *** :
--------------------
: 006 : 003 : *** :
--------------------
: 102 : 016 : *** :
--------------------
Command?
未来(Future)
与每个项目一样,我始终将重大更改放在可以改进的地方,但是最后期限迫在眉睫,我不想做任何激进的事情.但是需要进行大修.(As with every project, along the way I placed where a major change would make a big improvement, but a deadline loomed, and I didn’t want to do anything radical. But a major overhaul is needed.)
第一件事是,我意识到象限和部门之间的区别为时已晚,因为两者之间没有区别,因此应该合并这两个类.这将使大量的代码更加简单.(The first thing is that I realized too late the difference between a Quadrant & a Sector – there isn’t one – so those two classes should be merged. That would make a large swath of code much simpler.)
我还决定,这确实需要事件驱动的设计,因此,象限将触发一个事件,例如其中移动了一个对象,而Klingons将侦听该象限,并知道会触发.而不是当前的设计,引擎告诉(I also decided that this really needs an event-driven design, so the quadrant would fire an event say an object moved within it, and that Klingons would listen to the quadrant, and know to fire back. Rather than the current design, where the Engines tell the) Game
反对告诉克林贡人回击.但是Standard C ++库不包含消息传递框架,因此我不想构建自己的消息传递框架.(object to tell the klingons to fire back. But the Standard C++ library doesn’t include a message passing framework, and I didn’t want to build my own.)
但是,.NET确实有一个这样的框架,它内置在其核心中.我最初以为我不能轻易将其移植到C#,因为我使用了多重继承,但是现在我相信这很容易排除.但是,我在夏天将许多其他工作放在一边,以进行此工作,因此该项目将不得不等待明年夏天.(However, .NET does have such a framework, built right into its core. I had first thought I couldn’t port this easily to C#, because I had used multiple inheritance, but I now believe that would be easy to factor out. But, I put a lot of other work aside for the summer to work on this, so that project will have to wait for next summer.)
历史(History)
- 5(5)日(th)2008年8月-考虑到该程序的历史(请参见上文),将其称为" 1.0版"有点愚蠢,但是,不管怎么说,这是该版本的第一个发行版.(August, 2008 - Considering the history of this program (see above), it’s a bit silly to call it “version 1.0”, but, whatever, this is the first release of this rendition.)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C++ Windows Dev 新闻 翻译