Rock–paper–scissors console game 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&amp; playerChoice, char&amp; computerChoice);
    static char getComputerChoice();
};

#endif // !RPS_CORE_H


RPSCore.cc

#include &lt;random&gt;
#include &lt;chrono&gt;
#include &lt;cstdint&gt;
#include &lt;map&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;
#include &lt;algorithm&gt;

#include "RPSCore.h"

// private helper function
char getValueIfKeyExists(std::map&lt;std::string, char&gt;&amp; dict, std::string&amp; key)
{
    char ret = '\0';
    for (std::map&lt;std::string, char&gt;::iterator it = dict.begin(); it != dict.end(); it++)
    {
        if (it-&gt;first.compare(key) == 0)
        {
            ret = it-&gt;second;
            break;
        }
    }
    return ret;
}

int RPSCore::rpsWinner(char&amp; playerChoice, char&amp; computerChoice)
{
    std::map&lt;std::string, char&gt; rules = { {"rs", 'r'}, {"rp", 'p'}, {"sp", 's'} };
    std::stringstream ss;
    ss &lt;&lt; playerChoice &lt;&lt; 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 &amp;&amp; p != computerChoice ? 1 : p == computerChoice &amp;&amp; p != playerChoice ? 2 : -1; // 1-&gt; player wins, 2-&gt; computer wins, -1-&gt; draw
}

char RPSCore::getComputerChoice()
{
    std::string options = "rps";
    uint32_t seed = static_cast&lt;uint32_t&gt;(std::chrono::system_clock::now().time_since_epoch().count());
    std::minstd_rand0 range(seed);
    std::uniform_int_distribution&lt;std::minstd_rand0::result_type&gt; dist(0, 2);
    return options[dist(range)];    
}


main.cc

#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;cctype&gt;

#include "RPSCore.h"

std::string input(std::string prompt="")
{
    std::string temp;
    std::cout &lt;&lt; prompt;
    std::getline(std::cin, temp);
    return temp;
}

int main(int argc, char* argv[])
{
    char playerChoice = []() {
        std::string ret = "";
        do
        {
            ret = input("Your weapon &gt;&gt;&gt; ");
            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 &lt;&lt; "Your choice: " &lt;&lt; (playerChoice == 'r' ? "Rock" : playerChoice == 'p' ? "Paper" : "Scissors")  &lt;&lt; " Computer's choice: " &lt;&lt; (computerChoice == 'r' ? "Rock" : computerChoice == 'p' ? "Paper" : "Scissors") &lt;&lt; " And " &lt;&lt; (winner == 1 ? "You WIN!!!" : winner == 2 ? "Computer Wins :(" : "It's a draw :)");
    std::cin.get();
    return 0;
}
I'm thinking you named ret as in short for return.
Don't shorten variable names. Also try to give varaible names that are meaningful. Naming it return because you return it is silly.

char ret = '\0';


Same here:

std::string temp;


This line looks very odd and is a sign of poorly named variables:

ret = it-&gt;second;


r, p s these are a good example of when you should be using an ENUM.

Try to avoid 1 letter variable names.

You can use const when variables should never change. For example: rules.

I suggest putting the condition inside the while instead.
For example:

} while (std::tolower(ret[0]) != 'r' || std::tolower(ret[0]) != 'p' || std::tolower(ret[0]) != 's');


If you had an ENUM, you could check the entered value against all the values in the ENUM. This would look much better, and be easier to maintain. (E.g adding Lizard Spock)

The ENUM would also help for printing the values. (No more if r print rock etc)