I am learning C++ and for that, I try to do a simple game project (having the same rows as columns and randomly distributed numbers from 0-blank to rows*rows-1. Target is for player to change numbers to be in numeric order by rows). Then 0-blank can be switched with any neighborhood horizontally or vertically) I code it through procedural code and it works fine. Now I am trying to redo it using object-oriented programming and classes.
For that reason I have 2 classes:
Number - stores 2 integers with position x and y
Deck - stores array of Numbers, practically s index of an array is the number itself and Number object just store position.
Deck deck (rows) creates sorted numbers with position and is checked by std::cout.
Now I am trying to implement the shuffle function which will take randomly 2 Numbers and switch their positions (m_posX and m_posY) however trying the same principle to get m_posX is not correct and gives different large numbers compared to the creation of the position.
getNumber just does not work as I intended.
Practically I need to return m_posX and m_posY from exact Number object in array of m_game deck.
Any suggestions what am I doing wrong is welcome.
I have this code:
Number.h
#ifndef NUMBER_H
#define NUMBER_H
#include <array>
class Number
{
public:
// Number(int x, int y, int d);
setPosition (int x, int y);
setPosition (std::array <int,2> &xy ); // std::array [2]
setDigits (int d);
switchPosition (Number &c1, Number &c2);
std::array<int,2> getPosition (); // std::array [2]
int getPositionX ();
int getPositionY ();
int getDigits(); // int
protected:
int m_posX;
int m_posY;
int m_digits;
};
#endif // NUMBER_H
Number.cpp
Number::setPosition (int x, int y)
{
m_posX = x;
m_posY = y;
}
Number::setPosition (std::array <int,2> &xy )
{
m_posX = xy [0];
m_posY = xy [1];
}
Number::setDigits (int d)
{
m_digits=d;
}
Number::switchPosition (Number &c1, Number &c2)
{
int tempX {c1.m_posX};
int tempY {c1.m_posY};
c1.setPosition (c2.m_posX, c2.m_posY);
c2.setPosition (tempX, tempY);
}
std::array<int,2> Number::getPosition ()
{
static std::array <int,2> position;
position [0] = m_posX;
position [1] = m_posY;
return position;
}
int Number::getDigits ()
{
return m_digits;
}
int Number::getPositionX ()
{
return m_posX;
}
int Number::getPositionY ()
{
return m_posY;
}
deck.h
#ifndef DECK_H
#define DECK_H
#include "number.h"
class Deck
{
public:
Deck(int rows=3);
shuffleDeck (int rows);
Number & getNumber (int elementNumber);
protected:
std::array <Number,100> m_game;
};
#endif // DECK_H
deck.cpp
#include "deck.h"
#include "number.h"
#include "rnd.h"
#include <iostream>
Deck::Deck(int rows)
{
std::array <Number,100> m_game;
for (int j {0}; j < (rows); ++j)
{
for (int i {0}; i < (rows); ++i)
{
m_game[i+j*rows].setPosition (i,j);
std::cout << "Number: " << (i+j*rows) << '\t' << "Coordinates: " << '\t' << m_game[i+j*rows].getPosition()[0] <<"," << m_game[i+j*rows].getPosition()[1] << '\n' ;
};
};
std::cout << "fc Deck::Deck (int rows) Number10 posX: "<< m_game[10].getPosition()[0] << '\n';
std::cout << "fc Deck::Deck (int rows) Number10 posY: "<< m_game[10].getPosition()[1] << '\n';
}
Number & Deck::getNumber (int elementNumber)
{
std::cout << "fc Deck::getNumber() Number " << elementNumber << " getPosition X,Y: " << m_game[elementNumber].getPositionX() << "," << m_game[elementNumber].getPositionY() << '\n' ;
return m_game[elementNumber];
}
game.cpp running code
#include "game.h"
#include "gmath.h"
#include "constant.h"
#include "graphics.h"
#include "number.h"
#include "deck.h"
#include <iostream>
int game (int rows)
{
int steps = 0;
Graphics piece {};
Deck deck(rows);
Number temp = deck.getNumber(10);
int tempI = temp.getPosition()[10];
//
// THIS DOES NOT WORK GETTING printed large number as 28573728
// [10] has m_posX set to 2 and m_posY set to 2 by Deck deck (rows);
//
std::cout << "CHECK game.h Number10 positionX: "<< tempI << '\n';
return steps; // for future counting score
}
Try return by value and not by reference here:
Number & Deck::getNumber (int elementNumber)
{
std::cout << "fc Deck::getNumber() Number " << elementNumber << " getPosition X,Y: " << m_game[elementNumber].getPositionX() << "," << m_game[elementNumber].getPositionY() << '\n' ;
return m_game[elementNumber];
}
like this:
Number Deck::getNumber (int elementNumber)
{
std::cout << "fc Deck::getNumber() Number " << elementNumber << " getPosition X,Y: " << m_game[elementNumber].getPositionX() << "," << m_game[elementNumber].getPositionY() << '\n' ;
return m_game[elementNumber];
}
and of course do not forget to change the declaration:
Number getNumber (int elementNumber);
The problem is very obvious.
In function game you are writing int tempI = temp.getPosition()[10];.
The function getPosition() returns a std::array<int, 2>. So, an array having 2 elements. One for x and one for y position. But with [10] your are trying to access the element number 10 from your array (which has only 2 elements). This is an out of bounds error. So, It will read some random nonesense value and show that. This is undefined behaviour.
I am not sure, which compiler you have, but in debug mode, it should throw an exception and inform you about the problem.
Correct it to
int tempx = temp.getPosition()[0];
int temp< = temp.getPosition()[1];
You anyway need to enable ALL compiler warnings. It did it and got dozens of messages.
You define many functions without return type. You must use void for this, e.g. function setPosition(int x, int y); must be defined as void setPosition(int x, int y);. And so on.
Also in constructor of Deck you are redefining and with that overwriting the already defined array std::array <Number, 100> m_game; in class deck. Delete the line in the constructor.
You may also consider to replace the std::array <int, 2>& xy by a std::pair or a simple struct like:
struct Position{
int x;
int y;
};
That would be more intuitive . . .
Related
This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 4 years ago.
My assignment is to use operator overloading to
create a random number array
get lowest number
get highest number
get average
get total and
get standard deviation.
It is just a mess. Here is my code:
#ifndef ASSIGNMENT6_HEAD6_H
#define ASSIGNMENT6_HEAD6_H
#include <iostream>
using namespace std;
class Analyzer {
//Private Member
private:
int numbers;
//Public Member
public:
Analyzer();//default constructor
~Analyzer();//destructor
Analyzer operator+(const Analyzer &a) const;
friend numbers operator+();
};//end of class
#endif //ASSIGNMENT6_HEAD6_H
//Class math with overloading operator and friends
#include "head6.h"
#include <cmath>
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
vector<int> numbers;
int min = numbers[0];
int max = numbers[0];
int sizeofArray;
Analyzer::Analyzer() {
}
int getLowest(const int[], int);
//Random number member
void randNumbers(int sizeofArray, int* numbers[]) {
for (int index = 0; index < sizeofArray; index++)
{
numbers[index] = (numbers() % 499) + 100;
}return;
}
//Setters
int lowest = getLowest(numbers, sizeofArray);
int highest = getHighest(numbers, sizeofArray);
float total = getTotal(numbers);
double average = getAverage(total, sizeofArray);
//Lowest number
void getLowest(const int numbers[], int sizeofArray) {
for (int i = 0; i < sizeofArray; i++) {
if (min > numbers[i]) {
min = numbers[i];
min = lowest;
}
}
return;
}
//Highest number
void getHighest(const int numbers[], int sizeofArray) {
for (int i = 0; i < sizeofArray; i++) {
if (max > numbers[i]) {
max = numbers[i];
max = lowest;
}
}
return;
}
//Total
float getTotal(const int numbers) {
total = sum(numbers[]);
return total;
}
//Average
double getAverage(const float total, int sizeofArray) {
double average = total / sizeofArray;
return average;
}
//standard deviation
float getStandardDeviation(int sizeofArray, float numbers[])const
{
float deviation1;
for (int i = 0; i < sizeofArray; i++)
sum = (mean - numbers[i]) * (mean - numbers[i]);
deviation1 = sqrt(sum / sizeofArray - 1);
float deviation = deviation1;
return deviation;
}
string a() {
stringstream sout;
sout << "STATISTICAL ANALYSIS OF RANDOMLY GENERATED NUMBERS" << endl;
sout << "====================================================" << endl;
sout << left << "Lowest Number:" << left << getLowest() << endl;
sout << left << "Highest Number:" << left << getHighest() << endl;
sout << left << "Numbers Total:" << left << getTotal() << endl;
sout << left << "Numbers Averge:" << left << getAverage() << endl;
sout << left << "Numbers of Standard Deviation:" << left <<
getStandardDeviation() << endl;
return sout.a();
}
int main()
{
Analyzer a;
a + 100;
cout << a;
return 0;
}
Thank you for any assistance.
Your assignment is to use operator overloading to solve the issues - but you actually don't do so anywhere (apart from the operator+ for your Analyzer class – which is meaningless, though).
Reading your lines, I'd rather assume that you're supposed to write separate classes for each task:
class Minimum
{
std::vector<int> const& values
public:
Minimum(std::vector<int> const& values) : values(values) { }
// calculates minimum / lowest value from member:
int operator()();
};
class Maximum
{
public:
//Maximum(); not needed in this variant
// calculates maximum from parameter
int operator()(std::vector<int> const& values);
};
void test()
{
std::vector<int> values({10, 12, 7});
int min = Minimum(values)();
int max = Maximum()(values);
}
These are two different patterns, for consistency, you should select one and implement all classes alike. In first approach, you can access the vector from any member function without having to pass it around as parameter, in second approach, you can re-use one and the same object to calculate the value on several different vectors (you could still maintain a pointer to the vector to avoid passing it around via parameters...).
Coming back to your original code, unfortunately it is full of errors
vector<int> numbers;
int min = numbers[0]; // vector is yet empty! undefined behaviour!
int max = numbers[0];
Actually, you might want not to use globals at all, see later...
//int sizeofArray; // use numbers.size() instead!
// not an error, but questionable: you have a std::vector already, why do you
// fall back to C-style raw arrays?
void randNumbers(int sizeofArray, int* numbers[])
// ^ array of pointers???
{
for (int index = 0; index < sizeofArray; index++)
{
numbers[index] = (numbers() % 499) + 100;
// you certainly intended to use rand function
}
// return; // just plain obsolete
}
// vector variant:
void randNumbers(unsigned int numberOfValues, std::vector<int>& destination)
// ^ not how many numbers ARE in,
// but how many SHALL be inserted
{
// assuming we want to re-use this function and guarantee that EXACTLY
// 'numberOfValues' values are contained:
destination.clear(); // there might have been some values in already...
// assure sufficently internal memory pre-allocated to prevent
// multiple re-allocations during filling the vector:
destination.reserve(numberOfValues);
while(numberOfValues--)
{
numbers.push_back(rand() * 500 / RAND_MAX + 100);
// modulus is unprecise; this calculation will give you better
// distribution
// however, rather prefer modern C++ random number generators!
// IF you use rand: assure that you call srand, too, but exactly ONCE,
// best right when entering main function
}
}
// C++ random number generator:
void randNumbers(unsigned int numberOfValues, std::vector<int>& destination)
{
static std::uniform_int_distribution<> d(100, 599);
static std::mt19937 g;
destination.clear();
destination.reserve(numberOfValues);
while(numberOfValues--)
{
numbers.push_back(d(g));
}
}
Now you have contradicting function declarations:
int getLowest(const int[], int);
void getLowest(const int numbers[], int sizeofArray) { /* ... */ }
int lowest = getLowest(numbers, sizeofArray);
// again: the vector is yet empty!
// so you certainly won't get the result desired
// however, this won't compile at all: numbers is a std::vector,
// but parameter type is array, so you need:
int lowest = getLowest(numbers.data(), numbers.size());
// ^ replaced the redundant global as well
// move this into your main function AFTER having filled the vector!
// picking int as return value:
int getLowest(const int numbers[], unsigned int sizeofArray)
{
// you'd now have to initialize the global first; better, though:
// return a local variable:
// this assumes that there is at least one element in! check before usage
// and decide what would be the appropriate error handling if the vector
// is empty (return 0? return INT_MIN? throw an execption?)
int min = numbers[0];
for (int i = 1; i < sizeofArray; i++)
{
if (min > numbers[i])
{
min = numbers[i];
// min = lowest; // don't overwrite the minimum again!
}
}
// returning at end of void function is obsolete, don't do that explicitly
// well, with int as return value, as is NOW, you NEED to return:
return min;
}
Maximum analogously, be aware that you did not change the comparison from > to <! Be aware that there are already std::min_element, std::max_element and std::minmax_element which do the same (if not prohibited by the assignment, you should rather use these instead of re-inventing the wheel).
// prefere double! float (on typical machines at least) has same size as int
// and it is quite likely that you will lose precision due to rounding; I
// personally would rather use int64_t instead, so you won't run into rounding
// issues even with double and you'd need quite a large amount of summands
// before overflow can occur...
float getTotal(const int numbers) // just one single number???
{
total = sum(numbers[]);
// index operator cannot be applied on a single int; additionally, you need
// to provide an argument; where is 'sum' function defined at all???
return total;
}
// prefer double again
double getStandardDeviation(int sizeofArray, float numbers[]) // const
// (free standing functions cannot be const)
{
// mean isn't declared/defined anywhere (average instead?)!
// and you need to declare and initialize the sum appropriately:
double sum = 0.0;
float deviation1;
for (int i = 0; i < sizeofArray; i++)
sum += (mean - numbers[i]) * (mean - numbers[i]);
// ^ you need to add, if you want to build sum
// why two variables, even both of same type???
deviation1 = sqrt(sum / sizeofArray - 1);
float deviation = deviation1;
return deviation;
// simplest: drop both deviation and deviation 1 and just do:
return sqrt(sum / sizeofArray - 1);
}
Finally: I don't think that you'd use the resulting string (below) for anything else than printing out to console again, so I'd output to std::cout directly (naming the function 'print'); if at all, I'd provide a std::ostream as parameter to be more flexible:
void print(std::ostream& sout)
{
sout << "STATISTICAL ANALYSIS OF RANDOMLY GENERATED NUMBERS" << endl;
sout << "====================================================" << endl;
sout << left << "Lowest Number:" << left << getLowest() << endl;
sout << left << "Highest Number:" << left << getHighest() << endl;
sout << left << "Numbers Total:" << left << getTotal() << endl;
sout << left << "Numbers Averge:" << left << getAverage() << endl;
sout << left << "Numbers of Standard Deviation:" << left
<< getStandardDeviation() << endl;
}
Now you could pass std::cout to, a std::ostringstream object or even write to file via a std::ofstream...
int main()
{
Analyzer a, b, c; // b, c added by me for illustration only
a + 100;
// the operator accepts another Analyzer object, so you could do
c = a + b;
cout << a; // there's no operator<< overload for Analyzer class
// it is HERE where you'd call all your getXZY functions!
return 0;
}
You are passing a pointer to an array of integers:
void randNumbers(int sizeofArray, int* numbers[])
where you really just want to pass numbers as an array. And since all arrays degrade to pointers when passed as a parameter, your function is simply this:
void randNumbers(int sizeofArray, int* numbers) {
for(int index = 0; index < sizeofArray; index++) {
numbers[index]= (rand() % 499) + 100;
};
}
The result is that the items in numbers will be integers in the range of [100..599] inclusive.
i searched a lot here, but there is no right explanation for me, for an advanced newbie in c++. I worked before with vector of structs and now I get segmentation faults...
Thats why I want to know how such objects actually works and if it is the right the way I am doing!
I have a struct like
struct numberOfSpecies {
int predator;
int prey1;
int prey2;
};
and a vector of it:
std::vector<numberOfSpecies> size;
Before I resize it and fill it with values.
size.resize(100);
what is actually this doing? Is this right for a struct?
It looks like it is initialized with zeros...
Now I am doing this like:
size[t].predator=0;
size[t].prey1=0;
size[t].prey2=0;
for(int k = 0; k < N; ++k){
size[t].predator++;
size[t].prey1++;
size[t].prey2++;
}
Is this right? Where are possible issues? How to do it better?
The easiest and 'correct' solution here is probably to just use the resize() function that belongs to the vector object with aggregate initialization (if you have access to c++11 and on), something like
size.resize(100,{0,0,0}); //aggregate initialization
for(int k = 0; k < N; ++k)
{
size[t].predator++;
size[t].prey1++;
size[t].prey2++;
}
All members of each numberOfSpecies object will be initialized to 0.
This:
size[t].predator=0;
size[t].prey1=0;
size[t].prey2=0;
will write zeros to the tth element of size - that may or may not be useful:
This:
for(int k = 0; k < N; ++k){
size[t].predator++;
size[t].prey1++;
size[t].prey2++;
}
will increment the tth element of size N times. This seems incredibly unlikely to be useful. I think what you want is:
size[0].predator=0; // Technically not needed because .resize()
size[0].prey1=0; // will have initialized it to zero anyway
size[0].prey2=0; // *BUT* explicit is always better than implicit.
// Initialize each element of size to be one greater than previous.
for(int k = 1; k < N; ++k){
size[k].predator = size[k-1].predator + 1;
size[k].prey1 = size[k-1].prey1 + 1;
size[k].prey2 = size[k-1].prey2 + 1;;
}
Use the value parameter for static parameters.
#include <vector>
struct foo{
int g;
int h;
int l;
};
int main()
{
std::vector<foo> manyFoo(10, {0});
manyFoo.resize(60, {0});
}
If you want to grow your vector as you also put arbitrary values into the struct you could ->
#include <iostream>
#include <vector>
struct foo{
foo(int aG,int aH, int aL):g(aG),h(aH),l(aL) {};
int g;
int h;
int l;
};
int main() {
std::vector<foo> lVec;
for (int i=0;i<10;i++) {
lVec.emplace_back(foo(i,i*2,i*4));
}
int lPos=0;
for (auto &rFoo: lVec) {
std::cout << "Item pos" << lPos++ << " g:" << rFoo.g << " h:" << rFoo.h << " l:" << rFoo.l << std::endl;
}
return EXIT_SUCCESS;
}
If you know the size of the vector and you want to populate it you could ->
#include <iostream>
#include <vector>
struct foo{
foo(int aG,int aH, int aL):g(aG),h(aH),l(aL) {};
int g;
int h;
int l;
};
int main() {
std::vector<foo> lVec(10,{0,0,0});
int lPos = 0;
for (auto &rFoo: lVec) {
rFoo = foo(lPos,lPos*2,lPos*4);
lPos++;
}
lPos=0;
for (auto &rFoo: lVec) {
std::cout << "Item pos" << lPos++ << " g:" << rFoo.g << " h:" << rFoo.h << " l:" << rFoo.l << std::endl;
}
return EXIT_SUCCESS;
}
You could add an default constructor to your structure. The new code will look something like this:
struct numberOfSpecies {
numberOfSpecies (): predator(0), prey1(0), prey2(0) { } // default constructor
int predator;
int prey1;
int prey2;
};
That way, your structure will be properly initialized inside your vector when resize is applied.
I can't seem to find where my issue is. Its a three file program with aDie class in one file, aHistogram class in another file, and the main.cpp file. It is supposed to print a histogram constructed with X's to show how many times the die landed on each of the six faces. I cant move forward because of the vector error... There may be other issues with the program that i haven't worked out yet, but I just want to know about the vector error. Thank you.
main.cpp:
#include <iostream>
#include <stdlib.h> //srand and rand
#include <time.h> //Time
#include <vector>
#include <algorithm>
#include "aHistogram.h"
#include "aDie.h"
using namespace std;
int main()
{
srand (time(NULL));
int numRolls;
const int maxLengthOfLine = 50;
cout << "How many rolls? " << endl;
cin >> numRolls;
aDie fairDie;
aHistogram fairHistogram;
//For Loop rolls the die and updates the histogram vector ~~binHistogram.
for(int i = 0; i < numRolls; i++)
{
int face = fairDie.roll();
fairHistogram.update(face);
}
cout << "*******************" << endl;
cout << "*****Histogram*****" << endl;
cout << "*******************" << endl;
fairHistogram.display(maxLengthOfLine);
}
aDie.h:
#ifndef ADIE_H_INCLUDED
#define ADIE_H_INCLUDED
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <algorithm>
using namespace std;
/********************************************/
/*******Definition of aDie class*************/
/********************************************/
class aDie
{
public:
int roll(); //return an integer between 1 and 6 to represent what face appears when the die is rolled.
aDie(); //Default constructor
~aDie(); //Destructor
private:
int numFaces = 6;
};
int aDie::roll()
{
return ((rand() % numFaces) + 1); //returns a random number between 1 and 6
}
aDie::aDie()
{
cout << "Dice Roll...." << endl;
return;
}
aDie::~aDie()
{
return;
}
#endif // ADIE_H_INCLUDED
aHistogram.h:
#ifndef AHISTOGRAM_H_INCLUDED
#define AHISTOGRAM_H_INCLUDED
#include <algorithm>
#include <stdlib.h>
#include <vector>
using namespace std;
/********************************************/
/*******Definition of aHistogram class*******/
/********************************************/
class aHistogram
{
public:
void update(int face);
void display(int maxLengthOfLine);
int Count(int face);
void clear();
aHistogram(); //Constructor
~aHistogram(); //Destructor
private:
vector<int> binHistogram;
const int numFaces = 6;
int totalRolls;
int largeBin = 0;
double xScale;
};
//Adds a count to each face every time the die lands on said face.
void aHistogram::update(int face)
{
binHistogram.at(face) += 1;
return;
}
//Displays the histogram with X's
//maxLengthOfLine represents the maximum number of x’s to be printed for the largest bin count.
void aHistogram::display(int maxLengthOfLine)
{
xScale = maxLengthOfLine / largeBin;
for(int i = 1; i <= 6; i++)
{
cout << i << " : " << Count(i) << " : ";
int numXs = xScale * binHistogram.at(i);
for(int j = 0; j < numXs; j++)
{
cout << "X";
}
}
}
//To be called AFTER aHistogram::update
//Returns a count of how many times for each face of the die
int aHistogram::Count(int face)
{
//For Loop determines the largest bin count
for (int i = 1; i < numFaces; i++)
{
while (binHistogram[i] >= largeBin)
{
largeBin = binHistogram.at(i);
}
}
//
return binHistogram.at(face);
}
void aHistogram::clear()
{
binHistogram.clear();
return;
}
//Defines the DEFAULT CONSTRUCTOR. Sets all elements of the histogram to zero.
aHistogram::aHistogram()
{
return;
}
//Defines the DESTRUCTOR. Clears vector after use.
aHistogram::~aHistogram()
{
binHistogram.clear(); //Clears vector
return;
}
#endif // AHISTOGRAM_H_INCLUDED
I didnt find the place where you initialize the histogram this might be the problem. But even if you fix that, you will hit two other bugs:
for (int i = 1; i < numFaces; i++)
{
while (binHistogram[i] >= largeBin)
{
largeBin = binHistogram.at(i);
}
}
you are accessing elements 1....6 when probably it should be 0...5. Same problem in the line where you have
largeBin = binHistogram.at(i);
which is most likely the line that causes the error (the one above wont be so nice to tell you what is the problem but just crash your program).
You never change the size of the vector in the aHistogram class, which means its size will always zero. Any index will be out of bounds.
For things like histograms I would actually recommend you to use std::unorderd_map instead of std::vector, with the "face" being the key and the count being the data. Then you could do e.g.
binHistogramMap[face] += 1;
without worrying about the element for face not existing (it will be created and initialized to zero if the entry doesn't exist).
I am working on a program that is suppose to have 3 different Robots racing on a track. The track is suppose to be 100 in length. I have just learned inheritance and still trying to understand how to connect data members from one .h to another. When I run my program, nothing happens when I call any of my Robots. I will show one of them as an example. Can you explain how to make their movements update the race 2D array?
robotRace.h
#ifndef ROBOTRACE_H
#define ROBOTRACE_H
using namespace std;
class robotRace {
public:
robotRace (); //constructor
static const int rows = 5;
static const int columns = 100;
protected:
int race[rows][columns]; //initial base for race floor
};// end superclass robotRace that should do no movement
#endif
robotRace.cpp
#include <iostream>
#include "robotRace.h"
using namespace std;
robotRace :: robotRace() {
for (int i = 0; i < rows; i++)
for (int j= 0; j<columns; j++)
race[i][j] = ' ';
}//end constructor
This is one of the Robots and their functions to update array. Not sure how to make it work.
FunctionRobot.h
#ifndef FUNCTIONROBOT_H
#define FUNCTIONROBOT_H
#include "robotRace.h"
using namespace std;
class FunctionRobot : public robotRace{
public:
FunctionRobot();
int position(int);
void print();
protected:
};
#endif
FunctionRobot.cpp
#include <iostream>
#include "FunctionRobot.h"
#include <cmath>
using namespace std;
FunctionRobot :: FunctionRobot (): robotRace() {
int initPos =0;
race[initPos][0] = '*';
cout <<"Initial position of Function Robot is at begin of race."<<endl;
}
int FunctionRobot :: position(int place=0){
// log with a base 2 needs to be divided by the "x"
// below is the Robots formula to determine each of their movements
double x = ( 2 * (log(place)/log(2)));
return (int) x;
}
void FunctionRobot :: print(){
for (int i;i=0; i<100; i++)
for (int j;j=0; j<1; j++)
race[position()][j];
}
this is my main file as requested. This is basic format. I am hoping to make the while loop more practical so that the user doesn't have to keep entering 1.
There is also no error coming from my code. It runs just shows nothing.
main.cpp
#include <iostream>
#include "robotRace.h"
#include "FunctionRobot.h"
using namespace std;
int main() {
int userInput;
cout << "Welcome to the Robot Race of the year!" << endl;
cout << "For our contestants we have the amazing three!" << endl;
cout << "The contestants are Robots F, R and U" << endl;
cout << "Let the games begin! \n\n";
cout << "Enter 1 to begin. " << endl;
cin >> userInput;
FunctionRobot functionObj;
//functionObj.position();
//functionObj.print();
cout << "Ready... Set... Go!!" << endl;
while (userInput == 1) {
functionObj.position(4);
functionObj.print();
} //end while
return 0;
}
Your print() goes out of bounds:
void FunctionRobot :: print(){
for (int i; i<100; i++)
for (int j; j<1; j++)
race[position()][j];
}
j is not initialized. You could try int j = 0 for a start. Similar for i.
Moreover you know that this function is named PRINT but doesn't PRINT ANYTHING, actually it doesn't do anything but calling position().
int FunctionRobot :: position(int place=0){
// log with a base 2 needs to be divided by the "x"
// below is the Robots formula to determine each of their movements
double x = ( 2 * (log(place)/log(2))); <-------- now x is a double
return (int) x; <-------- now x is an integer, are you sure about that?
}
Loss of precision happens here. Let's say that x is assigned a value of 3.14. Then you cast it (the cast would happen automatically since the return type of the function is also an int) into an integer, thus it will be converted to 3, thus you loss precision.
About main.cpp
You call the user to input 1 and then you have:
while (userInput == 1) {
functionObj.position(4);
functionObj.print();
} //end while
but userInput is not going to be modified, thus you are running into a non-ending loop.
I'm writing a program which is intended to compare the numbers in 2 arrays and output the number of matches that there are.
RandomNumber.h
#pragma once
#include <iostream>
#include <cstdlib>
#include <ctime>
class RandomNumber
{
public:
void randomNumber();
int actualRandomNumber;
};
RandomNumber.cpp
#include "RandomNumberGenerator.h"
void RandomNumber::randomNumber()
{
actualRandomNumber = rand() % 66 + 1;
}
Game.h
#include "RandomNumberGenerator.h"
class Game
{
private:
int randomNumbers[6];
public:
void generateRandomNumbers();
void compareNumbers2();
};
Game.cpp
void Game::generateRandomNumbers()
{
RandomNumber create;
for (int i = 0; i < 6; i++)
{
create.randomNumber();
randomNumbers[i] = create.actualRandomNumber;
}
for (int i = 0; i < 6; i++)
{
std::cout << randomNumbers[i] << " ";
}
}
void Game::compareNumbers2()
{
int k = 0;
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
if (randomNumbers[i] == randomNumbers[j])
{
k++;
}
}
}
if (k > 0)
{
std::cout << "Congratulations you matched: " << k << " number(s)";
}
if (k == 0)
{
std::cout << "Unfortunatly you matched: " << k << " numbers";
}
}
Main.cpp
#include "Game.h"
#include "RandomNumberGenerator.h"
int main()
{
Game play;
srand (time(NULL));
play.generateRandomNumbers();
std::cout << std::endl << std::endl;
play.generateRandomNumbers();
std::cout << std::endl << std::endl;
play.compareNumbers2();
system("pause");
return 0;
}
The problem I'm having isn't in creating the arrays and filling them, I get two filled arrays with 2 different sets of random numbers, but for some reason when comparing them the number of matches it tells me I have is always about 6 or 8 when I in fact rarely have more than one or two if that.
The most obvious problem is that you only have one array.
class Game
{
...
int randomNumbers[6];
Where did you think the second array was?
Based on your code, I saw only 1 array. And in the function compareNumber2(), you compare each number with it once. Therefore, the result is the number of elements (e.g, 6).
Looking at code, I can say you will be getting 6 matches all the time, since you randomNumbers array will be overwritten in second step (when you try to generate random numbers second time)
There are actually two problems bigger and smaller:
You're comparing your array int randomNumbers[6] with itself.
Please don't call the object create. Its very wrong habit. Call the object of class RandomNumber i.e a randomNumber and take your random number from it like:
randomNumber.getValue()
Usually try to call the methods with verbs and objects with nouns it will be more natural don't you think?
You do no not compare two arrays. You compare one array, data member of class Game, with itself. You simply fill it two times.