I wrote this console rock-paper-scissors game. I'm new to C++. I'd appreciate any suggestions to improve the code below. Thanks.
RPSCore.h
#ifndef RPS_CORE_H
#define RPS_CORE_H
class RPSCore
{
public:
static int rpsWinner(char& playerChoice, char& computerChoice);
static char getComputerChoice();
};
#endif // !RPS_CORE_H
RPSCore.cc
#include <random>
#include <chrono>
#include <cstdint>
#include <map>
#include <sstream>
#include <string>
#include <algorithm>
#include "RPSCore.h"
// private helper function
char getValueIfKeyExists(std::map<std::string, char>& dict, std::string& key)
{
char ret = '\0';
for (std::map<std::string, char>::iterator it = dict.begin(); it != dict.end(); it++)
{
if (it->first.compare(key) == 0)
{
ret = it->second;
break;
}
}
return ret;
}
int RPSCore::rpsWinner(char& playerChoice, char& computerChoice)
{
std::map<std::string, char> rules = { {"rs", 'r'}, {"rp", 'p'}, {"sp", 's'} };
std::stringstream ss;
ss << playerChoice << computerChoice;
std::string combination = ss.str();
std::string combinationCopy{ combination };
std::reverse(combinationCopy.begin(), combinationCopy.end());
char p = getValueIfKeyExists(rules, combination) == '\0' ? getValueIfKeyExists(rules, combinationCopy) : getValueIfKeyExists(rules, combination);
return p == playerChoice && p != computerChoice ? 1 : p == computerChoice && p != playerChoice ? 2 : -1; // 1-> player wins, 2-> computer wins, -1-> draw
}
char RPSCore::getComputerChoice()
{
std::string options = "rps";
uint32_t seed = static_cast<uint32_t>(std::chrono::system_clock::now().time_since_epoch().count());
std::minstd_rand0 range(seed);
std::uniform_int_distribution<std::minstd_rand0::result_type> dist(0, 2);
return options[dist(range)];
}
main.cc
#include <iostream>
#include <string>
#include <cctype>
#include "RPSCore.h"
std::string input(std::string prompt="")
{
std::string temp;
std::cout << prompt;
std::getline(std::cin, temp);
return temp;
}
int main(int argc, char* argv[])
{
char playerChoice = []() {
std::string ret = "";
do
{
ret = input("Your weapon >>> ");
if (std::tolower(ret[0]) == 'r' || std::tolower(ret[0]) == 'p' || std::tolower(ret[0]) == 's') break;
} while (1);
return ret[0];
}();
char computerChoice = RPSCore::getComputerChoice();
int winner = RPSCore::rpsWinner(playerChoice, computerChoice);
std::cout << "Your choice: " << (playerChoice == 'r' ? "Rock" : playerChoice == 'p' ? "Paper" : "Scissors") << " Computer's choice: " << (computerChoice == 'r' ? "Rock" : computerChoice == 'p' ? "Paper" : "Scissors") << " And " << (winner == 1 ? "You WIN!!!" : winner == 2 ? "Computer Wins :(" : "It's a draw :)");
std::cin.get();
return 0;
}