I need to set a variable depending on another variable passed to a mixin.
F.e.
#make-grid(#columns){
when(#columns = 10){
#a: 1;
}
}
This is giving me a compile error "unrecognised input"
Related
First, if return 0 statements are removed, my program cannot run exactly. So I don't understand what does this means.
Secondly, one more problem is that it doesn't print the string "Accept 1-4 key only." at the end. If I press others key(not 1-4), the program stop and exit.
When I change if- else if statement to switch. It can run.
I am not able to figure what is going wrong in the program?
char key;
key = getchar();
fflush(stdin);//fpurge(stdin);
//1. play game
if (key == '1') {
if (Money >= 0.25) {
Money = Money - 0.25 + PlayGame();
}else {
printf("\nYou dont have enough money to play\n");
SaveGame (Money, "d:/SaveGame.txt");
return 0;
}
//2. Save game
}else if (key == '2') {
SaveGame (Money, "d:/SaveGame.txt");
//3. Cash out
}else if (key == '3') {
printf("Thank you for playing, you end with %.2f", Money);
remove("d:/SaveGame.txt");
return 0;
//4. Quit
}else if (key = '4') {
remove("d:/SaveGame.txt");
return 0;
//5. Wrong key
}else {
printf("Accept 1-4 key only.");
}
}while(1);
return 0;
}
return 0 is a programming convention that is used during program exit to indicate that the program have executed without errors. On the other hand, a > 0 return code indicates an error is encountered.
On your question, if return 0 is removed, program cannot run. It just means that the function that you are using is expecting an integer to be returned like below.
int main() {
....
}
If you are willing, you can also consider using switch/case statements instead of if/else. Note also that there is a logic error on your last else if. Should be key == '4'.
Assuming you have used int main() to run the code. int main() is a function in c/c++ with return type int, hence, you are supposed to use a return statement to run the code without errors.
Now, return 0 is a programming convention which indicates that program has executed without errors.
else if (key = '4') indicates assignment operator, not comparison operator which is ==.
If this code is inside the main function, there are three portable return values: 0, EXIT_SUCCESS, and EXIT_FAILURE. The latter two are constants that are defined in the header <cstdlib>. Returning 0 is equivalent to returning EXIT_SUCCESS. The values of those two constants are determined by the target system, that is, they will be values that the OS treats as success and failure, respectively.
In short: return 0; tells the system that the program succeeded. So does return EXIT_SUCCESS;. return EXIT_FAILURE; tells the system that the program failed.
There's one quirk here, though: in C++ (but not in C) you can leave out the final return statement from main:
int main() {
}
when execution reaches the end of main, it acts as if there was a return 0; just before the closing }. Personally, I've never liked that; I always write return 0; at the end of main. Your mileage may vary.
I'm trying to make a program that outputs the most used character in a file.
Why does the compiler give me an error when I try this:
for (char i = 97 ; i <=122 ; i ++) {
switch (x) {
case i :
break;
}
}
This code uses a switch to get the most used characters. The error is :
'i' cannot appear in a constant-expression
case labels need to be compile time constants, and you are trying to use variable i, so you get the rather descriptive error message.
If you need to test against variables, the direct replacement is if-else if-...-else ladder. Though your simple case has no "else" part, Additionally, break breaks out of the switch, so you can't use it to break out of a loop then (direct replacement would be to use goto but it's far better to rethink your logic in almost all cases).
So write your code like this:
for (char i = 97 ; i <=122 ; i ++) {
if (x == i) {
break; // did you mean to break the loop?
}
}
Recently I've been working on an inventory system for a text-based game that uses a global array for the inventory system and a corresponding function to read true or false in said array. The problem I've run into is this, the function I'm using to modify the array
void playerGet(bool items[], int itemNumber) //this function takes an assigned argument of the array indices variable, and changes that array indices from true, to false.
{
items[itemNumber] = true;
}
only modifies the array within the scope of the function its housed in. The array is defined in a .cpp file like this:
void inventoryArray(bool items[]) //This function establishes all the items in the game, the true false statement expresses whether or not the item is in the player's inventory.
{
items[WEAPON_RELIC_RIFLE] = false;
items[WEAPON_SCALPEL] = false;
items[MISC_ACTION_FIGURE] = false;
items[MISC_FIRE_EXTINGUISHER] = false;
items[MISC_LIFE_RAFT] = false;
}
and is then declared in a .h file like this:
void inventoryArray(bool items[]);
the enums used in the array are defined in a header file like this:
enum equipment //This declares a list of enums for each item in the game, consumables, not included.
{
WEAPON_RELIC_RIFLE, // = 0
WEAPON_SCALPEL, // = 1
MISC_ACTION_FIGURE, // = 2
MISC_FIRE_EXTINGUISHER, // = 3
MISC_LIFE_RAFT, // = 4
MAX_EQUIPMENT
};
the function that reads the inventory array is this:
void twoScavengerCombat(bool items[])
{
for (int item = 0; item < MAX_EQUIPMENT; ++item)
{
if (items[item] == true) //if true proceed
{
switch (item)
{
case 0: //if array indices identifier = 0, print relic rifle
cout << "1: Use the Relic Rifle\n";
break;
case 1:
cout << "2: Use the Scalpel\n";
break;
case 2:
break;
case 3:
cout << "3: Use the Fire Extingusher\n";
break;
case 4:
cout << "4: Use the Life Raft\n";
break;
default:
cout << "Error";
break;
}
}
else
cout << "Option Unavailible\n"; //if false print Option Unavailible
}
compiled, with the array and enums headers declared the main file would look like this:
int toolSearch()
{
bool items[MAX_EQUIPMENT];
inventoryArray(items);
playerGet(items, 0);
}
void twoScavengerCombat(bool items[])\\ declared in this file, but since its just above here i left it as a forward declaration to save space
int main()
{
toolSearch();
twoScavengerCombat(items);
return 0;
}
Ideally this would produce the result: Use Relic Rifle
Option Unavailable
Option Unavailable
Option Unavailable
Option Unavailable
but instead it produces 5 Option Unavailable's. What am I missing?
You would want
//bunch of #include<> directives
bool items[MAX_EQUIPMENT];
int toolSearch()
{
inventoryArray();
playerGet( 0);
}
void twoScavengerCombat()
...
// other functions here
int main()
{
toolSearch();
twoScavengerCombat();
return 0;
}
Note that bool items[MAX_EQUIPMENT]; is not defined in a function. It is off on it's own at the top of the file in plain view of anything defined below it. This is what it means to be global. Anyone and everyone can access it, if they know where it is or you tell them where it is with an extern statement. It is created when the program starts (even before main and that can cause some really fun debugging if the initialization logic of the variable is faulty) and dies only when the program does.
Lightness Races in Orbit delves a bit deeper here, but is more concerned with making a global variable extend past a single file
There is no need to pass items into any function because everyone can see items The downside is there is one and only one items so if you have multiple players each with different item lists, you're going to have problems.
You might want to look into std::vector (resizable array) and std::map (which will allow you to look items up by name items["sword"].attackFoe(foe);) and std::set (which makes it really easy to see what a player has (if (items.find("Vorpal Hand Grenade") != items.end()) BlowStuffUp();) rather than having to search through each item every time.
In the following code:
int i = 0;
switch(i)
{
case 0:
cout << "In 0" << endl;
i = 1;
break;
case 1:
cout << "In 1" << endl;
break;
}
What will happen? Will it invoke undefined behavior?
No undefined behavior. But the value of i is only tested when the code reaches switch (i). So case 1: will be skipped (by the break; statement).
The switch keyword does not mean "run code whenever the value of i is 0 / 1". It means, check what i is RIGHT NOW and run code based on that. It doesn't care what happens to i in the future.
In fact, it's sometimes useful to do:
for( step = 0; !cancelled; ++step ) {
switch (step)
{
case 0:
//start processing;
break;
case 1:
// more processing;
break;
case 19:
// all done
return;
}
}
And changing the control variable inside a case block is extremely common when building a finite state machine (although not required, because you could set next_state inside the case, and do the assignment state = next_state afterward).
You break out of this switch statement after you set it to 1 which is defined behavior so it will never enter case 1.
There's no issue here. The expression in the switch condition is evaluated when it is reached. It doesn't have to be a variable and if it is the variable can be subsequently modified without any effect on the behaviour of the switch statement.
Your output would be :
"In 0"
even if you assign the value i = 1 it wont be reflected because switch does not operate in iteration, it is one time selection as break would make it go out of the switch statement.
I find myself writing code that looks like this a lot:
set<int> affected_items;
while (string code = GetKeyCodeFromSomewhere())
{
if (code == "some constant" || code == "some other constant") {
affected_items.insert(some_constant_id);
} else if (code == "yet another constant" || code == "the constant I didn't mention yet") {
affected_items.insert(some_other_constant_id);
} // else if etc...
}
for (set<int>::iterator it = affected_items.begin(); it != affected_items.end(); it++)
{
switch(*it)
{
case some_constant_id:
RunSomeFunction(with, these, params);
break;
case some_other_constant_id:
RunSomeOtherFunction(with, these, other, params);
break;
// etc...
}
}
The reason I end up writing this code is that I need to only run the functions in the second loop once even if I've received multiple key codes that might cause them to run.
This just doesn't seem like the best way to do it. Is there a neater way?
One approach is to maintain a map from strings to booleans. The main logic can start with something like:
if(done[code])
continue;
done[code] = true;
Then you can perform the appropriate action as soon as you identify the code.
Another approach is to store something executable (object, function pointer, whatever) into a sort of "to do list." For example:
while (string code = GetKeyCodeFromSomewhere())
{
todo[code] = codefor[code];
}
Initialize codefor to contain the appropriate function pointer, or object subclassed from a common base class, for each code value. If the same code shows up more than once, the appropriate entry in todo will just get overwritten with the same value that it already had. At the end, iterate over todo and run all of its members.
Since you don't seem to care about the actual values in the set you could replace it with setting bits in an int. You can also replace the linear time search logic with log time search logic. Here's the final code:
// Ahead of time you build a static map from your strings to bit values.
std::map< std::string, int > codesToValues;
codesToValues[ "some constant" ] = 1;
codesToValues[ "some other constant" ] = 1;
codesToValues[ "yet another constant" ] = 2;
codesToValues[ "the constant I didn't mention yet" ] = 2;
// When you want to do your work
int affected_items = 0;
while (string code = GetKeyCodeFromSomewhere())
affected_items |= codesToValues[ code ];
if( affected_items & 1 )
RunSomeFunction(with, these, params);
if( affected_items & 2 )
RunSomeOtherFunction(with, these, other, params);
// etc...
Its certainly not neater, but you could maintain a set of flags that say whether you've called that specific function or not. That way you avoid having to save things off in a set, you just have the flags.
Since there is (presumably from the way it is written), a fixed at compile time number of different if/else blocks, you can do this pretty easily with a bitset.
Obviously, it will depend on the specific circumstances, but it might be better to have the functions that you call keep track of whether they've already been run and exit early if required.