Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 235347
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T20:15:27+00:00 2026-05-11T20:15:27+00:00

The Problem: I am trying to extract a valid game mode for Defense of

  • 0

The Problem: I am trying to extract a valid game mode for Defense of the Ancients (DotA) from a game name using C++.

Details:

  • Game names can be, at most, 31 characters long
  • There are three game mode categories: primary, secondary, and miscellaneous
    • There can only be 1 primary game mode selected
    • Certain primary game modes are incompatible with some secondary game modes
    • Certain secondary game modes are incompatible with other secondary game modes
    • Miscellaneous game modes can be combined with all other game modes

Here are a list of the various game modes, with a chart showing which secondary modes each mode is compatible with (X means incompatible):

// Only 1 primary allowed
static char *Primary[] = {
          // Compatible with > | dm | rv | mm | du | sh | aa | ai | as | id | em | np | sc | om | nt | nm | nb | ro | mo | sp | 
    "ap", // All Pick          |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "ar", // All Random        |    | X  |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "tr", // Team Random       | X  | X  |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "mr", // Mode Random       | X  | X  |    |    | X  | X  | X  | X  |    |    |    |    |    |    |    |    | X  | X  |    |
    "lm", // League Mode       | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  |    |
    "rd", // Random Draft      | X  | X  | X  |    | X  | X  | X  | X  |    |    |    |    |    |    |    |    | X  | X  |    |
    "vr", // Vote Random       | X  | X  | X  |    | X  | X  | X  | X  |    |    |    |    |    |    |    |    | X  | X  |    |
    "el", // Extended League   | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  |    |
    "sd", // Single Draft      | X  | X  | X  |    | X  | X  | X  | X  |    |    |    |    |    |    |    |    | X  | X  |    |
    "cm", // Captains Mode     | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  | X  |
    "cd"  // Captains Draft    | X  | X  | X  |    | X  | X  | X  | X  |    |    |    |    |    |    |    |    | X  | X  |    |
};

static char *Secondary[] = {
          // Compatible with > | dm | rv | mm | du | sh | aa | ai | as | id | em | np | sc | om | nt | nm | nb | ro | mo | sp | 
    "dm", // Death Match       |    | X  | X  |    | X  | X  | X  | X  |    |    |    |    |    |    |    |    | X  | X  |    |
    "rv", // Reverse Mode      | X  |    |    |    | X  |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "mm", // Mirror Match      | X  |    |    |    | X  |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "du", // Duplicate Mode    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "sh", // Same Hero         | X  | X  | X  |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "aa", // All Agility       | X  |    |    |    |    |    | X  | X  |    |    |    |    |    |    |    |    |    |    |    |
    "ai", // All Intelligence  | X  |    |    |    |    | X  |    | X  |    |    |    |    |    |    |    |    |    |    |    |
    "as", // All Strength      | X  |    |    |    |    | X  | X  |    |    |    |    |    |    |    |    |    |    |    |    |
    "id", // Item Drop         |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "em", // Easy Mode         |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "np", // No Powerups       |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "sc", // Super Creeps      |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    | 
    "om", // Only Mid          |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "nt", // No Top            |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "nm", // No Middle         |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
    "nb", // No Bottom         |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    | 
    "ro", // Range Only        | X  |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    | X  |    | 
    "mo", // Melee Only        | X  |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    | X  |    |    | 
    "sp"  // Shuffle Players   |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
};

// These options are always available
static char *Misc[] = {
    "ns", // No Swap
    "nr", // No Repick
    "ts", // Terrain Snow
    "pm", // Pooling Mode
    "oi", // Observer Info
    "mi", // Mini Heroes
    "fr", // Fast Respawn
    "so"  // Switch On
};

Examples: Here are some example input, with the desired output:

“DotA v6.60 -RDSOSP USA/CA LC!” -> “rdsosp”

“DOTA AREMDM USA LC” -> “aremdm”

“DotA v6.60 -ApEmDuSpId USA BL” -> “apemduspid”

Notes: The solution doesn’t necessarily have to provide actual code, pseudo-code and even just an explanation of how you would handle it is acceptable and preferred. Also, the solution needs to be flexible enough to where I can add another game mode fairly easily. It is also safe to assume that within the game name, the game mode will always start with a primary game mode.


Result:

#include <cstdarg>
#include <algorithm>
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <vector>

std::map<std::string, std::vector<std::string> > ModeCompatibilityMap;

static const unsigned int PrimaryModesCount = 11;
static char *PrimaryModes[] = { 
    "ap", "ar", "tr", "mr", "lm", "rd", "vr", "el", "sd", "cm", "cd"
};

static const unsigned int SecondaryModesCounts = 19;
static char *SecondaryModes[] = {
    "dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np",
    "sc", "om", "nt", "nm", "nb", "ro", "mo", "sp"
};

static const unsigned int MiscModesCount = 8;
static char *MiscModes[] = {
    "ns", "nr", "ts", "pm", "oi", "mi", "fr", "so" 
};

std::vector<std::string> Vectorize( int count, ... ) {
    std::vector<std::string> result;

    va_list vl;
    va_start( vl, count );

    for ( int i = 0; i < count; ++i ) {
        char *buffer = va_arg( vl, char * );
        result.push_back( buffer );
    }

    va_end( vl );

    return result;
}

void InitializeModeCompatibilityMap() {
    // Primary
    ModeCompatibilityMap["ar"] = Vectorize( 1, "rv" );
    ModeCompatibilityMap["tr"] = Vectorize( 2, "dm", "rv" );
    ModeCompatibilityMap["mr"] = Vectorize( 8, "dm", "rv", "sh", "aa", "ai", "as", "ro", "mo" );
    ModeCompatibilityMap["lm"] = Vectorize( 18, "dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np", "sc", "om", "nt", "nm", "nb", "ro", "mo" );
    ModeCompatibilityMap["rd"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
    ModeCompatibilityMap["vr"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
    ModeCompatibilityMap["el"] = Vectorize( 18, "dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np", "sc", "om", "nt", "nm", "nb", "ro", "mo" );
    ModeCompatibilityMap["sd"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
    ModeCompatibilityMap["cm"] = Vectorize( 19, "dm", "rv", "mm", "du", "sh", "aa", "ai", "as", "id", "em", "np", "sc", "om", "nt", "nm", "nb", "ro", "mo", "sp" );
    ModeCompatibilityMap["cd"] = Vectorize( 9, "dm", "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );   
    // Secondary
    ModeCompatibilityMap["dm"] = Vectorize( 8, "rv", "mm", "sh", "aa", "ai", "as", "ro", "mo" );
    ModeCompatibilityMap["rv"] = Vectorize( 2, "dm", "sh" );
    ModeCompatibilityMap["mm"] = Vectorize( 2, "dm", "sh" );
    ModeCompatibilityMap["sh"] = Vectorize( 3, "dm", "rv", "mm" );
    ModeCompatibilityMap["aa"] = Vectorize( 3, "dm", "ai", "as" );
    ModeCompatibilityMap["ai"] = Vectorize( 3, "dm", "aa", "as" );
    ModeCompatibilityMap["as"] = Vectorize( 3, "dm", "aa", "ai" );
    ModeCompatibilityMap["ro"] = Vectorize( 2, "dm", "mo" );
    ModeCompatibilityMap["mo"] = Vectorize( 2, "dm", "ro" );
}

std::vector<std::string> Tokenize( const std::string &string ) {
    std::vector<std::string> tokens;
    std::string token;
    std::stringstream ss( string );

    while ( ss >> token ) {
        tokens.push_back( token );
    }

    return tokens;
}

void SanitizeString( std::string &in ) {
    std::transform( in.begin(), in.end(), in.begin(), tolower );

    for ( size_t i = 0; i < in.size(); ++i ) {
        if ( in[i] < 'a' || in[i] > 'z' ) {
            in.erase( i--, 1 );
        }
    }
}

std::vector<std::string> SplitString( const std::string &in, int count ) {
    std::vector<std::string> result;

    if ( in.length() % count != 0 ) {
        return result;
    }

    for ( std::string::const_iterator i = in.begin(); i != in.end(); i += count ) {
        result.push_back( std::string( i, i + count ) );
    }

    return result;
}

bool IsPrimaryGameMode( const std::string &in ) {
    for ( int i = 0; i < PrimaryModesCount; ++i ) {
        if ( strcmp( PrimaryModes[i], in.c_str() ) == 0 ) {
            return true;
        }
    }

    return false;
}

bool IsSecondaryGameMode( const std::string &in ) {
    for ( int i = 0; i < SecondaryModesCounts; ++i ) {
        if ( strcmp( SecondaryModes[i], in.c_str() ) == 0 ) {
            return true;
        }
    }

    return false;
}

bool IsMiscGameMode( const std::string &in ) {
    for ( int i = 0; i < MiscModesCount; ++i ) {
        if ( strcmp( MiscModes[i], in.c_str() ) == 0 ) {
            return true;
        }
    }

    return false;
}

bool IsValidGameMode( std::string in, std::string &out ) {
    // 1. Strip all non-letters from the string and convert it to lower-case
    SanitizeString( in );

    // 2. Confirm that it is a multiple of 2
    if ( in.length() == 0 || in.length() % 2 != 0 ) {
        return false;
    }

    // 3. Split the string further into strings of 2 characters
    std::vector<std::string> modes = SplitString( in, 2 );

    // 4. Verify that each game mode is a valid game mode and is compatible with the others
    bool primaryModeSet = false;

    for ( size_t i = 0; i < modes.size(); ++i ) {
        if ( IsPrimaryGameMode( modes[i] ) || IsSecondaryGameMode( modes[i] ) ) {
            if ( IsPrimaryGameMode( modes[i] ) ) {
                if ( primaryModeSet ) {
                    return false;
                }

                primaryModeSet = true;
            }

            if ( ModeCompatibilityMap.count( modes[i] ) > 0 ) {
                std::vector<std::string> badModes = ModeCompatibilityMap[modes[i]];

                for ( size_t j = 0; j < badModes.size(); ++j ) {
                    for ( size_t k = 0; k < modes.size(); ++k ) {
                        if ( badModes[j] == modes[k] ) {
                            return false;
                        }
                    }
                }
            }
        } else if ( !IsMiscGameMode( modes[i] ) ) {
            return false;
        }
    }

    // 5. Assign the output variable with the game mode and return true
    out = in;

    return true;
}

std::string ExtractGameMode( const std::string &gameName ) {
    std::vector<std::string> tokens = Tokenize( gameName );

    std::string gameMode;

    for ( size_t i = 0; i < tokens.size(); ++i ) {
        if ( IsValidGameMode( tokens[i], gameMode ) ) {
            return gameMode;
        }
    }

    return "";
}

int main( int argc, char *argv[] ) {
    InitializeModeCompatibilityMap();

    std::string gameName = "DotA v6.60 -RDEM USA/CA LC";
    std::string gameMode = ExtractGameMode( gameName );

    std::cout << "Name: " << gameName << std::endl;
    std::cout << "Mode: " << gameMode << std::endl;

    return 0;
}

Output:

Name: DotA v6.60 -RDEM USA/CA LC

Mode: rdem


If anyone would like to review this code and let me know what they would change, that would be appreciated.

Thanks.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T20:15:28+00:00Added an answer on May 11, 2026 at 8:15 pm

    Extracting the game type from the host’s game name will be difficult without more rules in place. If you really want to avoid giving the end user more rules you could try the following…

    • ToLower() the entire game name string.
    • Split the game name using a space ‘ ‘ delimiter.
    • Analyse each word, do the following. If anything fails, go to next word.

    • taking [0] and determining if it has an ascii value of 97-122 (making sure it’s a letter). If it’s not within those values, go the next character, and so on until it does (without exceeding the array bounds obviously). This removes any user formatting like a hyphen -apem.
    • strcmp() the next 2 characters with each of primary game types until you reach a match. Otherwise failing and moving onto next word.
    • With the remaining characters, strcmp each next pair of characters with each secondary or misc gametype. If any don’t match fail out to next word, or if there is only 1 character left over fail out to next word

    That should extract the game type, or you can blame the user for using a bad game name.


    Now for the harder part, verifying if the gametypes are compatible with each other. I suggest that you make a struct that holds a data structure of booleans representing each of the secondary game types. A std::map, or a single boolean array that could be accessed using a enum.

    Now you’re going to need a data object to represent each primary game type as well as each secondary game type.

    Then just make an array of every gametype, both primary and secondary. Refer to code sample:

    map<const char*, bool> mapSecondaryCompatibility;
    
    struct tGameType
    {
        char szName[3];
        mapSecondaryCompatibility m_compat;
    }
    

    As you see, there technically isn’t a difference between your primary and secondary game types, they both have the same restriction… may not be compatible with another secondary game type.

    With this I’m sure you can figure out the rest. I hope it helps, I gotta get back to work 🙂

    Oh and I’m a big fan of DotA… keep up the good work!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 113k
  • Answers 113k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer I use SQL Server 2005 in combination with Visual Studio… May 11, 2026 at 10:02 pm
  • Editorial Team
    Editorial Team added an answer scope to the end of the line: Y is REAL… May 11, 2026 at 10:02 pm
  • Editorial Team
    Editorial Team added an answer This really depends on how you want to handle it… May 11, 2026 at 10:02 pm

Related Questions

I am trying to extract a table of values from an excel (2003) spreadsheet
This is a question for a WSS/SharePoint guru. Consider this scenario: I have an
I'm attempting to iterate over the ListViewDataItems in an ASP.Net ListView, and use the
I am working on an automated testing app, and am currently in the process
Here is an extract of HTML from within a standard HTML page: <form name=login_form

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.