I need to write C program for rolling dice using class Dice. The main requirement is that I need to use this main, editing it:
int main()
{
Dice* ptrDice;
???
for (int i = 0; i < 5; i++)
{
???? // roll the 5 dice
???? // print the outcome
}
}
I just cannot get how to use pointers here. Can anyone help, pls?!
Here is my code but it's not working :(
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
class Dice{
public:
Dice();
int getNums();
void Roll();
private:
int nNums;
};
Dice::Dice(){
nNums=5;
}
int Dice::getNums()
{
return nNums;
}
void Dice::Roll()
{
nNums = rand()%6 + 1;
}
int main()
{
Dice* ptrDice = new Dice;
ptrDice -> getNums();
for (int i = 0; i < 5; i++)
{
getNums[i] = rand()%6 + 1; // roll the 5 dice
cout << "You rolled: ";
cout << ptrDice->getNums() << setw(4);
cout << endl; // print the outcome
}
}
My main trouble is to use that ptrDice and printing it in main function, I guess!
You're making this more complicated than it needs to be.
A simple Dice object needs no data members and only one member function. If you're using the rand() function, the constructor should seed the random number generator with srand(seed). The Roll() function should return the number rolled as an int. You don't need the getNums() function at all, which will only return 5 as your class is defined.
class Dice() {
public:
int roll() { return rand() % 6 + 1; }
};
...
int main() {
Dice* ptrDice = new Dice;
for (int i=0; i<5; i++) {
cout << "You rolled" << ptrDice->roll() << '\n';
}
delete ptrDice;
}
You could expand this class to simulate multiple dice with any number of sides. Then you could use integer data members to retain the number of dice and their number of sides.
Related
Here is the code I'm trying to create, and yes its messy for now. To give some back story I'm trying to figure out how to call a class multiple times without doing it seperately. What I mean is instead of performing:
Dice diceOne;
Dice diceTwo; and so on, I want to know if it is possible to just put it as Dice dicewhatever(*) and have that be a modifiable variable. This is so that I can set that variable to a number and then decrement it based on a score.
I dont know if this is even possible, but at this point I've beat my head against this so much I'm just pulling at straws to see if it would be a fit.
class Dice {
public:
Dice();
int Roll();
int currentDiceSide();
private:
int diceRoll;
int diceReRoll; //Declares and initializes the number of dice to allow for roll next dice throw.
};
Dice::Dice()
: //This is the beginning of the class and sets diceRoll to zero
diceRoll(0)
{
}
int Dice::Roll()
{ //This function actually does the random roll within the class Dice.
diceRoll = ((rand() % 6) + 1);
return diceRoll;
}
int Dice::currentDiceSide()
{ //This function returns the value of the dice roll for the class call.
return diceRoll;
}
void Game::Rules()
{
ifstream inFile;
inFile.open("Farkle Rules.txt");
string line;
if (inFile.fail()) {
cerr << "Error opening file" << endl;
exit(1);
}
if (inFile.is_open()) {
while (inFile.good()) {
getline(inFile, line);
cout << line << endl;
}
inFile.close();
}
}
void Game::GetPlayerInput(int playerInput)
{
cin >> playerInput;
}
void Game::RunGame()
{
Rules();
bool farkle = false;
double turnSum = 0;
double value = 0;
int i = 0;
int w = 6;
int players = 0;
int numPlayer = 0;
int diceOneValue = 0;
int diceTwoValue = 0;
int diceThreeValue = 0;
int diceFourValue = 0;
int diceFiveValue = 0;
int diceSixValue = 0;
int num1s = 0; //Declaring and initializing the variables to hold how many times a number shows up in a roll.
int num2s = 0;
int num3s = 0;
int num4s = 0;
int num5s = 0;
int num6s = 0; //
srand(static_cast<unsigned int>(time(0)));
cout << "Welcome to Farkle!" << endl
<< endl;
cout << "Please enter the number of players " << endl;
cin >> players;
//Dice diceOne;
//diceOne.currentDiceSide();
//Dice diceTwo;
//diceTwo.currentDiceSide();
//Dice diceThree;
//diceThree.currentDiceSide();
//Dice diceFour;
//diceFour.currentDiceSide();
//Dice diceFive;
//diceFive.currentDiceSide();
//Dice diceSix;
//diceSix.currentDiceSide();
Dice diceOne(w);
< -this is the line that I would like to create with a variable that is modifiable.
You cannot give each Dice object a name, but you can create a Vector of Dice object pointers (vectors are basically resizable arrays), like this:
#include <vector>
#include <iostream>
//...
std::cout << "Please enter the number of players " << std::endl;
std::cin >> players;
// do something to make sure players is an integer
// initialize the empty playerDice vector
std::vector<Dice*> playerDice = {};
for (unsigned i = 0; i < players; ++i) {
playerDice.push_back(new Dice); // this adds a new Dice object pointer to the end of the vector
playerDice.at(i)->currentDiceSide();
}
You have then called the currentDiceSide() function on each Dice object you created, and have neatly organized them in a Vector, which you can access like this:
// say we want to access the third Dice Object,
// Vectors start counting at 0, so we acces the element at Index 2.
playerDice.at(2)->doSomething();
Now because you instantiated those Dice objects with new you have to remember to delete them when you're finished with them, otherwise this will create a memory leak.
//...
// this deletes all the Dice objects in the vector, and points the remaining pointers to null
for (auto d : playerDice) {
delete d;
d = nullptr;
}
Or, better yet, if you're using C++11, you can use std::unique_ptr instead of the raw C-style pointers. Those will prevent you from creating memory leaks, because they will be deleted when they go out of scope. Note you have to #include <memory> to use these.
The vector definition then turns into:
std::vector< std::unique_ptr<Dice> > playerDice = {};
And the creation of the objects would look like this
for (unsigned i = 0; i < players; ++i) {
Dice* temp = new Dice;
temp->currentDiceSide();
std::unique_ptr<Dice> uPtr{ temp };
playerDice.push_back(std::move(uPtr));
}
You can then just clear the vector when you're done with all the objects:
playerDice.clear();
which will delete all the Dice objects that you put into the vector.
Hello I'm having this issue with my C++ problem I'm working on.
Here is the code
Cell.h
#ifndef CELL_H
#define CELL_H
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Cell
{
private:
int level;
int row;
int column;
//declares a variable called ptrFunction_array which is an array of 3 function pointers.
typedef void (*ptrFunction[])(void);
static void function1()
{
cout << "I'm function 1";
}
static void function2()
{
cout << "I'm function 2";
}
static void function3()
{
cout << "I'm function 3";
}
public:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
ptrFunction = new *fArray[3];
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
}
virtual ~Cell();
void tick()
{
int randomNumber = rand() % 3;
cout << "Cell(" << level << ", " << row << ", " << column << ") ";
fArray[randomNumber];
}
};
#endif // CELL_H
Main.cpp
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include "Cell.h"
using namespace std;
Cell ****myArray;
int main()
{
int level = 0;
int row = 0;
int column = 0;
char userInput = 'y';
srand (time(NULL));
do
{
cout << "Please input the amount of levels: ";
cin >> level;
cout << "Please input the amount of rows: ";
cin >> row;
cout << "Please input the amount of columns: ";
cin >> column;
cout << endl;
myArray = new Cell *** [level];
// Set random number to the elements of the array
for (int currentLevel = 0; currentLevel < level; currentLevel++)
{
myArray [currentLevel] = new Cell ** [row];
for (int currentRow = 0; currentRow < row; currentRow++)
{
myArray [currentLevel][currentRow] = new Cell * [column];
for (int currentColumn = 0; currentColumn < column; currentColumn++)
{
myArray [currentLevel][currentRow][currentColumn] = new Cell (currentLevel, currentRow, currentColumn);
myArray [currentLevel][currentRow][currentColumn] -> tick();
cout << " ";
}
cout << endl;
}
cout << endl;
}
cout << "Do you want to try again? (y / n) ";
cin >> userInput;
cout << endl;
if ((userInput == 'y') || (userInput == 'Y'))
{
for (int currentLevel = 0; currentLevel < level; currentLevel++)
{
for (int currentRow = 0; currentRow < row; currentRow++)
{
for (int currentColumn = 0; currentColumn < column; currentColumn++)
{
delete[] myArray[currentLevel][currentRow][currentColumn];
}
delete[] myArray[currentLevel][currentRow];
}
delete[] myArray[currentLevel];
}
delete[] myArray;
myArray = NULL;
}
}while (userInput != 'n');
return 0;
}
I notice that my fArray isn't inside the scope. the Line ptrFunction = new *fArray[3]; is where my error is. I've recently started learning C++ so I'm in the process of trying to understand why my typedef void (*ptrFunction[])(void); isn't correctly initializing the fArrayfor my program. The goal of my program is to be able to create a 3 dimensional array and be able to point to the Cell Objects and be able to track the location x,y,z.
Why does an error like this happen?
I'm going to ignore the four star pointer for now and stick to what's giving OP the most immediate grief.
A quick walk-through:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
Not bad to here. But...
ptrFunction = new *fArray[3];
This says assign to the variable ptrFunction, which must already exist and doesn't, a newly allocated array of 3 fArrays. The problem here is ptrFunction has been defined as a type, not a variable. fArray is not a type.
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
Use fArray as a variable, making what's gone wrong here somewhat clear.
}
Cell needs to look a bit more like this, but not exactly. More on that later.
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
ptrFunction * fArray = new ptrFunction[3];
Now fArray is a variable that points to one or more objects of type ptrFunction (but the definition of ptrFunction is somewhat broken), and points fArray at three ptrFunctions. Technically it points at the first of three ptrFunctions.
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
}
Now we have an fArray, but it is a local variable and it only exists between the curly braces of Cell's constructor. When the constructor exists, the pointer goes away. The memory allocated does not and is lost. Without fArray pointing to it, you can't easily find it to use or delete it. fArray needs wider scope so that A) the memory isn't lost, and B) so that tick and other members of Cell can see it.
class Cell
{
private:
ptrFunction * fArray;
int level;
and in the constructor:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
fArray = new ptrFunction[3];
That fixes the can't find fArray.
My recommendation is to get one Cell working and then take a stab at getting a 1 dimensional array of Cells working. When you have one dimension, then try two. You might find that's all you need.
Edit
Forgot to mention this: Function pointers to members functions are an absolute expletive deleted to get right. Here is a page on common pitfalls and how to avoid them.
And here is how we avoid this smurf in the here and now of Modern C++: std::bind and std::function. The tutorials at the bottom of the linked document pages probably describe how to use them for simple cases better than I can.
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.