I'm currently learning c++ and trying to make a vending machine! I know my code is really bad and I am sorry about that.
I am trying to implement a bank and have the user take a loan from it, the only problem is that the bank is unable to add money to the user. Here's my code.
void Bank::askLoan() {
//ColaMachine object
ColaMachine cola;
bool loanGranted = false;
cout << string(100, '\n');
cout << "You do not have enough money!\n\n";
cout << "Would you like to take a loan?\n\n(1)-Yes\n(2)-No\n\n\n";
int choice;
cin >> choice;
switch (choice) {
case 1:
//Print the bank menu!
printBank();
while (loanGranted != true) {
cout << "Enter the amount to lend: $";
cin >> _loanValue;
//Test if _loanValue is less than or = to bankmoney, so they would scam the bank.
if (_loanValue <= _bankMoney) {
//Supposed to add money to the user.
cola.addMoney(_loanValue);
break;
}
else {
cout << "You entered too much! Try again..." << endl;
}
}
break;
case 2:
//User does not want to take a loan! Quit the game!
//Not implemented, yet.
break;
default:
cout << "Bad input! Please retry..." << endl;
}
}
If the amount entered was within the correct range it calls the addMoney() Func from ColaMachine class.
void ColaMachine::addMoney(int money) {
//This part doesnt seem to modify the actual value
//Whenever It goes back to the main game loop it doesnt change.
_money += money;
}
From what I understand += is the same as _money = _money + money;
What am I doing wrong here?
Full source on GitHub-
https://github.com/Rohukas/-LearningCPP
The problem is that you are creating new cola object inside askLoan() method which gets destroyed at the end of the function, so call to addMoney() method modifies state of that temporary cola object. One option is to provide cola object by pointer to the askLoan() method.
For example, in ColaMachine::chooseDrink() you would call bo.askLoan(this). this is pointer to the object from where you call bo.askLoan().
You would need to modify your askLoan() signature:
void askLoan(ColaMachine * cola) and remove ColaMachine cola; from askLoan() itself.
The problem is here
void Bank::askLoan() {
//ColaMachine object
ColaMachine cola;
bool loanGranted = false;
...
everytime you call Bank::askLoad you create a new ColaMachine, that's what the code above says. But the problem is that any changes to that ColaMachine are thrown away when you exit Bank::askLoan and the ColaMachine is destroyed. That's why the changes you make to the ColaMachine don't stick.
Instead you want to use same ColaMachine each time that you call Bank::askLoad. I can't say the best way to do that without seeing the rest of your code, but one way would be to pass ColaMachine as a reference parameter to Bank::askLoad
void Bank::askLoan(ColaMachine& cola) {
bool loanGranted = false;
...
Another way would be to make ColaMachine a class member variable of Bank
class Bank
{
...
void askLoan();
private:
ColaMachine cola;
};
Which is better? No idea. I think you need to read up on class design, and how the objects in your program should relate to each other. That seems to be the bit you're not getting at the moment.
=========================================================================
Having looked at your full code I can see that you make the same mistake in more than one place. In your main function you declare a Bank and a ColaMachine.
//ColaMachine Object
ColaMachine cola;
//Bank Object
Bank bank;
Those should be the only two Bank and ColaMachine objects you create, so this is wrong
void ColaMachine::chooseDrink() {
Bank bo;
...
bo.askLoan();
That Bank bo is a completely different bank from the one you declared in main. And like the previous code this Bank bo gets created and destroyed each time you call ColaMachine::chooseDrink.
I think that what you should be doing is passing the ColaMachine and Bank variables declared in main as reference parameters to the other parts of you code that need to use them. So (for instance)
void ColaMachine::chooseDrink(Bank& bank) {
...
bank.askLoan();
You have quite a lot of rewriting of this code to do.
Related
Good Morning.
Me and my team are facing a problem with our c++ assignment.
In main we are defining two instances of a class called Team, "Team famous, Team fighters". Inside main we are calling a function called "team details"; inside that function we are trying to access public methods of the instances we just created(famous.getName). The following message appears:
error: request for member 'getName' in 'famous', which is of non-class type 'teamdetails() ::team_t'
The message concerns the calls made inside that switch loop you can see in the code below. We can't find out where the problem comes from.
*Is it a problem that 'famous.getName' is used in a function in which object 'famous' was not declered in? *
NOTE: function 'teamdetails()' is called by function 'menu()', which is called by main.
Thank you for your help!
#include "Player.h"
#include "Team.h"
using namespace std;
void teamdetails();
int main(){
Team famous;
Team fighters;
cout<<"Welcome to the \"Survivor Experience of a lifetime\" !!!"<<endl;
menu();
return 0;)
void teamdetails(){
cout << " Which team are you interested in ? <famous/fighters>\t";
enum team_t {famous = 0, fighters = 1};
team_t team_as_enum;
// cin >> team_as_enum; // -> does not work. Below I am trying
//another alternative.
string team;
cin >>team;
for(;;)
if((team == "famous") || (team == "fighters"))
break;
if (team == "famous")
team_as_enum = famous;
else if(team == "fighters")
team_as_enum = fighters;
else
cout<<"sth went wrong with your input";
switch (team_as_enum){
case famous:
cout<<"The name is"<< famous.getName() <<endl;
cout<<"The number of players is "<<famous.getPlayers()<<endl;
cout<<"Portions are "<<famous.getPortions()<<endl;
cout<<"Victory : "<<famous.getVictories()<<endl;
break;
case fighters:
cout<<"The name is"<<fighters.getName()<<endl;
cout<<"The number of players is "<<fighters.getPlayers()<<endl;
cout<<"Portions are "<<fighters.getPortions()<<endl;
cout<<"Victory : "<<fighters.getVictories()<<endl;
break;
default:
cout<<"Ooop Entry not correct . Next time enter one of the following
team's name <famous/fighters>"<<endl;
}
}
You reuse famous variable name inside of your teamdetails function by declaring enum team_t {famous = 0, fighters = 1};. Chose a different name. And variable famous of type Team is not visible inside of that function at all as it is declared inside of main function scope, you need to pass it to teamdetails as argument.
I think I'm just confused on the wording to this project, but I'm posting here to make sure I have the basics on classes correct (like I said, we just started learning them).
The beginning of the project prompt is as follows:
Declare and define a class called Odometer. This class will have two private variables, one for the miles driven and the other for the gallons of gas pumped into the car.
The member functions should include:
A constructor that takes initial values for both of the private variables.
A default constructor that sets both values to zero.
Along with more member functions that aren't important for my problem. I understand the default constructor fully, but the other is the one I'm having troubles with. If he (my professor) wants us to gather initial variables, then why would it need any parameters at all? I guess I could pass an empty string into it as a parameter, but I feel like there's something I'm missing here...
To expand on the point of this project, in case it's needed, we are creating a program that allows the user to continually enter (on a menu screen) either miles driven or gallons put into their tank. The program will then find the mpg, when the user requests it. Very simple.
Here's part of the program, which should be enough for someone to help me with this. The second/non-default constructor seems like it would work, except obviously I need some type of parameter. Any suggestions or help is greatly appreciated.
#include <iostream>
using namespace std;
class Odometer{
public:
Odometer(); // sets values to 0
Odometer(WHAT GOES HERE); // gathers initial values
void get_miles();
void get_gallons();
void add_in_trip_miles();
void add_gas();
private:
double milesDriven; // represents the miles the car has driven
double gallonsGas; // represents the number of gallons pumped into car
};
int main() {
Odometer userInfo; // creates object for the user-inputted values
bool quit = false; // true when user wants to quit
int userChoice; // for navigating the menu screen
while(!quit){
cout << "To view total miles, enter 1. To view total gallons, enter 2.\nTo record more miles driven, enter 3. To record gallons pumped into the tank, enter 4.\n To view the average MPG, enter 5. To reset the odometer, enter 6.\n To quit the program, enter 7." << endl;
cin >> userChoice;
if(userChoice == 1) userInfo.get_miles(); // TODO: switch/case statement instead?
if(userChoice == 2) userInfo.get_gallons();
if(userChoice == 3) userInfo.add_in_trip_miles(); // TODO: "function which increases the miles by the amount sent in its parameter
}
cout << "Have a nice day!" <<endl;
return 0;
}
Odometer::Odometer(){ // sets values to 0 (default)
milesDriven = 0;
gallonsGas = 0;
}
Odometer::Odometer(WHAT GOES HERE?){ // gathers initial values
cout << "Please enter an initial value for miles driven." << endl;
cin >> milesDriven;
cout << "Please enter an initial value for how many gallons were put into the car." << endl;
cin >> gallonsGas;
}
Your teacher is asking you to implement the second constructor with parameters so user will be able to initialize the object with the state he wants. I would implement it like this:
Odometer(double milesDriven_, double gallonsGas_) :
milesDriven(milesDriven_),
gallonsGas(gallonsGas_)
{}
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.
I am willing to write a code of a tennis score keeper in C++ that keeps track of the score, but there are 2 problems that occur when I run the program:
I can't quit the loop with while(cin!="q")
The functions wouldn't initialize the variables
#include<iostream>
#include<string>
using namespace std;
int points1=0, points2=0;
int set1=0, set2=0;
int games1=0, games2=0;
string in="";
void score(int point,int set,int game);
int main()
{
do
{
cout<<"POINTS: "<<points1<<":"<<points2<<endl<<"SETS: "<<set1<<":"<<set2<<endl<<"GAMES: "<<games1<<":"<<games2<<endl;
cout<<"Who scored - player 1 or player 2? (p1/p2) : ";
cin>>in;
if(in=="p1")
{
void score(int points1,int set1,int games1);
}
else if(in=="p2")
{
void score(int points2,int set2,int games2);
}
else {cout<<endl<<"Error!"<<endl<<endl;}
}
while(cin!="q");
system("pause");
return 0;
}
void score(int& point,int& set,int& game){
if(set<5)
{
switch(point)
{
case '30':
point=point+10;
case '40':
set++;
point=0;
default:
point=point+15;
}
}
else game++;
}
while(cin!="q");
should be
while(in!="q");
In your function, your switch is on an integer value, so your cases should use an integer value as well:
case '30':
should be
case 30:
The others as well.
This is a function prototype:
void score(int points1,int set1,int games1);
This is a function call:
score(points1,set1,games1);
Make sure you have function calls where you want to execute the function. You have a lot of prototypes where they don't belong.
Some Tennis tips: you need to be two points ahead to win a set, two sets ahead to win a match. You may want to take that into account in your functions. Points and sets of a single player will not be enough to decide who won a set or game.
Edit:
In addition, if you want variables you pass to a function to change outside of this function, you need to pass them by reference.
void score(int& points1, int& set1, int& games1);
Note the ampersands.
Passing parameters to a function will make a [b]copy[/b] of the parameters. This is refered to as pass-by-value, because the value is passed. You can pass-by-reference, which means you don't create a copy but instead pass the location of the actual variable. Changes to it will then be reflected back to your main program.
You want an infinite while loop with a break, also get rid of type defs in function calls -- something like:
while (true) {
cin >> in;
if (in == "p1") {
score(points1, set1, games1);
}
else if (in == "p2") {
score(points2, set2, games2);
}
else if (in == "q") {
break;
} else {
cout << endl << "Error!" << endl << endl;
}
}
The following line is wrong: while(cin!="q");
Instead of cin you need to use in!="q"
The second issue is because you're calling the function in the wrong way.
When you call a function, you just write its name and pass the specified arguments, you don't need to write the function return type when calling it. Also you don't need to specify the types of the arguments you're passing. Your function call should be :
score(points2, set2, games2)
And finally you're switching on an integer, so your cases should check for integers.
I have a function of a "Table" class that should add a player to the table. I decided that if the seat is taken, the function should try and go through all the seats and add the player to the next available seat. How do I implement this in my addPlayer function?
int Table::addPlayer(Player player, int position)
{
deque<Player>::iterator it;
if(playerList[position] != "(empty seat)") {
//What goes here?
}
playerList.put(player,it);
cout >> "Player " >> player.toString >> " sits at position " >> position >> endl;
}
Instead of using position, use the iterator to point to that position, using something like this:
it = playerList.begin() + position;
Then, check if the seat is taken using the iterator.
If the seat is taken, increment the iterator, but check for end, like this:
while (no empty seat found yet)
{
++it;
if (it==playerList.end()) it = playerList.begin();
}
Of course, if all seats have been taken, this will result in an endless loop.
Therefore, also keep the iterator you started from (let's call this itStart), and add a check on it:
while (no empty seat found yet)
{
++it;
if (it==playerList.end()) it = playerList.begin();
if (it==itStart) break; // We tried all seats
}
Maybe you should also take a look at the circular buffer from boost.
http://www.boost.org/doc/libs/1_43_0/libs/circular_buffer/doc/circular_buffer.html
I think it will do what you want, and is quite easy to use.