- Feature Articles
- CodeSOD
- Error'd
-
Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
... so TRWTF is the lack of attention to code formatting details on case 10?
No, it's a complete lack of inspiration as to what to map case 11 to.
Admin
Admin
Maybe one enemy has parts that drop off as you attack it that have to be spawned as smaller enemies. In that case, 11 kind of makes sense.
Admin
I'm twinging at "Bell Pepper" having a space, but "OneGrape" does not.
Admin
I remember a while back having no luck trying to get a colleague to see the value of using enums over strings. We were dealing with country names, where the business logic might change depending on the country specified in the data being processed. I was trying to convey how it easy it is to slip a typo into your code with strings e.g. if (country == "Eblonia"), instead of "Elbonia", but using an enum name prevents that from occurring. He couldn't see the point.
Admin
If you get a few people in a room and everyone says "rutabaga" over and over again, it sounds like a crowded restaurant. Maybe that's what the coder was thinking?
Admin
Presumably it's because they originally used grapes and grape, then tried some kind of string search for 'grape' and got the wrong result
Admin
Well, you say game developers are not typically concerned with reusable code, but this thing is obviously borrowed from some fruit-oriented game with 12 enemy types, including one apparently very dangerous boss grape, and nobody enjoys writing serialization functions. Why reinvent the watermelon?
Admin
And we can tell it's dangerous because it's turned all the way up to ... eleven.
Admin
What was wrong with just using an array? (Aside from the complete lack of validation, that is.) Am I missing something?
Admin
In C# you use an enum (value type, usually derived from int) and just call the ToString() method. An array is an object type, it's slow and a waste of GC resources literally because it will end up just escalating in generations and the GC always have to make a pass over it - hence you want to avoid long living objects in general similiar to as you want to avoid allocing a lot of heap objects (aka reference types). With an enum the name is stored as type info meta data which the GC ignores by default.
In other words enums are way more efficient in every way, they are best practice and readable and you can add even more type information with attributes like DisplayName without losing out on refactoring capabilities or general overall performance and efficiency.
Admin
O(n) where there could be O(1) makes me hiss. In C++, I think I'd just do map<int,string>, along with a reverse mapping (array for int->string is appealing, but makes it harder to delete a specific ID later down the line). Not really knowing about C#, I do kind of like the enum approach in that language, although if I really want the spaces in the strings, I'd have to add in a replace and manage a special character. Also, I imagine it must also be storing some mapping permanently in memory in order to enact the conversions, so I don't see how memory is being handled any more minimally.
Admin
It's not O(n). Most compilers will optimize
switch
into a jump table. A good optimizer may even turn this whole function into an array reference.Admin
You're right! But I'll point out that while it runs in O(1), it's still O(n) code size!
Admin
Maybe the game in question it's a crossover between "Commander Keen: Keen Dreams" and "Eat Them To Defeat Them". Plus zombies. And one grape, provided by J.-B. E. Zorg...
Admin
We use annotations to give enums names for display. We then use helper methods for getting the name for an enum. Although I don't think that would be the best for performance in game code, as it uses reflection.
Admin
The code initializes returnData in declaration so there is no need for default case handling.
Admin
You must be new here. ;-)
Admin
The one enemy I'm missing is a pointed stick.
Admin
I think you've got the GC impact backwards. Rising in generations won't increase the GC cost, because the frequently-running GCs will ignore long-lived objects---that's the whole point of a generational GC is to optimize for scanning and reclaiming short-lived objects. The impact is more that if it ever gets released (which is unlikely in this case), it will be difficult and costly to convince the GC that it should reclaim the memory.
Admin
Makes me realise how valuable it is that some languages force you to cover the entire range of a data type in your switch statement, or it won't compile.
Admin
Using
std::map
for mapping short string to an integer, when you only have ~10 of these pairs, is the wrong way, actually. As weird as it might seem, a ladder of if-else will work much faster and will not allocate additional memory.Admin
It’s O(n) with n = 12 which makes it O(1). A switch statement is generated by the compiler, and it can be done wit a O(1) jump table, an O(log n) binary tree, or linear with six comparisons and 12 branches. The binary tree would tin in two nanoseconds.