hi,
i was writing some sort of a game, it's a console application.
every game needs input,
i thought to implement the input as follows:
the player writes a string, and the game should execute the command.
the way my program handles the command is, it does a calculation on the string to convert it into a unique int, then compare the int against some enumeration values.
up until now every thing is ok, i made the translation function, and it looks like fine.
the problem is, it's really hard to write the enum values by hand, as the int returned is unique for every string, so i thought i could automate the process.
like, create a class that contains static members ,a function that initializes those members with the right value to each command, and i want those members to be public for read access, but private for write access.
maybe some code can illustrate the idea, here's what i have:
you can skip
translate() as the problem isn't in it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
typedef unsigned int CommandID;
// translation constants, took the idea from the MD5 algorithm.
const CommandID TC1 = CommandID(0x0d);
const CommandID TC2 = CommandID(0x01);
const CommandID TC3 = CommandID(0x01);
const CommandID TC4 = CommandID(0x01);
CommandID translate(string& message)
{
CommandID com = NULL; // will hold the result.
unsigned int i = 0;
size_t tempSize = message.size();
for( i=0 ; i<tempSize ; i++) // preliminary process.
{
message[i] = std::tolower(message[i]); // ignore letter case.
if( i > sizeof(com) )
message [ i % sizeof(com) ] ^= message[i]; // reduce message to be of size = sizeof(com).
}
message.erase( sizeof(com) , tempSize ); // erase the un-needed characters.
tempSize *= tempSize; // enlarge tempSize to prepare it to be merged into the translation equation.
com ^= tempSize; //merge tempSize into the equation, this lets the string length affect its translation.
for( i=0 ; i<sizeof(com) ; i++)
{
com ^= ( static_cast<CommandID>( message[i] << 8*i ) ); //merge the message letters, each in its corresponding byte.
}
// merge the translation constants into com.
com *= TC1 ;
com *= TC2 ;
com *= TC3 ;
com *= TC4 ;
return com;
}
void processCommand(string& message)
{
CommandID a = translate(message);
switch(a)
{
case command::EXIT : //this is how i want to use it.
std::exit(0);
break;
default:
std::cerr<<"Unknown command recieved ("<<a<<"), ignoring.\n";
return;
break;
}
}
class command abstract
{
public:
static CommandID EXIT ;
// static methods.
static void Initialize();
command(void)
{
}
~command(void)
{
}
};
CommandID command::EXIT;
void command::Initialize()
{
command::EXIT = translate( std::string ("exit") ); // this is the automation process i want.
}
|
in the code above, i want
command::EXIT to be accessible publicly for read operations, but private for write operations.
before you ask, i used typdef to provide an easy platform for possible future upgrades on the project.
i read a previous thread to do so, it demonstrated it using const references, but looks like this method can be exhausting in my project because i might define lots of commands.
on the other hand, it needs an object to be created, i want the class abstract (the class represents an enumeration).
if there's another approach to do so, it'd be better.
thanks in advance.