I'm getting back into programming for the first time in over a decade and I'm a little rusty in C++.
I decided to make a zork type game that has a text based user prompt for all player actions but I wanted to parse the string input (i'm using getline(cin,MyString)) for keywords and interprete the desire of the user. I'm looking to have some sort of alias so that if user types any of the following: yes, y, Yes, Yesir, Yessem, Yep, Uh-Huh, etc that it will interprete it as "yes" and not have a giant case statement. I'm going to have this for a number of keywords and I want to easily add more.
I'm looking to have the game compare the keyword to a list of keywords in a text file and determine what the base keyword to use so I can determine an action from their input.
Are there any established libraries or practices that I could use for this functionality?
Currently looking at something like this:
Get user input
Check user input for keywords
Put each keyword into a class
assign class variable for the alias aka Keyword.type()="yes" or Keyword.type()="north"
Perform action based on keywords
Any help would be greatly appreciated.
Let's say you have an action class for all possible cases.
class Action
{
public:
virtual void doAction(YourGame*)=0;
};
class YesAction : public Action
{
public:
void doAction(YourGame* game) {/* your yes logic */}
};
class NoAction : public Action
{
public:
void doAction(YourGame* game) {/* your no logic */}
};
Then, in your YourGame, have a std::map<std::string, Action*> actionMap.
Action* yesAction = new YesAction();
actionMap["yes"] = yesAction;
actionMap["yep"] = yesAction;
actionMap["yeah"] = yesAction;
When you get user input, use actionMap.find(userInput) to get the possible action, and if it's not actionMap.end() (which means no such action), call doAction of the Action instance you get.
You'd also want to have functions such as isValid that checks whether the given action is valid for the current state in YourGame. doAction may call YourGame functions, or even change states.
Have you looked at Ternary search tree?
An implementation is here.
Related
I'm trying to create a performance monitor of sorts to run on a Particle board (STM32 based). I'm used to programming in c so the OOP approach is a bit new but I think it would fit well here.
For the purpose of this question let's assume I have two types of monitors:
Frequency. The application can call a "tick" method of the monitor to calculate the time since it last ran and store it.
Period- call a "start" and "stop" method of the monitor to calculate how long a process takes to run and store it.
What I would like to do is to create instances of these monitors throughout my application and be able to report on the stats of all monitors of all types from the main module.
I've read about the singleton design pattern which seems like it might be what I need but I'm not sure and I'm also concerned about thread safety with that.
I'm thinking I will create a "StatMonitor" class and a derived class "FrequencyMonitor" and "PeriodMonitor". Monitor would be a singleton and everywhere I wanted to create a new monitor I would request an instance of "Monitor" and use that like so:
freqMonitor * task1FreqMonitor = StatMonitor::GetInstance()->Add_Freq_Monitor("Task1");
The StatMonitor would track all monitors I've added and when I wanted to print the stats I could just call the printAll method which would iterate it's array of monitors and request their results like so:
StatMonitor::GetInstance()->PrintAllStats();
Am I going down the right path?
Your path sounds good, except that FrequencyMonitor and PeriodMonitor should not derive from the class that "manages" all these monitors (let's call it MonitorPrinter).
MonitorPrinter should be a singleton and could look like this:
class MonitorPrinter
{
public:
static MonitorPrinter& getInstance()
{
static MonitorPrinter monitorPrinter;
return monitorPrinter;
}
void printAllStats()
{
for (const auto& [_, frequencyMonitor] : _frequencyMonitors)
frequencyMonitor.print();
for (const auto& [_, periodMonitor] : _periodMonitors)
periodMonitor.print();
}
FrequencyMonitor& getFrequencyMonitor(std::string name)
{ return _frequencyMonitors[name]; }
PeriodMonitor& getPeriodMonitor(std::string name)
{ return _periodMonitors[name]; }
private:
MonitorPrinter() = default;
std::map<std::string, FrequencyMonitor> _frequencyMonitors;
std::map<std::string, PeriodMonitor> _periodMonitors;
};
Demo
(The const auto& [_, frequencyMonitor] is a structured binding).
FrequencyMonitor and PeriodMonitor should not have anything to do with singletons, and from your description, they need not be part of a class hierarchy either (as they have different interfaces). If you want, you can prevent users (other than the MonitorPrinter) from instantiating these classes using other techniques, but I won't elaborate on that here.
In short, there is no need to use OOP here. Use a singleton to provide (and keep track of) the monitors, and implement the monitors to your liking. Be wary of thread safety if this is relevant (the above is not thread-safe!).
My question is relatively simple: how would I go about implementing a UML sequence diagram in C++ code? I was reading up on sequence diagrams the other day, and I found this example for a program for a student enrolling in a seminar.
How would I go about turning this diagram into a program? For the sake of this question, lets focus on one class, say the EnrollInSeminar controller. How would I go about implementing this?
I imagine that it might be something like this:
class EnrollInSeminar
{
public:
void Activate();
};
void EnrollInSeminar::Activate()
{
SecurityLogon logonUI{};
Student theStudent = logonUI.getStudent();
SeminarSelector seminarSelectorUI{};
Seminar seminar = seminarSelectorUI.getSeminar();
if (!seminar.isEligible(theStudent))
return;
theStudent.getSchedule().determineFit(seminar);
Fee fee = StudentFees.calculateFees(seminar, theStudent);
FeeDisplay feeUI{fee};
if (!feeUI.getVerification())
return;
seminar.enrollStudent(theStudent);
}
Is this the correct way to implement the EnrollInSeminar class? If not, how should I do it?
Actually a SD does not tell anything about the methods being used in the messages passed from one object to another except the name, the parameters and - as the name says - the sequence. So the only thing you can draw from "just the SD" are methods and their parameters.
You will need additional information from a use case to know what the methods are all about. Without you simply can not "implement a SD".
I'm new to the site (and to c++) so please forgive me if this is a basic question - I've googled and looked through this site without success so far, so any help anyone can provide would be hugely appreciated.
I'd like to add some functionality to an app, that allows a user to fully define the structure and contents of an object. For example, user would be presented with a configuration screen that allows them to list each property of the object - given my limited knowledge I've assumed this might be achieved by using a class:
Class Name: CustomClassName
Class Property 1: property1Name property1DataType property1DefaultValue
...
Class Property n: propertynName propertynDataType propertynDefaultValue
The user would then be able to hit a button to save their custom configuration, and the program could then reference that configuration as a Class:
class CustomClassName
{
property1DataType property1Name = property1DefaultValue;
...
propertynDataType propertynName = propertynDefaultValue;
}
I'm not even sure this is possible using Classes, so if there's another mechanism that facilitates this I'm open to suggestions!
You can't create classes in runtime, but since dynamic typing is in essence a subset of static typing, you can fake it.
Start with the Property type1:
using Property = variant<int, float, string>;
A simple "dynamic" class could look like this:
class DynamicClass {
std::map<std::string, Property> properties;
public:
Property const& operator[](std::string const&) const
Property operator[](std::string const&);
};
Use:
DynamicClass d;
d["myInt"] = 5;
1 Example implementation. Internals of variant should be tailored for your specific purpose. If you need an open variant, where you don't know all of the possible types beforehand, this gets more complicated, calling for something like any.
I need to put scriptable NPC in my currect game project.
The project itself is developed in C++ language.
I will using Luabind to bind lua and c++.
I need to call NPC function when certain NPC clicked or timer to do something is activated.
Currently I stuck between 2 NPC script design.
Using a kind of npcname_action to differentiate every NPC.
This is kind of troublesome to give name to every different NPC.
I'm still thinking how to implement this in my project.
Example:
HotelBellboy12_Click() { .. }
HotelBellboy12_TimerAction() { .. }
Using name of function.
Every npc have it own lua file.
I'm thinking to load script into memory and when needed will be loaded into luaState using luaL_loadbuffer
Example:
OnClick() { .. }
OnTimerAction() { .. }
Which one is better and why?
You could use another design.
Take advantage of the fact that table keys and values can be any type.
Let's say npc is a table containing all NPC's. Its keys are NPC' names and its values are another table. This other table keys are the actions, and its values are the function for this actions.
So, if you want bob to jump when clicked on, and alice to cry after a timer, simply do :
npc.bob.click = function () jump() end
npc.alice.timer = function () cry() end
I've done something like this before and I used something similar to your #2 option. When the map loads I load a configuration Lua file containing all the NPC data; among that is the name of the script file used for the NPC.
When I need to load the NPC in the game I compile the Lua file. NPC's can use a 'model' NPC type to dictate most of the common behavior (for example a Merchant type or a Commoner type) which is specified in the NPC configuration. These model types provide all the basic functionality such as providing a trade window when clicked. The specific NPC's use functions like OnClick() to override their model and provide custom handlers.
This worked pretty well for me, although it ends up being a large volume of scripts if your game gets large.
I am currently working on a project where a team of us are designing a game, all of us are proficient in ruby and some (but not all) of us are proficient in c++.
Initially we made the backend in ruby but we ported it to c++ for more speed. The c++ port of the backend has exactly the same features and algorithms as the original ruby code.
However we still have a bunch of code in ruby that does useful things but we would rather not have to port it all, so we want to keep using the ruby code and get data from the c++ classes. Is this unrealistic?
Our first thought was that we could save some of the data structures in something like XML or redis and call that, but some of the developers don't like that idea.
We don't need any particularly complex data structures to be passed between the different parts of the code, just tuples, strings and ints.
Is there any way of integrating the ruby code so that it can call the c++ stuff natively?
Will we need to embed code? Will we have to make a ruby extension? If so are there any good resources/tutorials you could suggest?
For example say we have some code like this in the c++ backend:
class The_game{
private:
bool printinfo; //print the player diagnostic info at the beginning if true
int numplayers;
std::vector<Player*> players;
string current_action;
int action_is_on; // the index of the player in the players array that the action is now on
//more code here
public:
Table(std::vector<Player *> in_players, std::vector<Statistics *> player_stats ,const int in_numplayers);
~Table();
void play_game();
History actions_history;
};
class History{
private:
int action_sequence_number;
std::vector<Action*> recent_actions;
public:
void print_history();
void add_action(Action* the_action_to_be_added);
int get_action_sequence_number(){ return action_sequence_number;}
bool history_actions_are_equal();
int last_action_size(int street,int number_of_actions_ago);
History();
~History();
};
Is there any way to natively call something in the actions_history via The_game object in ruby? (The objects in the original ruby code all had the same names and functionality)
By this I mean:
class MyRubyClass
def method1(arg1)
puts arg1
self.f() # ... but still available
puts cpp_method.the_current_game.actions_history.get_action_sequence_number()
end
# Constructor:
def initialize(arg)
puts "In constructor with arg #{arg}"
#get the c++ object here and call it cpp_method
end
end
Is this possible? Any advice or suggestions are appreciated.
You could use the Ruby C API to create an extension that interfaces with the C++ class or SWIG to create a wrapper the C++ class.
For creating ruby extensions you also might want to have a look at:
Rice
RubyInline