c++ vectors/classes/structs to shorted verbose code - c++

I recently began reading my Sam's teach yourself C++ in 24 hours (5th Edition) book and came across Hour 3's first exercise where the question was something along the lines of create const ints for the values of touchdown extra point field goal and safety. I did this for a college game, where I printed the score for each team at the end of each quarter and then added them up for the final score. See code below:
#include <iostream>
int displayScore1(int oregon1, int oregonState1) {
if (oregon1 >= oregonState1) {
std::cout << " Oregon: " << oregon1 << " Oregon State: " << oregonState1 << "\n";
} else {
std::cout << " Oregon State: " << oregonState1 << " Oregon: " << oregon1 << "\n";
}
return 0;
}
int displayScore2(int oregon2, int oregonState2) {
if (oregon2 >= oregonState2) {
std::cout << " Oregon: " << oregon2 << " Oregon State: " << oregonState2 << "\n";
} else {
std::cout << " Oregon State: " << oregonState2 << " Oregon: " << oregon2 << "\n";
}
return 0;
}
int displayScore3(int oregon3, int oregonState3) {
if (oregon3 >= oregonState3) {
std::cout << " Oregon: " << oregon3 << " Oregon State: " << oregonState3 << "\n";
} else {
std::cout << " Oregon State: " << oregonState3 << " Oregon: " << oregon3 << "\n";
}
return 0;
}
int displayScore4(int oregon4, int oregonState4) {
if (oregon4 >= oregonState4) {
std::cout << " Oregon: " << oregon4 << " Oregon State: " << oregonState4 << "\n";
} else {
std::cout << " Oregon State: " << oregonState4 << " Oregon: " << oregon4 << "\n";
}
return 0;
}
int finalScore(int oregonFinal, int oregonStateFinal) {
if (oregonFinal > oregonStateFinal) {
std::cout << " Final Score: " << " Oregon " << oregonFinal << " Oregon State " << oregonStateFinal << "\n";
} else {
std::cout << " Final Score: " << " Oregon State " << oregonStateFinal << " Oregon " << oregonFinal << "\n";
}
return 0;
}
int main () {
const int touchdown = 6;
const int fieldGoal = 3;
const int extraPoint = 1;
const int safety = 2;
int oregon1 = 0;
int oregon2 = 0;
int oregon3 = 0;
int oregon4 = 0;
int oregonState1 = 0;
int oregonState2 = 0;
int oregonState3 = 0;
int oregonState4 = 0;
int oregonFinal = 0;
int oregonStateFinal = 0;
oregon1 = touchdown + extraPoint;
oregonState1 = touchdown + extraPoint;
displayScore1(oregon1, oregonState1);
oregon2 = touchdown + extraPoint;
oregonState2 = touchdown + extraPoint;
displayScore2(oregon2, oregonState2);
oregon3 = touchdown + extraPoint + fieldGoal;
oregonState3 = touchdown + extraPoint;
displayScore3(oregon3, oregonState3);
oregon4 = 0;
oregonState4 = touchdown + extraPoint + fieldGoal + fieldGoal;
displayScore4(oregon4, oregonState4);
oregonFinal = oregon1 + oregon2 + oregon3 + oregon4;
oregonStateFinal = oregonState1 + oregonState2 + oregonState3 + oregonState4;
finalScore(oregonFinal, oregonStateFinal);
return 0;
}
I understand that this is the long way to do it and I got the output to be what I wanted. However, being new to C++, I'm not entirely sure how to write something more flexible for re-use. My question is, is there a more efficient way to do this? Or is there a way to accomplish the same outcome/output in less code? I was happy i figured out the original problem, but I would like to understand/learn efficiency as well as the basics. I understand that vectors and structs/classes may be an avenue, I just don't really understand the reference materials.

So first things first, strings are expensive, consider using an enum and then using a map to translate that to a string, for example:
enum Teams {
OREGON,
OREGON_STATE
};
const map<Teams, string> Teams2string = { { OREGON, "Oregon" }, { OREGON_STATE, "Oregon State" } };
Then consider that the best way to store scores would be in a vector<pair<int, int>> particularly since we don't know how many, if any, overtime periods will be played. Thus the vector could be resized on a per-game basis.
Finally we need to make a game object which incorporates this information, and provides it's own displayScore method:
struct Game {
const Teams first;
const Teams second;
const vector<pair<int, int>> score;
void displayScore(const int period) {
if(period < size(score)) {
if(score[period].first >= score[period].second) {
cout << Teams2string[first] << ": " << score[period].first << ' ' << Teams2string[second] << ": " << score[period].second << endl;
} else {
cout << Teams2string[second] << ": " << score[second].first << ' ' << Teams2string[first] << ": " << score[first].second << endl;
}
}
}
};

Related

Football tournament with matrix

I'm trying to make a football tournament in C++, in which the user inputs the name of the teams(8 teams) and then each team has to play with the other one 1 time. Firstly, I don't know how to read the team names, I mean I tried to use .getline or just cin of a char array, but then I need to put the teams into the matrix and after the final game my program should print the table. So there's the first question: how to read the names and basically make the program think they are numbers or does it work with just with names, no need to use int? And then the users inputs the result for every game, but here comes the hard part. After all the results have been introduced, the matrix rotates cyclic and then the result stored in the variables(you will see in code victory/losses) overwrites themselves, so at the end, I cannot print the right table. So that's the second question: How can I make them store to the right 'team' while they rotate? Sorry if I didn't quite explain very well how it works, hope you understand it. Cheers!
// FOOTBALL TOURNAMENT
int map[2][4];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
cout << "map[" << i << "][" << j << "]= ";
cin >> map[i][j];
}
}
cout << "The map looks like this:" << endl;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
cout << map[i][j] << " ";
}
cout << endl;
}
map[0][0] = 1;
int temp = 0, temp2 = 0, temp3 = 0, temp4 = 0, temp5 = 0, temp6 = 0;
int a, b, c, d, e, f, g, h, round = 0;
int victory_m00(0), losses_m10(0), victory_m10(0), losses_m00(0), victory_m01(0), losses_m11(0), victory_m11(0), losses_m01(0);
int victory_m02(0), losses_m12(0), victory_m12(0), losses_m02(0), victory_m03(0), losses_m13(0), victory_m13(0), losses_m03(0);
do
{
// Insert result for every game
cout << "Enter the result of the first game between " << map[0][0] << " vs. " << map[1][0] << endl;
cin >> a >> b;
if (a > b) {
victory_m00++;
losses_m10++;
}
else if (a < b)
{
victory_m10++;
losses_m00++;
}
cout << "Enter the result of the first game between: " << map[0][1] << " vs. " << map[1][1] << endl;
cin >> c >> d;
if (c > d) {
victory_m01++;
losses_m11++;
}
else if (c < d)
{
victory_m11++;
losses_m01++;
}
cout << "Enter the result of the first game between: " << map[0][2] << " vs. " << map[1][2] << endl;
cin >> e >> f;
if (e > f) {
victory_m02++;
losses_m12++;
}
else if (e < f)
{
victory_m12++;
losses_m02++;
}
cout << "Enter the result of the first game between: " << map[0][3] << " vs. " << map[1][3] << endl;
cin >> g >> h;
if (g > h) {
victory_m03++;
losses_m13++;
}
else if (g < h)
{
victory_m13++;
losses_m03++;
}
round++;
// Map switching
temp = map[1][0];
map[1][0] = map[0][1];
temp2 = map[1][1];
map[1][1] = temp;
temp3 = map[1][2];
map[1][2] = temp2;
temp4 = map[1][3];
map[1][3] = temp3;
temp5 = map[0][3];
map[0][3] = temp4;
temp6 = map[0][2];
map[0][2] = temp5;
map[0][1] = temp6;
// Table calculating and printing ~ also this has to be outside the loop (but at first i wanted to print the table after every 'round'
cout << "This is how the table looks like after the " << round << " round: \n";
cout << map[0][0] << " has: " << victory_m00 << " victory(-ies) and " << losses_m00 << " loss-es!\n";
cout << map[0][1] << " has: " << victory_m01 << " victory(-ies) and " << losses_m01 << " loss-es!\n";
cout << map[0][2] << " has: " << victory_m02 << " victory(-ies) and " << losses_m02 << " loss-es!\n";
cout << map[0][3] << " has: " << victory_m03 << " victory(-ies) and " << losses_m03 << " loss-es!\n";
cout << map[1][0] << " has: " << victory_m10 << " victory(-ies) and " << losses_m10 << " loss-es!\n";
cout << map[1][1] << " has: " << victory_m11 << " victory(-ies) and " << losses_m11 << " loss-es!\n";
cout << map[1][2] << " has: " << victory_m12 << " victory(-ies) and " << losses_m12 << " loss-es!\n";
cout << map[1][3] << " has: " << victory_m13 << " victory(-ies) and " << losses_m13 << " loss-es!\n";
cout << endl;
cout << endl;
} while (map[0][1] != 2);
```

vector insert segmentation fault second iteration

I'm actually trying to implement the floyd's warshall algorithm but I met a hard-point. I got a segmentation fault while i'm trying to find the shortest-way in my matrix of sequence. I follow this tutorial:
floyd's warshall algorithm
Everything work well except at the line 124:
chemin.insert(it,sequenceTest[v1-1][temp-1]);
where i get the segfault (You can skip the first part except if you want to know how I implement the algorithm butt the problem is in the second part):
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
int i,j,k;
int sequenceTest [4][4] = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
int tempSequenceTest [4][4];
int distanceTest [4][4] = {{0,2,4,100000},{2,0,1,5},{4,1,0,3},{100000,5,3,0}};
int tempDistanceTest[4][4];
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
cout<<sequenceTest[i][j]<<" ";
}
cout<< endl;
}
cout<< endl;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
cout << distanceTest[i][j] << " ";
}
cout<< endl;
}
cout<< endl;
for(k=0;k<3;k++)
{
cout <<endl;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
cout << "i: " << i << " j: " << j << endl;
if(i == k)
{
tempSequenceTest[i][j] = sequenceTest[i][j];
tempDistanceTest[i][j] = distanceTest[i][j];
cout << " D " << tempDistanceTest[i][j] << " S " << tempSequenceTest[i][j];
}
if(j == k)
{
tempSequenceTest[i][j] = sequenceTest[i][j];
tempDistanceTest[i][j] = distanceTest[i][j];
cout << " D " << tempDistanceTest[i][j] << " S " << tempSequenceTest[i][j];
}
cout<< endl;
}
}
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
//cout<< "i: " << i << " j: " << j << " k:" << k << endl;
if(i!=k && j!=k)
{
if(distanceTest[i][j]> distanceTest[i][k] + distanceTest[k][j])
{
tempDistanceTest[i][j] = distanceTest[i][k] + distanceTest[k][j];
cout << distanceTest[i][j] << " > " << distanceTest[i][k] << " + " << distanceTest[k][j] << " = " << tempDistanceTest[i][j] << " " << i << j << endl;
tempSequenceTest[i][j] = k+1;
}
else
{
tempDistanceTest[i][j] = distanceTest[i][j];
tempSequenceTest[i][j] = sequenceTest[i][j];
}
}
}
}
cout<< endl;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
distanceTest[i][j] = tempDistanceTest[i][j];
sequenceTest[i][j] = tempSequenceTest[i][j];
}
}
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
cout<<tempSequenceTest[i][j]<<" ";
}
cout<< endl;
}
cout<< endl;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
cout << tempDistanceTest[i][j] << " ";
}
cout<< endl;
}
}
int v1, v2;
v1 = 1;
v2 = 4;
vector <int> chemin;
vector <int>::iterator it;
chemin.push_back(v1);
chemin.push_back(v2);
int temp = v2;
cout << sequenceTest[0][2];
while(sequenceTest[v1-1][temp-1] != v2)
{
it = chemin.begin() + 1;
cout << "V1: " << v1 << " V2: " << v2 << " Temp: " << temp << endl;
chemin.insert(it,sequenceTest[v1-1][temp-1]);
for(i=0;i<chemin.size();i++)
{
cout << chemin[i];
}
cout << endl;
temp = sequenceTest[v1-1][temp-1];
}
}
Thanks for your attention and for taking the time to help me!
chemin.insert(it,sequenceTest[v1-1][temp-1]);
This invalidates the iterator it, but you keep reusing it in the iterations that follow. If you want to continue inserting at the same position, capture the return value.
it = chemin.insert(it,sequenceTest[v1-1][temp-1]);

Newbie in C++. First text game

I study C ++ and try to create the first game. Here's the code:
#include <iostream>
#include <string>
using namespace std;
void info () {
int LVL = 1;
int money = 1000;
int EXP = 0;
int work = 200;
int learn = 15;
int k = 0;
}
void menu ()
{
info ();
char menu_items;
cout << "Choose action: " << "\n" << "1. Work" << "\n" << "2. Learn" << endl;
cin >> k;
if (k == 1){
int money = money + work;
cout << "U worked (+ "<< money << " dollars)" << "\n" << endl;
} if (k == 2) {
int EXP = EXP + learn;
cout << "U learned (+ " << EXP << " EXP)" << "\n" << endl;
} else {
cout << "ERROR" << endl;
}
}
int main()
{
info ();
while (LVL == 10) {
cout << "End game!";
}
while (LVL != 10) {
cout << "Your data: " << "\n" << "Money: " << money << "\n" << "EXP: " << EXP << "\n" << "LVL: " << LVL << "\n" << endl;
menu ();
}
}
Please correct the following:
1) The cyclic output data after rewrite
2) Proper cycle add money and experience when choosing one of the following actions
Info should probably be a class or struct. You only want to instantiate it once, and persist the values over your calls.
One option might be:
#include <iostream>
#include <string>
using namespace std;
struct info {
int lvl = 1;
int money = 1000;
int exp = 0;
const int work = 200;
const int learn = 15;
};
int main()
{
info i;
string k;
while (i.lvl < 10)
{
cout << "Your data: " << "\n" << "Money: " << i.money << "\n" << "EXP: " << i.exp << "\n" << "LVL: " << i.lvl << endl;
cout << "Choose action: " << "\n" << "1. Work" << "\n" << "2. Learn" << endl;
cin >> k;
if (k == "1")
{
i.money += i.work;
cout << "You worked (+ " << i.work << " dollars, now " << i.money << ")" << endl;
}
else if (k == "2")
{
i.exp += i.learn;
cout << "You learned (+ " << i.learn << " EXP, now " << i.exp << ")" << endl;
}
else
{
cout << "ERROR" << endl;
}
}
cout << "You won!" << endl;
}
#include <iostream>
#include <string>
using namespace std;
void menu()
{
int money = 1000;
int EXP = 0;
int work = 200;
int learn = 15;
int k = 0;
cout << "Choose action: \n 1. Work \n 2. Learn "<< endl;
cin >> k;
if (k == 1){
money =money + work;
cout << "U worked (+ " << money << " dollars)" << "\n" << endl;
} if (k == 2) {
EXP = EXP + learn;
cout << "U learned (+ " << EXP << " EXP)" << "\n" << endl;
}
else {
cout << "ERROR" << endl;
}
}
int main()
{
int money = 1000;
int LVL = 1;
int EXP = 0;
while (LVL == 10) {
`cout << "End game!"; `
}
while (LVL != 10) {
cout << "Your data: " << "\n" << "Money: " << money << "\n" << "EXP: " << EXP << "\n" << "LVL: " << LVL << "\n" << endl;
menu();
}
return 0;
}

User Input to a Value Stored in an Integer Array C++

I'm trying to make it so every time the user inputs a value, it's stored in an array in a place that represents a stat. Hard to explain so here's the code:
void MainChar::CharacterCreation()
{
int statPoints = 20;
int health = 0;
int magicDamage = 0;
int magicResist = 0;
int physicalResist = 0;
int physicalDamage = 0;
int magicOffMastery = 0;
int physicalOffMastery = 0;
int magicDefMastery = 0;
int physicalDefMastery = 0;
// SETS STATS AND THIER RESPECTIVE ARRAY PLACEMENT
int statArray[9];
statArray[0] = health;
statArray[1] = magicDamage;
statArray[2] = magicResist;
statArray[3] = physicalResist;
statArray[4] = physicalDamage;
statArray[5] = magicOffMastery;
statArray[6] = physicalOffMastery;
statArray[7] = magicDefMastery;
statArray[8] = physicalDefMastery;
std::string stats[9];
stats[0] = "Health : " ;
stats[1] = "Magic Damage : " ;
stats[2] = "Magic Resist : " ;
stats[3] = "Physical Resist : " ;
stats[4] = "Physical Damage : " ;
stats[5] = "Magic Offensive Mastery : " ;
stats[6] = "Physical Offensive Mastery : ";
stats[7] = "Magic Defensive Mastery : " ;
stats[8] = "Physical Defensive Mastery : ";
int statString = 0;
int statInt = 0;
while (statPoints > 0)
{
std::cout << "*******************************************************************************" << std::endl;
std::cout << "* *" << std::endl;
std::cout << "* CHARACTER CREATION *" << std::endl;
std::cout << "* *" << std::endl;
std::cout << "*******************************************************************************" << std::endl;
std::cout << " Health : " << health * 10 << std::endl;
std::cout << std::endl;
std::cout << " Magic Damage : " << magicDamage << std::endl;
std::cout << std::endl;
std::cout << " Magic Resist : " << magicResist << std::endl;
std::cout << std::endl;
std::cout << " Physical Resist : " << physicalResist << std::endl;
std::cout << std::endl;
std::cout << " Physical Damage : " << physicalDamage << std::endl;
std::cout << std::endl;
std::cout << " Magic Offensive Mastery : " << magicOffMastery << std::endl;
std::cout << std::endl;
std::cout << " Physical Offensive Mastery : " << physicalOffMastery << std::endl;
std::cout << std::endl;
std::cout << " Magic Defensive Mastery : " << magicDefMastery << std::endl;
std::cout << std::endl;
std::cout << " Physical Defensive Mastery : " << physicalDefMastery << std::endl;
std::cout << "*******************************************************************************" << std::endl;
std::cout << "STAT POINTS: " << statPoints << std::endl;
std::cout << stats[statString] ;
std::cin >> statArray[statInt] ;
statPoints -= statArray[statInt];
++statString;
++statInt;
}
}
As you might notice, I'm trying to have the user change the value of health, which is stored in statArray[statInt], which equates to statArray[0], then I ++statInt. The idea was I'd be able to have the user input all his stats one at a time. Instead of my intention, whats happening is it's taking the user input as a reference to the array slot. (statArray[0], statArray[1]) etc. Instead of the stat associated with that array slot.
To achieve what you want to do you could use a union:
union Stat {
struct {
int health;
int magicDamage;
int magicResist;
// ...
};
int array[3];
};
int main() {
Stat stat;
stat.array[1] = 42;
cout<<stat.magicDamage<<endl; // should give 42
};
However a better solution would be to use a map:
map<string,int> stat;
const char *keys[] = {"health","magicDamage","magicResist"};
int main() {
for (int i=0;i<3; ++i) {
cout<<"enter "<<keys[i]<<endl;
cin>>stat[keys[i]];
}
}
Change statArraydefinition to use pointers instead of values
int *statArray[9];
statArray[0] = &health;
statArray[1] = &magicDamage;
statArray[2] = &magicResist;
statArray[3] = &physicalResist;
statArray[4] = &physicalDamage;
statArray[5] = &magicOffMastery;
statArray[6] = &physicalOffMastery;
statArray[7] = &magicDefMastery;
statArray[8] = &physicalDefMastery;
And update next lines:
std::cout << *stats[statString] ;
std::cin >> *statArray[statInt] ;
statPoints -= *statArray[statInt];

Hot Dog Stand static function issue

I need this program to create a new HotDogStand object that is able to track how many hot dogs are sold by each stand individually and all together, and I cannot figure out how to make my static method work to find the total number of hot dogs sold between all stands. Can someone point me in the right direction please?
#include <iostream>
using namespace std;
class HotDogStand
{
public:
HotDogStand(int id, int hds);
void justSold();
int getNumSold();
int getID();
int getTotalSold();
private:
int idNum;
int hotDogsSold;
static int totalSold;
};
HotDogStand::HotDogStand(int id, int hds)
{
idNum = id;
hotDogsSold = hds;
return;
}
void HotDogStand::justSold()
{
hotDogsSold++;
return;
}
int HotDogStand::getNumSold()
{
return hotDogsSold;
}
int HotDogStand::getID()
{
return idNum;
}
int HotDogStand::getTotalSold()
{
totalSold = 0;
totalSold += hotDogsSold;
}
int main()
{
HotDogStand s1(1, 0), s2(2, 0), s3(3, 0);
s1.justSold();
s2.justSold();
s1.justSold();
cout << "Stand " << s1.getID() << " sold " << s1.getNumSold() << "." << endl;
cout << "Stand " << s2.getID() << " sold " << s2.getNumSold() << "." << endl;
cout << "Stand " << s3.getID() << " sold " << s3.getNumSold() << "." << endl;
cout << "Total sold = " << s1.getTotalSold() << endl;
cout << endl;
s3.justSold();
s1.justSold();
cout << "Stand " << s1.getID() << " sold " << s1.getNumSold() << "." << endl;
cout << "Stand " << s2.getID() << " sold " << s2.getNumSold() << "." << endl;
cout << "Stand " << s3.getID() << " sold " << s3.getNumSold() << "." << endl;
cout << "Total sold = " << s1.getTotalSold() << endl;
}
Globally (outside of the class), you have to define the static variable:
int HotDogStand::totalSold = 0;
Change
void HotDogStand::justSold()
{
hotDogsSold++;
totalSold++; // increment here
return;
}
And
int HotDogStand::getTotalSold()
{
return totalSold; // just return value
}