2024-09-04 01:01:53 -06:00
|
|
|
/* CSCI 200: Assignment 1 (Rock Paper Scissors): Tyler Beckman
|
|
|
|
*
|
|
|
|
* Author: Tyler Beckman
|
2024-09-19 22:06:16 -06:00
|
|
|
* Resources used:
|
|
|
|
* While learning how to use classes & polymorphism in the way I wanted to,
|
|
|
|
* student Maxwell Gross helped me debug why the way I was trying to use classes
|
|
|
|
* didn't work (virtual fields not existing, where I needed to put class
|
|
|
|
* definitions vs method definitions, etc). No code was copied or written for
|
|
|
|
* me, he just helped me understand how all of these structures I was used to in
|
|
|
|
* other langs like Java and JS worked in cpp :)
|
2024-09-04 01:01:53 -06:00
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* A C++ program to play rock paper scissors (lizard spock) against
|
|
|
|
* randomly-generated computer hands. A hand can be entered to start, and is
|
|
|
|
* then compared against a random one. The game can then be played again until
|
|
|
|
* the user chooses to stop. After each round, statistics are gathered and
|
|
|
|
* displayed after the user chooses to exit the game.
|
|
|
|
*
|
|
|
|
* Note on project structure:
|
|
|
|
* Just for fun and to get ahead on learning cpp, I did create my RPS using
|
|
|
|
* classes, inheritance, and polymorphism. I have experience with this in
|
|
|
|
* multiple other languages, so I felt it would be fun to use this as an excuse
|
|
|
|
* to learn how the concepts work in cpp. I apologize if this is more
|
|
|
|
* complicated than we were supposed to make it, but it was fun and it should
|
2024-09-19 22:06:16 -06:00
|
|
|
* still be a perfectly functional and point-scoring program :). To clarify, I
|
|
|
|
* didn't copy any code but I did use multiple online tutorials and references
|
|
|
|
* to learn how classes and the such work in cpp.
|
2024-09-19 22:09:11 -06:00
|
|
|
*
|
|
|
|
* Edits since first submission:
|
|
|
|
* I passed the mt19937 and uniform distribution variables as arguments by
|
|
|
|
* reference to the generateRandom function, to avoid unnecessary re-creation of
|
|
|
|
* the Mersenne Twister.
|
2024-09-04 01:01:53 -06:00
|
|
|
*/
|
2024-09-01 23:26:25 -06:00
|
|
|
#include "hands.h"
|
|
|
|
|
2024-09-19 22:06:16 -06:00
|
|
|
#include <chrono>
|
2024-09-01 23:26:25 -06:00
|
|
|
#include <iostream>
|
|
|
|
#include <memory>
|
|
|
|
#include <ostream>
|
|
|
|
|
|
|
|
int main(void) {
|
2024-09-19 22:06:16 -06:00
|
|
|
int wins = 0;
|
|
|
|
int losses = 0;
|
|
|
|
int ties = 0;
|
|
|
|
|
|
|
|
std::mt19937 mt(std::chrono::steady_clock::now().time_since_epoch().count());
|
|
|
|
std::uniform_int_distribution<int> intDist(0, 4);
|
2024-09-01 23:26:25 -06:00
|
|
|
|
2024-09-19 22:06:16 -06:00
|
|
|
while (true) {
|
|
|
|
// Take a letter input and convert it to the correct class type for
|
|
|
|
// later use
|
|
|
|
char handLetter;
|
|
|
|
std::cout << "Welcome to a round of [R]ock [P]aper [S]cissors [L]izard "
|
|
|
|
"Sp[O]ck! Please enter "
|
|
|
|
"a hand to play (R/P/S/L/O): ";
|
|
|
|
std::cin >> handLetter;
|
|
|
|
const std::unique_ptr<Hand> userHand = Hand::fromChar(handLetter);
|
2024-09-01 23:26:25 -06:00
|
|
|
|
2024-09-19 22:06:16 -06:00
|
|
|
// Generate a random "computer" hand and display the two choices
|
|
|
|
const std::unique_ptr<Hand> computerHand =
|
|
|
|
Hand::generateRandom(mt, intDist);
|
2024-09-01 23:26:25 -06:00
|
|
|
|
2024-09-19 22:06:16 -06:00
|
|
|
std::cout << std::endl
|
|
|
|
<< "Player chose " << userHand->getHandName() << std::endl
|
|
|
|
<< "Computer chose " << computerHand->getHandName() << std::endl
|
|
|
|
<< std::endl;
|
2024-09-01 23:26:25 -06:00
|
|
|
|
2024-09-19 22:06:16 -06:00
|
|
|
// Compare the two hands, add to statistics, and give the correct output
|
|
|
|
// and explanation
|
|
|
|
switch (userHand->compareAgainst(*computerHand)) {
|
|
|
|
case Win:
|
|
|
|
std::cout << "The player wins, as " << userHand->getHandName()
|
|
|
|
<< " beats " << computerHand->getHandName() << "!"
|
|
|
|
<< std::endl;
|
|
|
|
wins++;
|
|
|
|
break;
|
|
|
|
case Tie:
|
|
|
|
std::cout << "No one wins, as " << userHand->getHandName()
|
|
|
|
<< " is the same as " << computerHand->getHandName() << "."
|
|
|
|
<< std::endl;
|
|
|
|
ties++;
|
|
|
|
break;
|
|
|
|
case Loss:
|
|
|
|
std::cout << "The computer wins, as " << computerHand->getHandName()
|
|
|
|
<< " beats " << userHand->getHandName() << "." << std::endl;
|
|
|
|
losses++;
|
|
|
|
break;
|
|
|
|
}
|
2024-09-01 23:26:25 -06:00
|
|
|
|
2024-09-19 22:06:16 -06:00
|
|
|
// Ask if the user would like to play again or exit
|
|
|
|
char playAgain;
|
|
|
|
std::cout << "Do you want to play again (Y/N)? ";
|
|
|
|
std::cin >> playAgain;
|
|
|
|
switch (playAgain) {
|
|
|
|
case 'Y':
|
|
|
|
case 'y':
|
|
|
|
std::cout << std::endl;
|
|
|
|
continue;
|
|
|
|
case 'N':
|
|
|
|
case 'n':
|
|
|
|
default:
|
|
|
|
std::cout << std::endl
|
|
|
|
<< "Thanks for playing!" << std::endl
|
|
|
|
<< "You won " << wins << " game(s), lost " << losses
|
|
|
|
<< " game(s), and tied " << ties << " time(s)." << std::endl;
|
|
|
|
std::exit(0);
|
|
|
|
}
|
|
|
|
}
|
2024-09-01 23:26:25 -06:00
|
|
|
}
|