Help with functions

Hi,

Is there another way for me to properly terminate my rock, paper, scissors program other than using exit(1) in my int calculateWinner function? I tried return 0; but it won't work and I'm hesitant to use the exit because I know it is not considered "proper".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;


int menuChoice();
int generateComputerChoice();
int calculateWinner(int, int);

int main () {
bool x = true;
while (x) {
int playerChoice = menuChoice();
int computerChoice = generateComputerChoice();
int winnerIs = calculateWinner(playerChoice, computerChoice);
}
}





int menuChoice (){

int playerChoice;

do {
cout << " Please select 1-4 based on your choice of action." << endl;
cout << " 1) Rock " << endl;
cout << " 2) Paper " << endl;
cout << " 3) Scissors " << endl;
cout << " 4) Quit " << endl ;
cin >> playerChoice;
} while (playerChoice < 1 && playerChoice > 4);
if (playerChoice == 1){
    return 1;
}
else if (playerChoice == 2){
    return 2;
}
else if (playerChoice == 3){
    return 3;
}
else if (playerChoice == 4){
return 4;
}
else {
    cout << "The entered value " << playerChoice << " is not recognized. " <<endl;
    return menuChoice ();
}

}

int generateComputerChoice () {
srand(time(0));
int computerChoice;

computerChoice = rand()%3+1;

if (computerChoice == 1){
    return 1;
}
else if (computerChoice == 2){
    return 2;
}
else {
    return 3;
}
}

int calculateWinner (int playerChoice, int computerChoice) {
static int wins, loses, ties;

    if(playerChoice == 4){
        cout << "Thanks for playing the game." << endl;
        exit (1);
         }
    else if(playerChoice == computerChoice){
        cout << "It's a tie! You and the computer chose the same thing." << endl << endl;
         ++ties;
     }
    else if(playerChoice == 1 && computerChoice == 3) {
        cout << "You win! You chose rock and the computer choose scissors." << endl << endl;
        ++wins;
        }
    else if(playerChoice == 1 && computerChoice == 2) {
        cout << "You lose! You chose rock and the computer choose paper." << endl << endl;
        ++loses;
        }
    else if(playerChoice == 2 && computerChoice == 3) {
        cout << "You lose! You chose paper and the computer choose scissors." << endl << endl;
        ++loses;
        }
    else if(playerChoice == 2 && computerChoice == 1) {
        cout << "You win! You chose paper and the computer choose rock." << endl << endl;
       ++wins;
        }
    else if(playerChoice == 3 && computerChoice == 1) {
        cout << "You lose! You chose scissors and the computer choose rock." << endl << endl;
        ++loses;
        }
    else if(playerChoice == 3 && computerChoice == 2) {
        cout << "You win! You chose scissors and the computer choose paper."<< endl << endl;
        ++wins;
        }
cout << "wins = " << wins << " loses = " << loses << " ties = " << ties << endl << endl;
}
If you don't have data that you need to return then why make it a value returning function? Why not just make it a void function?
my teacher gave us the function prototypes. I can't change them. I'm just looking for a proper way to terminate my program without using the exit(1) in line 78.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <cstdlib>
#include <ctime>

constexpr int ROCK = 1 ;
constexpr int PAPER = 2 ;
constexpr int SCISSORS = 3 ;
constexpr int QUIT = 4 ;
const char* const names[] = { "not used", "Rock", "Paper", "Scissors", "Quit" } ;


int menuChoice();
int generateComputerChoice();
int calculateWinner(int, int);

int main () {

    std::srand( std::time(nullptr) ); // seed the rng once, in the beginning

    int playerChoice ;

    while( ( playerChoice = menuChoice() ) != QUIT ) {

        // returned value is ignored
        calculateWinner( playerChoice, generateComputerChoice() );
    }

    std::cout << "Thanks for playing the game.\n" ;
}

int menuChoice () {

    std::cout << "\nPlease select " << ROCK << '-' << QUIT
              << " based on your choice of action.\n" ;

    for( int i = ROCK ; i <= QUIT ; ++i ) std::cout << i << ") " << names[i] << '\n' ;

    int choice ;
    if( std::cin >> choice )
    {
        if( choice >= ROCK && choice <= QUIT ) return choice ;
        else std::cout << "The entered value " << choice << " is not recognized.\n" ;
    }

    else
    {
        std::cout << "please enter a number\n" ;
        std::cin.clear() ; // non-numeric input; clear the failed stated of std::cin
        std::cin.ignore( 1000, '\n' ) ; // discard the current input line
    }

    return menuChoice();
}

int generateComputerChoice () {

    return std::rand() % SCISSORS + ROCK ;
}

// invariant: valid playerChoice, computerChoice (in the range ROCK-SCISSORS)
int calculateWinner( int playerChoice, int computerChoice ) {

    static int wins = 0, loses = 0, ties = 0 ;

    if( playerChoice == computerChoice ) {

        std::cout << "It's a tie! You and the computer chose "
                  << names[playerChoice] << ".\n\n" ;
         ++ties;
    }

    else
    {
        const int cookie = playerChoice * 10 + computerChoice ;
        const bool player_wins = cookie == 13 || cookie == 21 || cookie == 32 ;

        if(player_wins) { ++wins ; std::cout << "You win! " ; }
        else { ++loses ; std::cout << "You lose! " ; }

        std::cout << "You chose " << names[playerChoice]
                  << " and the computer chose " << names[computerChoice] << "\n\n"
                  << "wins = " << wins << " loses = " << loses << " ties = " << ties << "\n\n" ;
    }

    return 0 ; // return value is not used
}
Last edited on
As far as possible, a C++ program should avoid calling std::exit().

exit() is C-aware and works well in C programs (for instance it flushes and closes all C streams). The fundamental problem with std::exit() in C++ is that it does not perform clean up of objects with automatic storage duration.

Terminating the program without leaving the current block (e.g., by calling the function std::exit(int)) does not destroy any objects with automatic storage duration. If std::exit is called to end a program during the destruction of an object with static or thread storage duration, the program has undefined behavior.
Why is it not proper?
Because it introduces a hidden control path that bypasses stack unwinding.

Calling std::exit is almost never a good idea. This is because std::exit() does not destroy objects with automatic storage duration. That means unavoidable resource leaks can occur even cross-module or in otherwise exception-safe, RAII-enabled code.

std::exit() is closely related to std::abort(). The functions quick_exit(), abort(), terminate(), exit(), etc., are all there so you can crash your program in the most appropriate manner, but usually you don't want to crash at all. If you have an error that requires that the program ends, consider throwing an exception instead. Even if you don't catch it, at least your destructors will run.

Edit:
Ah, sorry for the duplicate information -- I didn't see JLBorges' post.
Last edited on
Topic archived. No new replies allowed.