patterncppMinor
Rock-Paper-Scissors game
Viewed 0 times
scissorspapergamerock
Problem
This is the first piece of code I wrote on my own. I tried to use everything I know, like functions, loops and variables. Is it good or could it be simpler?
Please be hard as you can be with me because I feel my programming knowledge is quite poor and I end up using Google for solving my problems.
```
// RPS.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
#include
using namespace std;
int nPlayerScore=0;
int nComputerScore=0;
int nPlayerMove=0;
int nComputerMove=0;
void DisplayScore()
{
cout > x;
cout << endl;
return x;
}
void CalculateResults()
{
if (nPlayerMove==1) //player is Rock
{
if (nComputerMove==1) {cout << "player Rock vs computer Rock: IT'S A TIE!";}
if (nComputerMove==2) {cout << "player Rock vs computer Paper: COMPUTER WON!"; nComputerScore=nComputerScore+1;}
if (nComputerMove==3) {cout << "player Rock vs computer Scissors: PLAYER WON!"; nPlayerScore=nPlayerScore+1;}
}
if (nPlayerMove==2) //player is Paper
{
if (nComputerMove==1) {cout << "player Paper vs computer Rock: PLAYER WON!"; nPlayerScore=nPlayerScore+1;}
if (nComputerMove==2) {cout << "player Paper vs computer Paper: IT'S A TIE!";}
if (nComputerMove==3) {cout << "player Paper vs computer Scissors: COMPUTER WON!"; nComputerScore=nComputerScore+1;}
}
if (nPlayerMove==3) //player is Scissors
{
if (nComputerMove==1) {cout << "player Scissors vs computer Rock: COMPUTER WON!"; nComputerScore=nComputerScore+1;}
if (nComputerMove==2) {cout << "player Scissors vs computer Paper: PLAYER WON!"; nPlayerScore=nPlayerScore+1;}
if (nComputerMove==3) {cout << "player Scissors vs computer Scissors: IT'S A TIE!";}
}
cout << endl << endl;
}
int main()
{
do
{
cout << "Welcome to RPS 1.0a \tby GeTAFIX \n\n";
DisplayScore();
nPlayerMove=GetMove();
srand((unsigned)time(0));
nComputerMove=rand()%(3)+1;
C
Please be hard as you can be with me because I feel my programming knowledge is quite poor and I end up using Google for solving my problems.
```
// RPS.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
#include
using namespace std;
int nPlayerScore=0;
int nComputerScore=0;
int nPlayerMove=0;
int nComputerMove=0;
void DisplayScore()
{
cout > x;
cout << endl;
return x;
}
void CalculateResults()
{
if (nPlayerMove==1) //player is Rock
{
if (nComputerMove==1) {cout << "player Rock vs computer Rock: IT'S A TIE!";}
if (nComputerMove==2) {cout << "player Rock vs computer Paper: COMPUTER WON!"; nComputerScore=nComputerScore+1;}
if (nComputerMove==3) {cout << "player Rock vs computer Scissors: PLAYER WON!"; nPlayerScore=nPlayerScore+1;}
}
if (nPlayerMove==2) //player is Paper
{
if (nComputerMove==1) {cout << "player Paper vs computer Rock: PLAYER WON!"; nPlayerScore=nPlayerScore+1;}
if (nComputerMove==2) {cout << "player Paper vs computer Paper: IT'S A TIE!";}
if (nComputerMove==3) {cout << "player Paper vs computer Scissors: COMPUTER WON!"; nComputerScore=nComputerScore+1;}
}
if (nPlayerMove==3) //player is Scissors
{
if (nComputerMove==1) {cout << "player Scissors vs computer Rock: COMPUTER WON!"; nComputerScore=nComputerScore+1;}
if (nComputerMove==2) {cout << "player Scissors vs computer Paper: PLAYER WON!"; nPlayerScore=nPlayerScore+1;}
if (nComputerMove==3) {cout << "player Scissors vs computer Scissors: IT'S A TIE!";}
}
cout << endl << endl;
}
int main()
{
do
{
cout << "Welcome to RPS 1.0a \tby GeTAFIX \n\n";
DisplayScore();
nPlayerMove=GetMove();
srand((unsigned)time(0));
nComputerMove=rand()%(3)+1;
C
Solution
First of all, stop using
Secondly, you are seeding the random number generator every iteration. This is not only unnecessary, it is harmful: if you do this in a program that calls
Thirdly, I think you're getting a little far with splitting things into functions. It might make sense to split the move-reading part into a separate function if you're going to perform input validation, but I think it currently just complicates matters.
Your
Further stylistic issues: you should fix your indentation, turn the
By the way, if you're using Google to solve your C++ problems, you're likely picking up a lot of information that's very wrong. Make sure you have a good book to learn from, such as Accelerated C++.
Your code could be simplified to this, although the behaviour isn't quite the same:
This results in a larger
If you are using C++11, you can get even more awesome syntax than the
And then use
system("pause"); and system("cls");. Both of those are not portable, and are silly ways of achieving what you want. Take a look here for an actual solution.Secondly, you are seeding the random number generator every iteration. This is not only unnecessary, it is harmful: if you do this in a program that calls
rand more than once a second, you will get the same result each call. Even if you are only accessing it once a second (as you may be here), it is bad practice in any case, and can lead to a decrease in randomness.Thirdly, I think you're getting a little far with splitting things into functions. It might make sense to split the move-reading part into a separate function if you're going to perform input validation, but I think it currently just complicates matters.
Your
CalculateResults function is overcomplicated. If 0 is rock, 1 is paper, and 2 is scissors, and x and y are the choices of the players, you can tell who won with (3+x-y)%3. If the result is 1 then x has won; if it is 2, then y has won; otherwise (if it is 0) there has been a tie.Further stylistic issues: you should fix your indentation, turn the
do ... while loop into a while(true) or for(;;) loop, stop using using namespace std;, and disable precompiled headers (they offer no benefit for a single-file solution). You should also output '\n' instead of std::endl unless you explicitly want to flush the stream; an expression like std::cout << std::endl << std::endl simply doesn't make sense.By the way, if you're using Google to solve your C++ problems, you're likely picking up a lot of information that's very wrong. Make sure you have a good book to learn from, such as Accelerated C++.
Your code could be simplified to this, although the behaviour isn't quite the same:
#include
#include
#include
#include
#include
std::string numberToWeapon(int n) {
switch (n) {
case 0: return "rock";
case 1: return "paper";
case 2: return "scissors";
}
assert(!"Invalid parameter");
}
int main() {
std::cout (time(0)));
while (true) {
int playerMove;
std::cout > playerMove))
return 0;
--playerMove;
if (playerMove 2) {
std::cout << "Invalid input.\n";
continue;
}
int ourMove = rand()%3;
std::cout << "You played: " << numberToWeapon(playerMove) << ". ";
std::cout << "We played: " << numberToWeapon(ourMove) << ".\n";
switch ((3 + playerMove - ourMove) % 3) {
case 0:
std::cout << "The game is a tie.\n";
break;
case 1:
std::cout << "You won!\n";
++playerScore;
break;
case 2:
std::cout << "We won!\n";
++ourScore;
break;
}
std::cout << "The score is currently:\n";
std::cout << "You - " << playerScore << ".\n";
std::cout << "We - " << ourScore << ".\n";
}
}This results in a larger
main function, but no global variables. You can argue on whether that's any better or not: personally, I think it's clear as it is, and I don't see any duplication, but you may want to experiment.If you are using C++11, you can get even more awesome syntax than the
numberToWeapon function, namely:std::array weapons = {"rock", "paper", "scissors"};And then use
weapons.at(num) (or weapons[num] if you're sure you're in-bounds).Code Snippets
#include <iostream>
#include <string>
#include <cassert>
#include <ctime>
#include <cstdlib>
std::string numberToWeapon(int n) {
switch (n) {
case 0: return "rock";
case 1: return "paper";
case 2: return "scissors";
}
assert(!"Invalid parameter");
}
int main() {
std::cout << "Rock-Paper-Scissors v1.0\n";
int playerScore = 0;
int ourScore = 0;
std::srand(static_cast<unsigned int>(time(0)));
while (true) {
int playerMove;
std::cout << "Please enter 1 for rock, 2 for paper, or 3 for scissors.\n";
if (!(std::cin >> playerMove))
return 0;
--playerMove;
if (playerMove < 0 || playerMove > 2) {
std::cout << "Invalid input.\n";
continue;
}
int ourMove = rand()%3;
std::cout << "You played: " << numberToWeapon(playerMove) << ". ";
std::cout << "We played: " << numberToWeapon(ourMove) << ".\n";
switch ((3 + playerMove - ourMove) % 3) {
case 0:
std::cout << "The game is a tie.\n";
break;
case 1:
std::cout << "You won!\n";
++playerScore;
break;
case 2:
std::cout << "We won!\n";
++ourScore;
break;
}
std::cout << "The score is currently:\n";
std::cout << "You - " << playerScore << ".\n";
std::cout << "We - " << ourScore << ".\n";
}
}std::array<4, std::string> weapons = {"rock", "paper", "scissors"};Context
StackExchange Code Review Q#9590, answer score: 5
Revisions (0)
No revisions yet.