Thread: Stuck

  1. #31
    Registered User major_small's Avatar
    Join Date
    May 2003
    Posts
    2,787
    okay, this is what I came up with - most of my edits are in teh comments... I don't see any problems, but then again I don't know what your problem was... maybe I fixed your error while I was cleaning up your code?

    Code:
    #include <iostream>
    #include <cstdlib>
    #include <string>
    #include <ctime>
    #include <fstream>
    /*
     * Avoid using "using namespace std;", and instead either use
     * the lines below (only the ones you need) or throwing an std::
     * in front of each time you use the word.  I prefer the latter method
     * but for the sake of sanity (mine) I'm doing it this way
     */
    using std::string;
    using std::cout;
    using std::endl;
    using std::cin;
    using std::fstream;
    
    int main()
    {
    	int loan;	//no need to initialize if you're getting it from a file
    	int track;
    	int a;	//wow... nice and descriptive
    	int b;	//again
    	int c;	//and again
    	int d;	//and again
    	int balance;	//see comment on loan
    	int bet = 0;
    	const int min = 2;	//use constant integers when you don't want them to change
    	const int max = 12;	//max... of what?
    	const int min2 = 1;	//again... 
    	const int max2= 4;	//and again...
    	int win;
    	int winnings;
    	string loanloan;
    	string stopch;	//I just used this in your loop instead of creating another var
    	/*
    	 * I'm using an integer and pre-written names in an array to avoid all the
    	 * misspellings/capitilazation problems
    	 */
    	int horse;
    	int winner;
    	string horsenames[]={"Black Beauty","Red Rum","Green Goddess","Silver Speedy"};
    	
    	bool loantrue;	//see comment on line
    
    	/*
    	 * IMO, one of the points of using files is to avoid this kind of thing...
    	 * I used one file, formatted like this:
    	 * 100
    	 * 0
    	 * 0
    	 */
    
    	std::fstream file("test.dat",std::ios::in);
    	file>>balance>>loantrue>>loan;
    	file.close();	//don't forget to close your files
    
    	do
    	{
    		srand(time(0));	//don't use macros
    		//what exactly are you doing here?
    		//track = (rand() % (max2 - min2 + 1) + min);
    		//this is how you get it in a range using variables
    		//I threw it in braces just so I could localize my own
    		//variables
    		{
    			const int min=1;
    			const int max=5;
    			track=(min+rand()%(max+1-min));
    		}
    		switch (track)
    		{
    			case 1:
    				cout<<"Welcome to Aintree, happy betting!\n"<<endl;
    				break;
    			case 2:
    				cout<<"Welcome to Royal Ascot! May luck be on your side!\n"<<endl;
    				break;
    			case 3:
    				cout<<"Welcome to Newmarket, the odds are on your side!\n"<<endl;
    				break;
    			case 4:
    				cout<<"Welcome to Epsom...it's a fine day for some serious betting!\n"<<endl;
    				break;
    			default:
    				cout<<"Welcome to Chepstow...there are some big races today!\n"<<endl;
    				break;
    		}
    
    		a = (rand() % (max - min + 1) + min);
    		b = (rand() % (max - min + 1) + min);
    		c = (rand() % (max - min + 1) + min);
    		d = (rand() % (max - min + 1) + min);
    	
    		cout<<"Your balance is "<<static_cast<char>(156)<<balance<<endl;	//this kind of cast is safer
    		
    		/*
    		 * I took loantrue out of here, because with it in there, if you already
    		 * took out a loan and lost everything, your game goes into an infinite
    		 * loop of sorts - you get to the betting screen, but have no money and 
    		 * therefore can't bet, but you can't get a loan anymore either
    		 */
    		if (balance == 0)
    		{
    			cout<<"Would you like to take a loan? (Y/N): ";
    			getline (cin, loanloan);
    			//cout<<endl;	//no need for this
    			if (loanloan == "Y" || loanloan == "y")
    			{
    				//I didn't see loan initialized, so I just did it here:
    				std::cout<<"Enter the amount of the loan: ";
    				std::cin>>loan;
    				balance += loan;	//admittedly, this was nitpicking
    				cout<<"Your balance is now "<<char(156)<<balance<<endl;
    				loantrue = true;
    			}
    		}
    		cout <<"\nOdds....\n\n"
            	<<"Black Beauty: "<<a<<"/1\n"
    	        <<"Red Rum: "<<b<<"/1\n"
    	        <<"Green Goddess: "<<c<<"/1\n"
    	        <<"Silver Speedy: "<<d<<"/1\n"
    	        <<endl;
    		
    		//changed this to a do-while loop
    		do
    		{
    			cout<<"Please choose your horse:\n"
    				<<" 1. Black Beauty\n"
    				<<" 2. Red Rum\n"
    				<<" 3. Green Goddess\n"
    				<<" 4. Silver Speedy\n"
    				<<"Enter the number next to your choice: ";
    			cin>>horse;
    			cin.ignore(1);
    			horse--;
    			if(horse<0 || horse >3)
    			{
    	        		cout<<"That is not a correct horsename!\n"<<endl;
    				system("cls");
    			}
    		} while(horse<0 || horse > 3);
    	
    		do
    		{
    			cout<<"Please enter the amount you would like to bet on "<<horsenames[horse]<<": "<<char (156);
    			cin>>bet;
    			cin.ignore();
    			
    			/*
    			 * here's a better use of the loop - if the conditions aren't met, print why not
    			 * and let the loop take it's course.  If the conditions are met, it'll break
    			 * itself
    			 */
    			if(bet>balance)
    			{
    				cout<<"You don't have enough money to bet that amount!\n"<<endl;
    			}
    			else if(bet==0)
    			{
    				cout<<"You have to bet something!\n"<<endl;
    			}
    	
    		}while ( bet > balance || bet == 0 );
    	
    		//here I took out your system() call - avoid that
    		cout<<"Please wait while the race takes place...\n"
    			<<"Press [ENTER] to continue"<<std::endl;
    		std::cin.get();
    	
    		/*
    		 * well, this is all fine and good, but you should probalby add some weights
    		 * to each horse if you want to play the odds game
    		 */
    		win = (rand() % (max2 - min2 + 1) + min);
    	
    		switch (win)
    		{
    			case 1:	//black beauty wins
    				winner = 0;	
    				winnings = a * bet;
    				break;
    			case 2:	//red rum wins
    				winner = 1;	
    				winnings = b * bet;
    				break;
    			case 3:	//green goddess wins
    				winner = 2;
    				winnings = c * bet;
    				break;
    			case 4:	//silver speedy wins
    				winner = 3;
    				winnings = d * bet;
    				break;
    		}
    	
    		if (horse == winner)
    		{
    			cout<<"Congratulations, "<<horsenames[horse]<<" won the race!\n\n"
    				<<"You have won "<<char(156)<<winnings;
    			balance += winnings;
    			cout<<"\n\nYour balance is now "<<char(156)<<balance<<'\n'<<std::endl;
    			if (loantrue)	//this is the same as (loantrue == true)
    			{
    				/*
    				 * you were incrementing loan by one then testing to see
    				 * if they had enough to pay off 9 more than loan, and that
    				 * didn't make sense.  I assumed you wanted to add 10 to the
    				 * loan and see if they have enough to pay it off
    				 */
    	                	loan+=10;
    				if(balance >= loan )
    				{
    					balance -= loan;
    					cout<<"You have sucessfully paid off your loan have payed off your loan.'\n'"
    						<<"Your balance is now "<<char(156)<<balance<<endl;
    				}
    			}
    		}
    		else
    		{
    			cout<<"Sorry, "<<horsenames[horse]<<" lost.\n\n";
    			balance -= bet;
    			cout<<"Your balance is now "<<char(156)<<balance<<'\n'<<endl;
    			if (loantrue)
    			{
    				loan+=10;
    				if(balance > loan + 10)
    				{
    					balance -= loan;
    					cout<<"You have sucessfully paid off your loan have payed off your loan.\n\n"
    					<<"Your balance is now "<<char(156)<<balance<<endl;
    				}
    			}
    		}
    
    		/*
    		 * I moved this out here, because it makes more logical sense and cuts down
    		 * on the amount of code
    		 */
    		cout<<"Would you like to play again?(Y/N): ";
    		getline(cin, stopch);
    		if (stopch == "n" || stopch == "N")
    		{
    			//again, I compacted all your files into one
    			fstream file("test.dat",std::ios::out|std::ios::trunc);
    			file<<balance<<'\n'<<loantrue<<'\n'<<loan;
    			file.close();
    			break;
    		}
    		else
    		{
    			bet = 0;
    			system ("CLS");
    		}
    	} while (stopch=="Y"||stopch=="y");
    	return 0;
    }
    and ffs, please use tabs in the code you post to the forums...
    Last edited by major_small; 03-30-2006 at 02:36 AM.
    Join is in our Unofficial Cprog IRC channel
    Server: irc.phoenixradio.org
    Channel: #Tech


    Team Cprog Folding@Home: Team #43476
    Download it Here
    Detailed Stats Here
    More Detailed Stats
    52 Members so far, are YOU a member?
    Current team score: 1223226 (ranked 374 of 45152)

    The CBoard team is doing better than 99.16% of the other teams
    Top 5 Members: Xterria(518175), pianorain(118517), Bennet(64957), JaWiB(55610), alphaoide(44374)

    Last Updated on: Wed, 30 Aug, 2006 @ 2:30 PM EDT

  2. #32
    Registered User
    Join Date
    Nov 2005
    Posts
    545
    Wow...thanks...I made most of the changes but I wanted to keep it as my own code so I just added the most important parts to my code and changed bits that I wanted differently.

    I had a think a few days ago about how to make the odds weighted...and I thought if I could find the lowest highest middle numbers then it would be easy

    Is there a way to do this?

  3. #33
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    My next suggestion would be to learn about functions, so your main isn't 10 nesting levels deep and 500 lines long.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #34
    Registered User
    Join Date
    Nov 2005
    Posts
    545
    Ok...I just want to know how I would find what number is the biggest smalles and ones in teh middle

  5. #35
    Registered User major_small's Avatar
    Join Date
    May 2003
    Posts
    2,787
    Quote Originally Posted by bumfluff
    Ok...I just want to know how I would find what number is the biggest smalles and ones in teh middle
    umm... what?!

    yeah, one way to weight it is to just pick one horse to win more than you pick the others. Theoretically, perfect random numbers should be evenly distributed, so you have to weight them yourself. Here's one way to do it:
    Code:
    #include <iostream>
    #include <iomanip>
    #include <cstdlib>
    #include <ctime>
    
    int main()
    {
    	srand(static_cast<unsigned int>(time(0)));
    	short int randnum;
    	short int l=0,m=0,h=0;
    	double lOff,mOff,hOff;
    	
    	//loop 100 times
    	for(register short int i=0;i<100;i++)
    	{
    		//pick a random number in the range 1..100
    		randnum=1+rand()%100;
    		
    		//this has 20% chance
    		if(randnum<=20)
    		{
    			l++;
    		}
    		//this has 30% chance
    		else if(randnum<=50)
    		{
    			m++;
    		}
    		//this has 50% chance
    		else
    		{
    			h++;
    		}
    	}
    
    	/*
    	 * ignore this part - it just calcuates percent error and outputs
    	 * how far off the machine is from what it should be.  Following the
    	 * laws of probability, these numbers should be close to zero, but
    	 * according to the laws of statistics, there's a very good possibility
    	 * they won't be.
    	 * 
    	 * The formula for percent error:
    	 * 
    	 * accepted-measured
    	 * -----------------  x  100
    	 *     accepted
    	 */
    	lOff=((20-l)/20.0)*100;
    	mOff=((30-m)/30.0)*100;
    	hOff=((50-h)/50.0)*100;
    
    	std::cout<<"20% range was picked "<<l<<" times\n"
    		<<"30% range was picked "<<m<<" times\n"
    		<<"50% range was picked "<<h<<" times\n"
    		<<std::fixed<<std::showpos<<std::setprecision(2)
    		<<"20% range is off by: "<<lOff<<"%\n"
    		<<"30% range is off by: "<<mOff<<"%\n"
    		<<"50% range is off by: "<<hOff<<"%\n"
    		<<"---------------------------\n"
    		<<"On average, there is "<<((lOff+mOff+hOff)/3.0)
    		<<"% error"<<std::endl;
    
    	return 0;
    }
    just mess with the if statements to fix your own odds.
    Join is in our Unofficial Cprog IRC channel
    Server: irc.phoenixradio.org
    Channel: #Tech


    Team Cprog Folding@Home: Team #43476
    Download it Here
    Detailed Stats Here
    More Detailed Stats
    52 Members so far, are YOU a member?
    Current team score: 1223226 (ranked 374 of 45152)

    The CBoard team is doing better than 99.16% of the other teams
    Top 5 Members: Xterria(518175), pianorain(118517), Bennet(64957), JaWiB(55610), alphaoide(44374)

    Last Updated on: Wed, 30 Aug, 2006 @ 2:30 PM EDT

  6. #36
    Registered User
    Join Date
    Nov 2005
    Posts
    545
    How does that work? You see my plan was to find which numbe was the greatest smallest etc and then use a switch case to give the greatest more chances of winning...

  7. #37
    Registered User major_small's Avatar
    Join Date
    May 2003
    Posts
    2,787
    Quote Originally Posted by bumfluff
    You see my plan was to find which numbe was the greatest smallest etc and then use a switch case to give the greatest more chances of winning...
    I have no clue what you're trying to say... If you mean to race the horses several times and see which one wins more, don't bet on it. Theoretically they should all have equal chances - the C++ PRNG isn't perfect, but it isn't bad. If you're just picking random numbers and giving them to random horses... then how would that weight anything? it's just attaching meaningless numbers to meaningless names and casting a false implication to the end users, ultimately fustrating them and wasting their cpu cycles.

    Quote Originally Posted by bumfluff
    How does that work?
    read the comments - it chooses a number between 1 and 100 and breaks that down into three unevenly distributed groups... for example:
    Code:
    If the number is <= 20 (20% of the range)
    horse 1 wins
    If the number is >20 and <=50 (30% of the range)
    horse 2 wins
    If the number is >50 and <=100 (50% of the range)
    horse 3 wins
    with that, you can now say that horse 1 will win 20/100 races, horse 2 will win 30/100 races, and horse 3 will win 50/100 races.

    I really don't know how I could make it any simpler without writing a book on probability... I created ranges that represent a certain percentage of the range, and if the chosen number lands in that range, the horse tied to that range (and therefore that percentage) is chosen as the winner.
    Join is in our Unofficial Cprog IRC channel
    Server: irc.phoenixradio.org
    Channel: #Tech


    Team Cprog Folding@Home: Team #43476
    Download it Here
    Detailed Stats Here
    More Detailed Stats
    52 Members so far, are YOU a member?
    Current team score: 1223226 (ranked 374 of 45152)

    The CBoard team is doing better than 99.16% of the other teams
    Top 5 Members: Xterria(518175), pianorain(118517), Bennet(64957), JaWiB(55610), alphaoide(44374)

    Last Updated on: Wed, 30 Aug, 2006 @ 2:30 PM EDT

  8. #38
    Registered User
    Join Date
    Nov 2005
    Posts
    545
    Well my idea was to find the horse with the best odds...the worst odds...the second best odds an d third best odds. And then choose a random number...then use a switch case statementso if random number is 0-3 then horse with best odds wins...then 4-6 second best wins...7-8 horse with third best odds wins and 9 then worst horse wins

  9. #39
    Registered User major_small's Avatar
    Join Date
    May 2003
    Posts
    2,787
    erm, that's exactly what my code did... except it used a scale of 1...100 and only broke it into 3 groups...

    but you can't say that a horse has certain odds and give it different odds... don't forget, these are all being computed by you.
    Join is in our Unofficial Cprog IRC channel
    Server: irc.phoenixradio.org
    Channel: #Tech


    Team Cprog Folding@Home: Team #43476
    Download it Here
    Detailed Stats Here
    More Detailed Stats
    52 Members so far, are YOU a member?
    Current team score: 1223226 (ranked 374 of 45152)

    The CBoard team is doing better than 99.16% of the other teams
    Top 5 Members: Xterria(518175), pianorain(118517), Bennet(64957), JaWiB(55610), alphaoide(44374)

    Last Updated on: Wed, 30 Aug, 2006 @ 2:30 PM EDT

  10. #40
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Lessons in modularity, based on a previous work by major_small .
    Code:
    #include <iostream>
    #include <cstdlib>
    #include <string>
    #include <ctime>
    #include <fstream>
    
    #define ASIZE(x)  (sizeof(x)/sizeof(x[0]))
    
    using std::string;
    using std::cout;
    using std::endl;
    using std::cin;
    using std::fstream;
    
    void showTrack ( void ) {
      string tracks[] = {
        "Welcome to Aintree, happy betting!",
        "Welcome to Royal Ascot! May luck be on your side!",
        "Welcome to Newmarket, the odds are on your side!",
        "Welcome to Epsom...it's a fine day for some serious betting!",
        "Welcome to Chepstow...there are some big races today!"
      };
      int track = rand() % ASIZE(tracks);
      cout << tracks[track] << endl;
    }
    
    void createOdds( int odds[], int numOdds ) {
      const int min = 2;
      const int max = 12;
      for ( int i = 0 ; i < numOdds ; i++ ) {
        odds[i] = (rand() % (max - min + 1) + min);
      }
    }
    
    void showBalance ( int balance ) {
      cout << "Your balance is "
           << static_cast<char>(156) //this kind of cast is safer
           << balance
           << endl;
    }
    
    bool promptForLoan ( int& balance ) {
      bool   result = false;
      string loanloan;
    
      cout<<"Would you like to take a loan? (Y/N): ";
      getline (cin, loanloan);
      if ( loanloan == "Y" || loanloan == "y" )
      {
        int loan;
        cout<<"Enter the amount of the loan: ";
        cin>>loan;
        cin.ignore(100,'\n');     //!! problems mixing cin and getline
        balance += loan;
        showBalance ( balance );  //!! re-use of a function
        result = true;
      }
      return result;
    }
    
    void displayRunners ( string horses[], int odds[], int numRunners ) {
      cout <<"\nOdds....\n\n";
      for ( int i = 0 ; i < numRunners ; i++ ) {
        cout << horses[i] << " " << odds[i] << ":1" << endl;
      }
    }
    
    int chooseHorse ( string horsenames[], int numRunners ) {
      int horse;
      do {
        cout<<"Please choose your horse:" << endl;
        for ( int i = 0 ; i < numRunners ; i++ ) {
          cout << i+1 << ". " << horsenames[i] << endl;
        }
        cin>>horse;
        cin.ignore(1);
        if ( horse < 1 || horse > numRunners )
        {
          cout<<"That is not a correct horsename!\n"<<endl;
          system("cls");
        }
      } while(horse<0 || horse > 3);
    
      return horse - 1;
    }
    
    int chooseBet ( int balance, string horsename ) {
      int bet;
      do
      {
        cout << "Please enter the amount you would like to bet on "
             << horsename
             << ": "
             << char (156);
        cin>>bet;
        cin.ignore();
    
        if(bet>balance)
        {
          cout<<"You don't have enough money to bet that amount!\n"<<endl;
        }
        else if(bet==0)
        {
          cout<<"You have to bet something!\n"<<endl;
        }
    
      } while ( bet > balance || bet == 0 );
      return bet;
    }
    
    bool checkLoan ( int &loan, int balance ) {
      bool loanOutstanding = true;
      loan += 10;
      if ( balance >= loan )
      {
        balance -= loan;
        loan = 0;
        cout << "You have sucessfully paid off your loan" << endl;
        showBalance ( balance );
        loanOutstanding = false;
      }
      return loanOutstanding;
    }
    
    int main()
    {
      bool loantrue = false;
      int loan = 0;
      int balance = 0;
      int bet = 0;
      int win = 0;
      int winnings = 0;
      string stopch;
      int horse;
      string horsenames[] = {
        "Black Beauty",
        "Red Rum",
        "Green Goddess",
        "Silver Speedy"
      };
      const int numRunners = ASIZE(horsenames);
      int odds[numRunners];
    
      // do this once at program start, not in every loop
      srand(time(0));
    
      std::fstream infile("test.dat",std::ios::in);
      infile>>balance>>loantrue>>loan;
      infile.close(); //don't forget to close your files
    
      do
      {
        showTrack();
        createOdds( odds, ASIZE(odds) );
        showBalance ( balance );
    
        if (balance == 0)
        {
          loantrue = promptForLoan ( balance );
        }
    
        displayRunners ( horsenames, odds, numRunners );
        horse = chooseHorse ( horsenames, numRunners );
        bet = chooseBet ( balance, horsenames[horse] );
    
        cout<<"Please wait while the race takes place...\n"
            <<"Press [ENTER] to continue"<<std::endl;
        std::cin.get();
    
        win = (rand() % numRunners);
        winnings = odds[win] * bet;
    
        if ( horse == win )
        {
          cout << "Congratulations, " << horsenames[horse]
               << " won the race!\n\n"
               << "You have won " << char(156) << winnings;
          balance += winnings;
          showBalance ( balance );
          if ( loantrue )
          {
            loantrue = checkLoan ( loan, balance );
          }
        }
        else
        {
          cout << "Sorry, " <<horsenames[horse]<< " lost.\n\n";
          balance -= bet;
          showBalance ( balance );
          if (loantrue)
          {
            loan += 10;
    
            // you can never pay off the loan on a loss, so there's
            // no point in checking.
            // This bit of the code can be deleted
            //if(balance > loan + 10)
            //{
            // balance -= loan;
            //  cout<<"You have sucessfully paid off your loan have payed off your loan.\n\n"
            //      <<"Your balance is now "<<char(156)<<balance<<endl;
            //}
          }
        }
    
        cout<<"Would you like to play again?(Y/N): ";
        getline(cin, stopch);
        bet = 0;
        system ("CLS");
      } while (stopch=="Y"||stopch=="y");
    
      // moved outside the loop
      fstream outfile("test.dat",std::ios::out|std::ios::trunc);
      outfile<<balance<<'\n'<<loantrue<<'\n'<<loan;
      outfile.close();
    
      return 0;
    }
    How does this help?
    Well for one thing, main is <100 lines long now rather than 250+ (and growing).

    Also, it's a lot easier to add new code, knowing that stuff which is there already is working.

    For example, you might have started out with
    Code:
    void showBalance ( int balance ) {
      cout << "Your balance is "
           << static_cast<char>(156) //this kind of cast is safer
           << balance
           << endl;
    }
    int main ( ) {
      int balance = 123;
      showBalance( balance );
      return 0;
    }
    A pretty trivial example, but a function allows you to test it in isolation. Once you know it works, you can simply cut/paste it to your main program.

    If it doesn't work, then you have a nice simple program to post to the forum, which would be far more appreciated than say dumping 100's of lines of main() code on the forum and asking for "hunt the bug"
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #41
    Registered User
    Join Date
    Nov 2005
    Posts
    545
    My plan is to improve my skills and then re-write the entire code in a better way like the one that you have posted.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 10-23-2006, 07:22 PM
  2. string array stuck:(
    By mass in forum C Programming
    Replies: 18
    Last Post: 05-22-2006, 04:44 PM
  3. Program stuck in infinite loop-->PLEASE HELP
    By Jedijacob in forum C Programming
    Replies: 5
    Last Post: 03-26-2005, 12:40 PM
  4. Stuck on random generating
    By Vegtro in forum C++ Programming
    Replies: 3
    Last Post: 10-01-2003, 07:37 PM
  5. stuck ky
    By JaWiB in forum Tech Board
    Replies: 2
    Last Post: 06-15-2003, 08:28 PM