| You are here: | About>Computing & Technology>C / C++ / C#> Projects> Star Trek Conversion> Star Trek Conversion Article from C to Non STL C++ |
![]() | C / C++ / C# |
Star Trek Conversion Article from C to Non STL C++Being ObjectiveThis is the non STL command line version in C++. A future version will use the STL to demonstrate how useful it can be.
Redesigning the GameI started with a brief analysis and decomposed the game down to these basic classes
PrivitizationApart from the CQuadrants which are structs and have public access (a good design feature- use structs for holding data) I tried to make all data as private as possible. Things like the Damage[] array in CEnterprise bulked up the code quite a bit. Instead of a publicly accessing Enterprise.Damage[], this used accessor functions Enterprise.GetDamage(Index) and Enterprise.SetDamage(Index,Value). This also made what had been quite concise-Enterprise.Damage[index]--into the uglier Enterprise.SetDamage(DamageIndex, Enterprise.GetDamage(DamageIndex)-1)This is where properties (sadly a C# feature!) are quite useful. As an overall design strategy, making as much as possible private is good. It can of course get out of hand when there is a lot of data like in the CQuadrant class. Had all the data there been made private, it would have added considerable amounts of code to implement and use the accessor functions. I didn't like the existing code for inputting directions. This was written 30 years ago for a system with little floating point support (I guess) and I kept it in the C version but I rewrote it for this. You still enter the direction angle (0-359) where 0 is North etc. I now resolve this into two floating point vectors for East and South (negative means West and North). Photon Torpedoes and Warp Drive both call this. One thing to watch is that the cosine of angles between 270 and 90 are all positive whereas the game treats up as negative. There is a subtle difference between these lines in CGame::InputDirection(. Note the OffY = -. That's why that is there. OffY = -(float)cos( Angle*PI/180.0) ;Both functions work on angle in radians, not degrees. If you take a circle of radius R and measure R along the edge of the circle that is a radian. You'll find that in a full circle of 360 degrees there are exactly 6.283... (or 2 x PI) radians. So to convert from degrees to radians, multiply the angle in degrees by PI (3.14159 etc) and divide by 180. Now this is pretty gruesome code. int NewSX= (int)sqrt(abs(Speed*OffX))*sign(OffX) ;This calculates how far the Enterprise moves (horizontally and vertically in sectors for a given speed. Speed*OffX etc can be negative and you can't take the square root of a negative number. So the abs() function is used so the square root can be obtained. Then multiply it by the sign( ) function which I added to definitions.h and .cpp. This returns 1 if the value is positive, -1 if negative or 0 if it is 0. Having got the square root (using the cmath library call sqrt()), the (int) casts it to an int. Game Architecture OverviewThe game object holds game play details, game map and the Enterprise object. I moved CStarShip and Location into definitions.h. Much functionality such as moving the Enterprise, firing weapons etc is done in the Game object rather than the Enterprise object. This is by far the biggest class. Putting it in Game kept it simple.A quadrant is a 2d array of sectors and the map is a 2d array of quadrants. Sectors only hold one thing in each so an enum type SectorType is used in an array. A common problem in a hierarchy of classes and objects knowing how to get from one to the other. This is usually easiest from top to bottom and that also is why much of the functionality is in Game. Firing a torpedo for instance requires access to the map. From game, it is in Map. From the Enterprise, access to the map would have to be provided either via a map pointer or maybe a map reference or with a level of indirection from game. From the game object, it's easy to get a quadrant and sector within that quadrant. From the game object, it is also easy to access the Enterprise object as it's owned by the Game object. But consider from the point of view of the Enterprise object. All it knows is the quadrant and sector it is in. In a long range scan, how do we get from the Enterprise object to a quadrant? The only instance where the Enterprise objects needs to access the map is in the check for a Starbase, so the Map is passed in as a parameter to that function. However I did add a pointer to the owning Game object in each quadrant. This was used in placing Klingons in a quadrant and initializing them as they are owned by the Game object. References would have been better but you can't use a member initializer in the constructor for an array of objects. |
Las Vegas on a BudgetFind a BargainHotel DealsCheap EatsFree AttractionsEntertainment for Less |
All Topics | Email Article | | | ![]() |
| Advertising Info | News & Events | Work at About | SiteMap | Reprints | Help | Our Story | Be a Guide |
| User Agreement | Ethics Policy | Patent Info. | Privacy Policy | ©2008 About, Inc., A part of The New York Times Company. All rights reserved. |


