I'm creating a dice game. I'm building the files but get the following error:
No matching function for call to Dice::Dice
main.cpp:
#include "Dice.h"
#include <iostream>
using namespace std;
int main (){
Dice d(1,6);
cout << d.getRoll() << endl;
return 0;
}
Dice.h:
#ifndef DICE_H
#define DICE_H
class Dice
{
public:
Dice();
void getRoll(int m, int n);
};
#endif
Dice.cpp:
#include "Dice.h"
#include <ctime>
#include <iostream>
using namespace std;
Dice::Dice()
{}
void Dice::getRoll(int m, int n) {
srand(time(0));
(rand() % n)+m;
}
I see several problems with the code. Here's are my fixes and tips:
Firstly, your construction and method call of Dice will not compile:
Dice d(1,6); // you give arguments to the constructor
cout << d.getRoll() << endl; // your method call has no arguments
But you defined:
Dice(); // constructor takes no arguments
void getRoll(int m, int n); // method takes arguments
Secondly, srand only needs to be done once, not every time you call roll – maybe in the main function:
srand( (unsigned)time( NULL ) );
This seeds the generator so that you should get different random numbers every time the program runs. Call it only once, before the first dice roll.
Thirdly, your getRoll function returns nothing, meaning you get no value back. And you should name your variables according to what idea they represent in reality or your specification:
int Dice::getRoll(int maxEyes) { // Still no good abstraction
(rand() % maxEyes) + 1;
}
A real dice does not change its maxEyes at runtime. Why not try some object orientation instead of a function library class. Think about a real dice object! Here's a dice abstraction to start with:
main.cpp
#include "Dice.h"
#include <iostream>
using namespace std;
int main()
{
Dice::randomize(); // Try commenting this out and run the program several times, check the result, then comment it back in
Dice diceWith6Sides(6);
cout << "The 6 sided dice rolls a " << diceWith6Sides.getRoll() << endl;
cout << "The 6 sided dice rolls a " << diceWith6Sides.getRoll() << endl;
cout << "The 6 sided dice rolls a " << diceWith6Sides.getRoll() << endl;
Dice diceWith20Sides(20);
cout << "The 20 sided dice rolls a " << diceWith20Sides.getRoll() << endl;
cout << "The 20 sided dice rolls a " << diceWith20Sides.getRoll() << endl;
cout << "The 20 sided dice rolls a " << diceWith20Sides.getRoll() << endl;
return 0;
}
Dice.h
#ifndef DICE_H
#define DICE_H
class Dice
{
public:
Dice(int sides);
int getRoll();
static void randomize(); // Call only once
private:
int sides;
};
#endif
Dice.cpp
#include "Dice.h"
#include <time.h>
#include <stdlib.h>
Dice::Dice(int sides) :
sides(sides)
{
}
int Dice::getRoll()
{
return ((rand() % sides) + 1);
}
void Dice::randomize()
{
srand((unsigned)time(NULL));
}
Hope that is a good starting point. Have a lot of fun!
Related
I have this batting average program. My problem is that I cannot output this program using input/output files so that it shows the highest/lowest averages and the names to go with them. The code I have in main is not right because it is only outputting "Highest batting average is: 0" and "Players with the highest batting average: " None of the averages are 0 so it should not be outputting that, and there should be a name next to the highest batting average. The same goes with the lowest. This is what I have so far:
#include "Player.h"
#include "Stack.h"
#include <fstream>
using namespace std;
int main()
{
Player x;
string name;
double avg;
ifstream infile("avgs.txt");
while (infile >> name >> avg)
{
x.insertPlayer(name, avg);
}
infile.close();
x.printHigh();
x.printLow();
if(!infile)
{
cout << "Unable to open the file for writing " << endl;
exit(0);
}
ofstream outfile("avgs.txt");
if (!outfile)
{
cout << "Error opening file " << endl;
exit(0);
}
outfile << endl;
}
Here are the files to the Player class, and the Stack class in case it is needed aswell:
////Player.h
#include "stdafx.h"
#include <iostream>
#include <string>
#include "Stack.h"
using std::string;
class Player
{
public:
double lowest;
double highest;
Stack<string> low;
Stack <string> high;
void insertPlayer(string name, double batAvg);
void printHigh();
void printLow();
};
This is the .cpp file for the Player class:
#include "stdafx.h"
#include <iostream>
#include <string>
#include "Player.h"
using namespace std;
using std::string;
void Player::insertPlayer(string name, double batAvg)
{
cout << "Player " << name << " has an average of: " << batAvg << endl;
if (low.empty() && high.empty())
{
low.push(name);
high.push(name);
highest = lowest = batAvg;
}
else
{
if (batAvg>highest)
{
while (!high.empty())
high.pop();
highest = batAvg;
high.push(name);
}
else if (batAvg == highest)
high.push(name);
else if (batAvg<lowest)
{
while (!low.empty())
low.pop();
lowest = batAvg;
low.push(name);
}
else if (batAvg == lowest)
low.push(name);
}
}
void Player::printHigh()
{
cout << "Highest batting average is: " << highest << endl;
cout << "Players with the highest batting average: " << endl;
}
void Player::printLow()
{
cout << "Lowest batting average is: " << lowest << endl;
cout << "Players with the lowest batting average: " << endl;
}
And my Stack class if it is needed:
#ifndef STACK
#define STACK
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
template <class T>
class Stack : public exception
{
private:
vector<T>myStacks;
public:
void push(T const& uStack);
void pop();
T peek() const;
bool empty() const
{
return myStacks.empty();
}
};
template <class T>
void Stack<T>::push(T const& uStack)
{
myStacks.push_back(uStack);
}
template <class T>
void Stack<T>::pop()
{
if (myStacks.empty())
{
throw std::out_of_range("Stack <>::pop(): This is an empty stack ");
}
myStacks.pop_back();
}
template <class T>
T Stack<T>::peek() const
{
if (myStacks.empty())
{
throw std::out_of_range("Stack<>::peek(): This is an empty stack ");
}
return myStacks.back();
}
#endif
The focus code that I am trying to output is Player.cpp, but the Stack.h and Player.h are needed to make it run. In main() I need to output the names, averages, and the people with the highest/lowest averages. Any help is appreciated!
The text file consists of players and their averages, for example:
Orlando .775
Charles .606
J.D. .775
Gina .400
Sam .702
Rich .686
and so on.
The first thing you want to do is remove everything after x.printLow(); in main, then verify that the expected input is present in avgs.txt.
Your code will overwrite the input file with a single newline, so if you have tried it once, you probably haven't got the input you expect anymore. Notice how you never see output from cout << "Player " << name << " has an average of: " << batAvg << endl;. That indicates insertPlayer is not being called.
I'm pretty sure it is a problem with finding your input file, as it works with a different input source. Is the file with the text in the same folder as your .exe? Is it instead in a different folder, such as where the source files are?
A simple test would be to just copy the contents of the file to cout, to see what the program finds
int main() {
std::ifstream infile("avgs.txt");
for (std::string line; std::getline(infile, line;) {
std::cout << line << std::endl;
}
}
I just have a simple program where dice.cpp and dice.h run through game.cpp to as of now just compute the sum of two dice rolls.
When I try to run the program apparently I am redefining the Dice class, that is what my error is telling me.
Here are my three files.
game.cpp
#include "Dice.h"
#include <iostream>
using namespace std;
int main()
{ int sum;
Dice dice1;
Dice dice2;
dice1.roll();
dice2.roll();
sum = dice1.getFace() + dice2.getFace();
cout << sum;
return 0;
}
dice.cpp
#ifndef DICE_H
#define DICE_H
#include "Dice.h"
using namespace std;
// g++ -c Dice.cpp
// default constructor: initializes the face of a new
// Dice object to 1
Dice::Dice()
{
//cout << "Default constructor " << endl;
face = 1; // not redeclaring the data member face
}
// specific constructor: initializes the face of a new
// Dice object to newFace
// Pre-condition: newFace is a valid number
// call setFace function inside Dice(int newFace)
Dice::Dice(int newFace)
{
//cout << "Specific constructor " << endl;
setFace(newFace);
}
// Sets face to the value in otherFace
// Pre-condition: otherFace is valid
void Dice::setFace(int otherFace)
{
assert(otherFace >= 1 && otherFace <= 6);
face = otherFace;
}
// Changes the value of face to a random value between 1 and 6
void Dice::roll()
{
face = rand()%6 +1;
}
// returns the face value of a Dice object
int Dice::getFace() const
{
return face;
}
// displays the face value of a Dice object
void Dice::display() const
{
cout << "This dice has " << face << " on top" << endl;
}
#endif
Dice.h
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <ctime>
// definition of class Dice
class Dice
{
private:
int face; // can only take values between 1 and 6
public:
// default constructor: initializes the face of a new
// Dice object to 1
Dice();
// specific constructor: initializes the face of a new
// Dice object to newFace
// Pre-condition: newFace is a valid number
// call setFace function inside Dice(int newFace)
Dice(int newFace);
// Sets face to the value in otherFace
// Pre-condition: otherFace is valid
void setFace(int otherFace);
// Changes the value of face to a random value between 1 and 6
void roll();
// returns the face value of a Dice object
int getFace() const;
// displays the face value of a Dice object
void display() const;
};
HERE IS A PHOTO OF THE ERROR
In "dice.cpp" file, remove the third line which says "#include "dice.h".
You are already defining the dice class and hence you don't need the #include statement
The code you show is lying. The error seems to say that game.cpp includes Dice.h, and that Dice.h includes Dice.cpp, which includes Dice.h. So your Dice.h header file is included twice, and with no header include guards in the header file the class will be defined twice.
Simple solution? Don't include the source file. You should still have header include guards in the header file though.
This question already has answers here:
Problems importing libraries to my c++ project, how to fix this?
(2 answers)
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I'm trying to create a classes in separate files using codeblocks. I get the error in function '_start' undefined reference to 'main'. I'm sure its a linkage problem but can't see where. In my program I’m trying to get a die, let the user decide how many sides the dice has, then roll the die a user specified amount of times.
die.h file///////////////////////////////////
#include <iostream>
#include <string>
#ifndef DIE_H
#define DIE_H
using namespace std;
class die{
public:
die();//function prototype
int numsides;//member
void setNumsides(int numsides_);//setter
int getNumsides();// getter for size of dice
int value;
void setValue(int value_, int numsides_);
int getValue();
int roll;
void setroll(int roll_);
int getroll();
};
#endif// DIE_H
die.cpp//////////////////////////////////////////
#include "die.h"
#include <iostream>
#include <string>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
using namespace std;
die::die()
{
//ctor
}
void die::setroll(int roll_)
{
roll=roll_;
}
int die::getroll()//amount o rolls
{
cout << "enter the ammont of rolls you would like" << endl;
cin >> roll;//amount of rolls you want
return roll;
}
void die::setValue(int value_, int numsides_)
{
value=value_;
numsides=numsides_;
}
int die::getValue()//get value function
{
//int roll;
value = (rand() % numsides) + 1;//sets roll value
return value;
}
void die::setNumsides(int numsides_)
{
numsides=numsides_;
}
int die::getNumsides()//get num of sides
{
cout << "how big of a dice would you like to roll " << endl;
cin >> numsides;//use this to determine dice
if(numsides < 4){//if dice is less than 4
cout << "Error has to be bigger than " << numsides << endl;
numsides = 6;//change to six sided dice
}
return numsides;
}
exercise1.cpp my main class/////////////////////////////////////
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <time.h>
#include "die.h"
using namespace std;
int main()
{
die mydice;//create an object dice
mydice.getNumsides();//gets sides of dice
mydice.getValue();//gets amount of rolls
mydice.getroll();//rolls the dice value times
return 0;
}
I am still new to c++ and just started to learn about classes and OOP. I have been practicing trying to make classes out of any item I can think of, so I made a phone class. Code is below. The problem is no matter what number I give it, it displays the same WRONG number everytime. The crazy thing is in the beginning I had given the phone class a variable to store its own number and gave the class instance its own number. That number is the number it keeps wanting to "call". Even after going back several times and making sure I wasn't calling the wring variable I completely deleted the variable and the code still displays the same number. The number is 214-748-3647. Makes me feel like my computer is haunted. Could anyone help?
CODE DOESN'T ACTUALLY MAKE ANY SORT OF PHONE CALL OR ANY CONNECTION WHAT SO EVER
PHONE CLASS HEADER
#ifndef PHONE_H_INCLUDED
#define PHONE_H_INCLUDED
#include <string>
using namespace std;
class Phone{
public:
string Brand;
int Serial;
string CellId;
void Call();
private:
void Dial(int NumberToDial);
void EndCall();
};
#endif // PHONE_H_INCLUDED
PHONE SOURCE CODE
#include <iostream>
#include <string>
#include <sstream>
#include "phone.h"
using namespace std;
void Phone::Call(){
string UserInput = "0";
int NumberToCall = 0;
cout << "What number would you like to call?" << endl << endl;
getline(cin, UserInput);
if(UserInput.length() != 10){
cout << endl << "invalid digits" << endl;
Call();
}
else{
stringstream(UserInput) >> NumberToCall;
Dial(NumberToCall);
}
}
void Phone::Dial(int NumberToDial = 0){
ostringstream converter;
string Number;
converter << NumberToDial;
Number = converter.str();
cout << "Dialing ";
for(int i=0;i<10;i++){
cout << Number[i];
if(i==2){
cout << "-";
}
if(i==5){
cout << "-";
}
}
cout << endl << endl << "Press any key to end the call..." << endl << endl;
cin.get();
EndCall();
}
void Phone::EndCall(){
cout << "Call ended." << endl << endl;
}
Aaaaannnnd my MAIN
#include <iostream>
#include <cstdlib>
#include "phone.h"
using namespace std;
int main()
{
Phone MyPhone;
MyPhone.Brand = "iPhone 5";
MyPhone.CellId = "F2D9G3A2";
MyPhone.Serial = 1411512;
MyPhone.Call();
return 0;
}
This is a very simple answer. You're code and logic is fine. The error occurs because you convert the std::string which holds the phone number to an integer. This is a problem because a typical 10 digit phone number is too big to fit inside the int type. Have a look here to see the min and max numbers you can fit in different types: http://www.cplusplus.com/reference/climits/
Look at this line here actually.
Maximum value for an object of type long int: 2147483647 (231-1) or greater
Funny how the max value is that mysterious phone number.
I am making a hot potato game that deals with inheritance. I have a potato class, player class and umpire class.
In calling the toss function within my umpire class I KEEP getting this same error and I can't seem to figure out why: terminate called throwing an exceptionAbort trap: 6
I went through and found that within umpire::start(), the call to Players.at(randU)->toss(*m) in my for loop is making this error come up. But everything looks fine to me.
Can anyone help me out? Thanks!
Umpire.cc
#include <iostream>
#include <string>
#include "potato.h"
#include "player.h"
#include "umpire.h"
#include "PRNG.h"
using namespace std;
// Declare globally
int gamecount=1;
// GLOBAL VARIABLES
bool first=false; // False if set has not started
PRNG rplayer;
// UMPIRE CONSTRUCTOR-------------------------------------------------------------------
Umpire::Umpire( Player::PlayerList &players ){
Players=players;
cout<<"\tMashed POTATO will go off after ";
cout.flush();
m=new Mashed(Players.size()-1);
cout << " tosses" << endl;
cout.flush();
cout <<"\tFried POTATO will go off after 5 tosses" << endl;
cout.flush();
f=new Fried(5);}
// UMPIRE DESTRUCTOR-------------------------------------------------------------------
Umpire::~Umpire(){
delete m;
delete f;}
// UMPIRE START------------------------------------------------------------------------
void Umpire::start(){
int randU;
int gameCount=1; // Keeps track of sets
// Check if you are at the end of the list.
if(Players.size()==1){
// Who won?
cout << Players.at(0)->getId() << "wins the Match!" << endl;
cout.flush();}
else{
// Print output for sets----------------------------------------------------------------
// See which potato is being used in the set
if(gameCount%2!=0){
cout << "Set " << gameCount << "-\tUser (mashed) [";
cout.flush();}
else{
cout << "Set " << gameCount << "-\tUser (fried) [";
cout.flush();}
gameCount++; // increase gamecount
// Outputting players left in the set
for(unsigned int i=0;i<Players.size();i++){
cout<<Players.at(i)->getId();}
cout <<"]: ";
cout.flush();
//Start Tossing--------------------------------------------------------------------------
randU=rplayer(Players.size()-1);
// Output A(id) or R(id)
if (randU%2==0){
cout<<"A("<<randU<<"), ";
cout.flush();}
else{
cout<<"R("<<randU<<"), ";
cout.flush();}
if(first==false){
for(unsigned int i=0; i<Players.size(); i++){
if(Players.at(i)->getId()==Players.at(randU)->toss(*m)){
Players.erase(Players.begin()+i);
cout << "Eliminated: "<< i << endl;
cout.flush();}
}
first=true;
f->reset();
start();
}
else{
for(unsigned int i=0; i<Players.size(); i++){
if(Players.at(i)->getId()==Players.at(randU)->toss(*f)){
Players.erase(Players.begin()+i);
cout << "Eliminated: "<< i << endl;
cout.flush();}
}
first=false;
m->reset();
start();
}
}
}
Player.cc
#include <iostream>
#include "player.h"
#include "potato.h"
#include "PRNG.h"
using namespace std;
// GLOBAL DECLARATIONS--------------------------------------------------------------------
PRNG randP;
// PLAYER CONSTRUCTOR---------------------------------------------------------------------
Player::Player(unsigned int id, Player::PlayerList &players){
pid=id;
Players=players;
lrpFLAG=false;}
// getId() returns the player's id--------------------------------------------------------
unsigned int Player::getId(){
return pid;}
// RNPlayer Constructor-------------------------------------------------------------------
RNPlayer::RNPlayer( unsigned int id, Player::PlayerList &players ) : Player(id,players){}
// TOSS FUNCTION--------------------------------------------------------------------------
unsigned int RNPlayer::toss( Potato &potato ){
unsigned int randnum;
if(potato.countdown()){ return getId(); }
for(;;){
randnum=randP(Players.size()-1);
if (randnum%2==0){
cout<<"A("<<randnum<<"), ";
cout.flush();}
else{
cout<<"R("<<randnum<<"), ";
cout.flush();}
// If our randomly selected player is not the current player...
if(Players.at(randnum)->getId()!=getId()){
break;}
}
return Players.at(randnum)->toss(potato);
}
// LRPlayer Constructor-------------------------------------------------------------------
LRPlayer::LRPlayer( unsigned int id, Player::PlayerList &players ) : Player(id,players){}
// TOSS FUNCTION
unsigned int LRPlayer::toss( Potato &potato ){
unsigned int current; // current player
// Find who our current player is
for(unsigned int i=0; i<Players.size(); i++){
if(Players.at(i)->getId()==getId()){
current=i;
cout<<"A("<<i<<"), ";}
}
// if timer hasn't gone off yet...
if(potato.countdown()!=true){
// if this is the FIRST toss, we want to toss left
if(lrpFLAG==false){
if(current==0){
lrpFLAG=true;
(Players.at(Players.size()-1))->toss(potato);}
else{
lrpFLAG=true;
(Players.at(current-1))->toss(potato);}
}
else{
if(current==Players.size()-1){
lrpFLAG=false;
(Players.at(0))->toss(potato);}
else{
lrpFLAG=false;
(Players.at(current+1))->toss(potato);}
}
}
return (Players.at(current))->getId();
}
Main.cc
#include <iostream>
#include <vector>
#include <time.h>
#include "potato.h"
#include "player.h"
#include "umpire.h"
#include "PRNG.h"
using namespace std;
int main(int argc, char *argv[] ){
int p = 5;
int tmp;
unsigned int s;
PRNG prng1;
prng1.seed(1234567890);
// Parse the command line arguments
switch ( argc ) {
case 3:
tmp=atoi(argv[1]);
s=atoi(argv[2]);
prng1.seed(s);
if(tmp<2 || tmp>20){
cout << "Player must be between 2 and 20 inclusive" << endl;
return 0;}
else{
p = atoi(argv[1]);}
}
// Creating list of players.
Player::PlayerList players;
for(int i=0; i<p; i++){
if(i%2==0){
players.push_back(new LRPlayer(i,players));}
else{
players.push_back(new RNPlayer(i,players));}
}
//for (int i=0;i<players.size();i++){
// cout << "Player at " << i << " id: " << players.at(i)->getId() << endl;}
// How many players?----------------------------------------------------------------------
cout << p << " players in the match" << endl;
// Construct an UMPIRE--------------------------------------------------------------------
Umpire u(players);
// Start the game!------------------------------------------------------------------------
u.start();
}
Also note: PRNG.h is a class that generates a random number. so PRNG prng1; int rand=prng1(#) generates a random number between 0 and #.
ALSO:
The problem is occurring when i call my toss function. I'm not out of range because when i try to call Players.at(randU)->getID() i don't get any errors at all. Could it be that i can't reach the toss function for that player?I'm thinking it has to do with something im pointing to or memory. I first make a PlayerList players in my main.cc and push_back players alternating between the two. But each player also takes in a list. Maybe I'm running into errors involved with this?
Thanks! Any help is much appreciated :)
The exception thrown must be std::out_of_range. The random number you are generating must be higher than the number of elements in the vector.
randU must be re-generated after Players.erase() is called. Otherwise it will go out of range.
Or you should break the loop as:
for(unsigned int i=0; i<Players.size(); i++){
if(Players.at(i)->getId()==Players.at(randU)->toss(*f)){
Players.erase(Players.begin()+i);
cout << "Eliminated: "<< i << endl;
cout.flush();
break; // BREAK HERE as randU now can be greater than (Players.size() - 1)
}
}