#include <array>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <stdexcept>
#include <string>
#include <utility>
enum Weapon { ROCK=1, PAPER, SCISSORS, LIZARD, SPOCK };
enum Outcome { WIN, LOSE, DRAW };
const Weapon rock = static_cast<Weapon>(ROCK);
const Weapon paper = static_cast<Weapon>(PAPER);
const Weapon scissors = static_cast<Weapon>(SCISSORS);
const Weapon lizard = static_cast<Weapon>(LIZARD);
const Weapon spock = static_cast<Weapon>(SPOCK);
typedef std::pair<Weapon, Weapon> PlayerMoves;
std::string toString(Weapon const& weapon)
{
switch (weapon)
{
case ROCK: return "rock";
case PAPER: return "paper";
case SCISSORS: return "scissors";
case LIZARD: return "lizard";
case SPOCK: return "spock";
default: throw std::logic_error("invalid weapon");
}
}
Weapon getPlayerWeapon()
{
int weapon;
std::cout << "\n\n(1) -> Rock\n";
std::cout << "(2) -> Paper\n";
std::cout << "(3) -> Scissors\n";
std::cout << "(4) -> Lizard\n";
std::cout << "(5) -> Spock\n\n";
std::cout << "Your move: ";
/*do
{
std::cin >> weapon;
} while (weapon < 1 || weapon > 5);*/
weapon = 1;
return static_cast<Weapon>(weapon);
}
Weapon getOpponentWeapon()
{
return static_cast<Weapon>(1 + std::rand() % 5);
}
Outcome determineOutcome(Weapon const& player, Weapon const& opponent)
{
// scissors cuts paper,
// paper covers rock,
// rock crushes lizard,
// lizard poisons Spock,
// Spock smashes scissors,
// scissors decapitate lizard,
// lizard eats paper,
// paper disproves Spock,
// Spock vaporizes rock.
// rock crushes scissors.
PlayerMoves playerMoves = std::make_pair(player, opponent);
/*Weapon rock = static_cast<Weapon>(ROCK);
Weapon paper = static_cast<Weapon>(PAPER);
Weapon scissors = static_cast<Weapon>(SCISSORS);
Weapon lizard = static_cast<Weapon>(LIZARD);
Weapon spock = static_cast<Weapon>(SPOCK);*/
std::array<PlayerMoves, 10> possibleMoves =
{ std::make_pair(scissors, paper),
std::make_pair(paper, rock),
std::make_pair(rock, lizard),
std::make_pair(lizard, spock),
std::make_pair(spock, scissors),
std::make_pair(scissors, lizard),
std::make_pair(lizard, paper),
std::make_pair(paper, spock),
std::make_pair(spock, rock),
std::make_pair(rock, scissors)
};
// if round moves match any of the above, player loses round
for (auto iter = possibleMoves.cbegin(); iter != possibleMoves.cend(); ++iter)
{
if (playerMoves == *iter)
return LOSE;
}
// both moves are the same
if (player == opponent)
return DRAW;
// player wins
return WIN;
}
int main()
{
std::srand(static_cast<unsigned int>(std::time(nullptr)));
std::cout << "Rock, Paper, Scissors, Lizard, Spock\n\n\n";
unsigned int playerScore = 0;
unsigned int opponentScore = 0;
//for (;;)
//{
Weapon playerWeapon = getPlayerWeapon();
Weapon opponentWeapon = getOpponentWeapon();
std::cout << "\n\nYou've picked : " << toString(playerWeapon);
std::cout << "\nComputer picked: " << toString(opponentWeapon);
Outcome outcome = determineOutcome(playerWeapon, opponentWeapon);
switch (outcome)
{
case WIN:
std::cout << "\n\nYou win! Point awarded to you.";
playerScore++;
break;
case LOSE:
std::cout << "\n\nYou lose! Point awarded to opponent.";
opponentScore++;
break;
case DRAW:
std::cout << "\n\nIt's a draw! No points awarded.";
break;
}
//std::cout << "\n\nPlay again (Y/N)? ";
//char choice;
//std::cin >> choice;
//if (choice == 'n' || choice == 'N') break;
//}
std::cout << "\n\nFinal Scores:\n\n";
std::cout << "Player : " << playerScore;
std::cout << "\nOpponent: " << opponentScore;
}