Skip to content

Instantly share code, notes, and snippets.

@cppxor2arr
Last active June 23, 2018 15:18
Show Gist options
  • Save cppxor2arr/9641f6afd0f60c0e5f827971195b2d93 to your computer and use it in GitHub Desktop.
Save cppxor2arr/9641f6afd0f60c0e5f827971195b2d93 to your computer and use it in GitHub Desktop.
rock paper scissors
#include <iostream>
#include <utility>
#include <string>
#include <algorithm>
#include <cctype>
#include <map>
#include <random>
#include <chrono>
#include <stdexcept>
enum class Result { win, lose };
enum class Hand { rock, paper, scissors };
using Status = std::pair<Result, Hand>;
bool valid_input(std::string);
Hand str_to_hand(std::string);
std::string hand_to_str(Hand);
Status round(Hand, std::uniform_int_distribution<unsigned short> &, std::mt19937 &);
int main()
{
std::uniform_int_distribution<unsigned short> dist(0, 1);
std::mt19937 gen(std::chrono::high_resolution_clock::now().time_since_epoch().count());
while (true)
{
std::cout << "Input (rock, paper, scissors): " << std::flush;
std::string input;
while (!((std::cin >> input) && valid_input(input)))
{
std::cout << "Invalid input. Again: " << std::flush;
}
const Status status = round(str_to_hand(input), dist, gen);
const std::string result = status.first == Result::win ? "won" : "lost";
const std::string hand = hand_to_str(status.second);
std::cout << "You " << result << '\n'
<< "Computer picked " << hand << '\n';
}
}
bool valid_input(std::string input)
{
std::transform(input.begin(), input.end(), input.begin(), ::tolower);
return input == "rock" || input == "paper" || input == "scissors";
}
Hand str_to_hand(std::string str)
{
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
if (str == "rock")
{
return Hand::rock;
}
if (str == "paper")
{
return Hand::paper;
}
if (str == "scissors")
{
return Hand::scissors;
}
throw std::invalid_argument("rock, paper, scissors");
}
std::string hand_to_str(Hand hand)
{
if (hand == Hand::rock)
{
return "rock";
}
if (hand == Hand::paper)
{
return "paper";
}
if (hand == Hand::scissors)
{
return "scissors";
}
}
Status round(Hand hand, std::uniform_int_distribution<unsigned short> &dist, std::mt19937 &gen)
{
Result result = static_cast<bool>(dist(gen)) ? Result::win : Result::lose;
static std::map<Status, Hand> outcome
{
{Status(Result::win, Hand::rock), Hand::scissors},
{Status(Result::win, Hand::paper), Hand::rock},
{Status(Result::win, Hand::scissors), Hand::paper},
{Status(Result::lose, Hand::rock), Hand::paper},
{Status(Result::lose, Hand::paper), Hand::scissors},
{Status(Result::lose, Hand::scissors), Hand::rock}
};
return Status(result, outcome[Status(result, hand)]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment