Rock Paper Scissors game using OOP












12














I'm a complete beginner to Java and we have just started learning objects and classes in school. I'm trying to create a very simple text-based Rock Paper Scissors game. I do realise that my code is a mess, so I'm asking for some suggestions on how could I improve it and if I'm even in the right direction with OOP.



Main class:



public class Main {
public static void main(String args) {
new Game();
}
}


Player class



public abstract class Player {
private String name;
private String choice;

public Player() {}
public Player(String name) {this.name = name;}

public void setName(String newName) {
name = newName;
}

public String getName() {
return name;
}

public String getChoice() {
return choice;
}

public void setChoice(String newChoice) {
choice = newChoice;
}
public abstract void selectChoice();
}


User class



import java.util.Scanner;

public class User extends Player {

private Scanner input;

public User() {
input = new Scanner(System.in);
}

public void selectChoice() {
System.out.println("Enter your choice: R - Rock, P - Paper, S - Scissors");
setChoice(input.nextLine().toUpperCase());
}
}


Computer class



import java.util.Random;

public class Computer extends Player {

private Random rand;
private final int MAX_NUMBER = 3;

public Computer() {
setName("Computer");
rand = new Random();
}

public void selectChoice() {
int randomNumber = rand.nextInt(MAX_NUMBER);
switch(randomNumber) {
case 0:
setChoice("ROCK");
break;
case 1:
setChoice("PAPER");
break;
case 2:
setChoice("SCISSORS");
break;
}
}
}


Game class



import java.util.Scanner;

public class Game {
private User p;
private Computer com;
private int playerWins;
private int playerLoses;
private int ties;
private boolean isRunning = false;
private Scanner scan;

public Game() {
p = new User();
com = new Computer();
scan = new Scanner(System.in);
start();
}

private void start() {
isRunning = true;
System.out.println("Please, enter your name:");
p.setName(scan.nextLine());

while(isRunning) {
displayScore();
p.selectChoice();
com.selectChoice();
displayChoices();
displayWinner(decideWinner());
updateScore(decideWinner());
playAgain();
}
}

private void displayScore() {
System.out.println(p.getName());
System.out.println("----------");
System.out.println("Wins: " + playerWins);
System.out.println("Loses: " + playerLoses);
System.out.println("Ties: " + ties);
System.out.println("----------");
}

private int decideWinner() {
// 0 - User wins
// 1 - Computer wins
// 2 - tie

if(p.getChoice().equals("ROCK") && com.getChoice().equals("SCISSORS"))
return 0;
else if(p.getChoice().equals("PAPER") && com.getChoice().equals("ROCK"))
return 0;
else if(p.getChoice().equals("SCISSORS") && com.getChoice().equals("PAPER"))
return 0;
else if(com.getChoice().equals("ROCK") && p.getChoice().equals("SCISSORS"))
return 1;
else if(com.getChoice().equals("PAPER") && p.getChoice().equals("ROCK"))
return 1;
else if(com.getChoice().equals("SCISSORS") && p.getChoice().equals("PAPER"))
return 1;
else
return 2;
}

private void displayChoices() {
System.out.println("User has selected: " + p.getChoice());
System.out.println("Computer has selected: " + com.getChoice());
}

private void displayWinner(int winner) {
switch(winner) {
case 0:
System.out.println("User has won!");
break;
case 1:
System.out.println("Computer has won!");
break;
case 2:
System.out.println("It is a tie!");
}
}

private void playAgain() {
String choice;
System.out.println("Do you want to play again? Enter Yes to play again.");
choice = scan.nextLine();
if(!(choice.toUpperCase().equals("YES") ))
isRunning = false;

}

private void updateScore(int winner) {
if(winner == 0)
playerWins++;
else if(winner == 1)
playerLoses++;
else if(winner == 2)
ties++;
}
}









share|improve this question




















  • 3




    What problem do you expect an OOP approach to solve for you? Design decisions should never be made in a vacuum.
    – jpmc26
    Dec 10 at 4:15






  • 1




    I suggest you do some validation on the user's input. If the user types anything but the 3 options it always results in a tie now. And you also misleadingly instruct the user to input R, P or S while in fact he needs to type it out
    – Ivo Beckers
    Dec 10 at 10:34






  • 1




    @jpmc26 come on, it's a programming assignment. You might as well ask what problem is solved by making computer write "Hello world".
    – IMil
    Dec 11 at 2:03






  • 1




    @IMil If it's an assignment, that's even more reason to focus on what the tool is best used for rather than apply it blindly. During coursework is the time you're supposed to be learning. Sadly, our discipline does a very poor job in the classroom. It teaches platitudes and incorrect absolutes, leaving new recruits a net cost for employers and struggling to learn the basics on the job instead.
    – jpmc26
    Dec 11 at 2:10












  • @jpmc26 I once had a similar assignment. Not in a freshman course, but as part of the hiring process for a senior software developer position that I applied for (with ~20 years of programming experience). You can implement "rock-paper-scissors" with maybe 50 LOC. That's not the point. (I'll probably post my code from back then as part of an answer. I didn't want the job anyhow.)
    – Marco13
    Dec 11 at 10:43
















12














I'm a complete beginner to Java and we have just started learning objects and classes in school. I'm trying to create a very simple text-based Rock Paper Scissors game. I do realise that my code is a mess, so I'm asking for some suggestions on how could I improve it and if I'm even in the right direction with OOP.



Main class:



public class Main {
public static void main(String args) {
new Game();
}
}


Player class



public abstract class Player {
private String name;
private String choice;

public Player() {}
public Player(String name) {this.name = name;}

public void setName(String newName) {
name = newName;
}

public String getName() {
return name;
}

public String getChoice() {
return choice;
}

public void setChoice(String newChoice) {
choice = newChoice;
}
public abstract void selectChoice();
}


User class



import java.util.Scanner;

public class User extends Player {

private Scanner input;

public User() {
input = new Scanner(System.in);
}

public void selectChoice() {
System.out.println("Enter your choice: R - Rock, P - Paper, S - Scissors");
setChoice(input.nextLine().toUpperCase());
}
}


Computer class



import java.util.Random;

public class Computer extends Player {

private Random rand;
private final int MAX_NUMBER = 3;

public Computer() {
setName("Computer");
rand = new Random();
}

public void selectChoice() {
int randomNumber = rand.nextInt(MAX_NUMBER);
switch(randomNumber) {
case 0:
setChoice("ROCK");
break;
case 1:
setChoice("PAPER");
break;
case 2:
setChoice("SCISSORS");
break;
}
}
}


Game class



import java.util.Scanner;

public class Game {
private User p;
private Computer com;
private int playerWins;
private int playerLoses;
private int ties;
private boolean isRunning = false;
private Scanner scan;

public Game() {
p = new User();
com = new Computer();
scan = new Scanner(System.in);
start();
}

private void start() {
isRunning = true;
System.out.println("Please, enter your name:");
p.setName(scan.nextLine());

while(isRunning) {
displayScore();
p.selectChoice();
com.selectChoice();
displayChoices();
displayWinner(decideWinner());
updateScore(decideWinner());
playAgain();
}
}

private void displayScore() {
System.out.println(p.getName());
System.out.println("----------");
System.out.println("Wins: " + playerWins);
System.out.println("Loses: " + playerLoses);
System.out.println("Ties: " + ties);
System.out.println("----------");
}

private int decideWinner() {
// 0 - User wins
// 1 - Computer wins
// 2 - tie

if(p.getChoice().equals("ROCK") && com.getChoice().equals("SCISSORS"))
return 0;
else if(p.getChoice().equals("PAPER") && com.getChoice().equals("ROCK"))
return 0;
else if(p.getChoice().equals("SCISSORS") && com.getChoice().equals("PAPER"))
return 0;
else if(com.getChoice().equals("ROCK") && p.getChoice().equals("SCISSORS"))
return 1;
else if(com.getChoice().equals("PAPER") && p.getChoice().equals("ROCK"))
return 1;
else if(com.getChoice().equals("SCISSORS") && p.getChoice().equals("PAPER"))
return 1;
else
return 2;
}

private void displayChoices() {
System.out.println("User has selected: " + p.getChoice());
System.out.println("Computer has selected: " + com.getChoice());
}

private void displayWinner(int winner) {
switch(winner) {
case 0:
System.out.println("User has won!");
break;
case 1:
System.out.println("Computer has won!");
break;
case 2:
System.out.println("It is a tie!");
}
}

private void playAgain() {
String choice;
System.out.println("Do you want to play again? Enter Yes to play again.");
choice = scan.nextLine();
if(!(choice.toUpperCase().equals("YES") ))
isRunning = false;

}

private void updateScore(int winner) {
if(winner == 0)
playerWins++;
else if(winner == 1)
playerLoses++;
else if(winner == 2)
ties++;
}
}









share|improve this question




















  • 3




    What problem do you expect an OOP approach to solve for you? Design decisions should never be made in a vacuum.
    – jpmc26
    Dec 10 at 4:15






  • 1




    I suggest you do some validation on the user's input. If the user types anything but the 3 options it always results in a tie now. And you also misleadingly instruct the user to input R, P or S while in fact he needs to type it out
    – Ivo Beckers
    Dec 10 at 10:34






  • 1




    @jpmc26 come on, it's a programming assignment. You might as well ask what problem is solved by making computer write "Hello world".
    – IMil
    Dec 11 at 2:03






  • 1




    @IMil If it's an assignment, that's even more reason to focus on what the tool is best used for rather than apply it blindly. During coursework is the time you're supposed to be learning. Sadly, our discipline does a very poor job in the classroom. It teaches platitudes and incorrect absolutes, leaving new recruits a net cost for employers and struggling to learn the basics on the job instead.
    – jpmc26
    Dec 11 at 2:10












  • @jpmc26 I once had a similar assignment. Not in a freshman course, but as part of the hiring process for a senior software developer position that I applied for (with ~20 years of programming experience). You can implement "rock-paper-scissors" with maybe 50 LOC. That's not the point. (I'll probably post my code from back then as part of an answer. I didn't want the job anyhow.)
    – Marco13
    Dec 11 at 10:43














12












12








12


7





I'm a complete beginner to Java and we have just started learning objects and classes in school. I'm trying to create a very simple text-based Rock Paper Scissors game. I do realise that my code is a mess, so I'm asking for some suggestions on how could I improve it and if I'm even in the right direction with OOP.



Main class:



public class Main {
public static void main(String args) {
new Game();
}
}


Player class



public abstract class Player {
private String name;
private String choice;

public Player() {}
public Player(String name) {this.name = name;}

public void setName(String newName) {
name = newName;
}

public String getName() {
return name;
}

public String getChoice() {
return choice;
}

public void setChoice(String newChoice) {
choice = newChoice;
}
public abstract void selectChoice();
}


User class



import java.util.Scanner;

public class User extends Player {

private Scanner input;

public User() {
input = new Scanner(System.in);
}

public void selectChoice() {
System.out.println("Enter your choice: R - Rock, P - Paper, S - Scissors");
setChoice(input.nextLine().toUpperCase());
}
}


Computer class



import java.util.Random;

public class Computer extends Player {

private Random rand;
private final int MAX_NUMBER = 3;

public Computer() {
setName("Computer");
rand = new Random();
}

public void selectChoice() {
int randomNumber = rand.nextInt(MAX_NUMBER);
switch(randomNumber) {
case 0:
setChoice("ROCK");
break;
case 1:
setChoice("PAPER");
break;
case 2:
setChoice("SCISSORS");
break;
}
}
}


Game class



import java.util.Scanner;

public class Game {
private User p;
private Computer com;
private int playerWins;
private int playerLoses;
private int ties;
private boolean isRunning = false;
private Scanner scan;

public Game() {
p = new User();
com = new Computer();
scan = new Scanner(System.in);
start();
}

private void start() {
isRunning = true;
System.out.println("Please, enter your name:");
p.setName(scan.nextLine());

while(isRunning) {
displayScore();
p.selectChoice();
com.selectChoice();
displayChoices();
displayWinner(decideWinner());
updateScore(decideWinner());
playAgain();
}
}

private void displayScore() {
System.out.println(p.getName());
System.out.println("----------");
System.out.println("Wins: " + playerWins);
System.out.println("Loses: " + playerLoses);
System.out.println("Ties: " + ties);
System.out.println("----------");
}

private int decideWinner() {
// 0 - User wins
// 1 - Computer wins
// 2 - tie

if(p.getChoice().equals("ROCK") && com.getChoice().equals("SCISSORS"))
return 0;
else if(p.getChoice().equals("PAPER") && com.getChoice().equals("ROCK"))
return 0;
else if(p.getChoice().equals("SCISSORS") && com.getChoice().equals("PAPER"))
return 0;
else if(com.getChoice().equals("ROCK") && p.getChoice().equals("SCISSORS"))
return 1;
else if(com.getChoice().equals("PAPER") && p.getChoice().equals("ROCK"))
return 1;
else if(com.getChoice().equals("SCISSORS") && p.getChoice().equals("PAPER"))
return 1;
else
return 2;
}

private void displayChoices() {
System.out.println("User has selected: " + p.getChoice());
System.out.println("Computer has selected: " + com.getChoice());
}

private void displayWinner(int winner) {
switch(winner) {
case 0:
System.out.println("User has won!");
break;
case 1:
System.out.println("Computer has won!");
break;
case 2:
System.out.println("It is a tie!");
}
}

private void playAgain() {
String choice;
System.out.println("Do you want to play again? Enter Yes to play again.");
choice = scan.nextLine();
if(!(choice.toUpperCase().equals("YES") ))
isRunning = false;

}

private void updateScore(int winner) {
if(winner == 0)
playerWins++;
else if(winner == 1)
playerLoses++;
else if(winner == 2)
ties++;
}
}









share|improve this question















I'm a complete beginner to Java and we have just started learning objects and classes in school. I'm trying to create a very simple text-based Rock Paper Scissors game. I do realise that my code is a mess, so I'm asking for some suggestions on how could I improve it and if I'm even in the right direction with OOP.



Main class:



public class Main {
public static void main(String args) {
new Game();
}
}


Player class



public abstract class Player {
private String name;
private String choice;

public Player() {}
public Player(String name) {this.name = name;}

public void setName(String newName) {
name = newName;
}

public String getName() {
return name;
}

public String getChoice() {
return choice;
}

public void setChoice(String newChoice) {
choice = newChoice;
}
public abstract void selectChoice();
}


User class



import java.util.Scanner;

public class User extends Player {

private Scanner input;

public User() {
input = new Scanner(System.in);
}

public void selectChoice() {
System.out.println("Enter your choice: R - Rock, P - Paper, S - Scissors");
setChoice(input.nextLine().toUpperCase());
}
}


Computer class



import java.util.Random;

public class Computer extends Player {

private Random rand;
private final int MAX_NUMBER = 3;

public Computer() {
setName("Computer");
rand = new Random();
}

public void selectChoice() {
int randomNumber = rand.nextInt(MAX_NUMBER);
switch(randomNumber) {
case 0:
setChoice("ROCK");
break;
case 1:
setChoice("PAPER");
break;
case 2:
setChoice("SCISSORS");
break;
}
}
}


Game class



import java.util.Scanner;

public class Game {
private User p;
private Computer com;
private int playerWins;
private int playerLoses;
private int ties;
private boolean isRunning = false;
private Scanner scan;

public Game() {
p = new User();
com = new Computer();
scan = new Scanner(System.in);
start();
}

private void start() {
isRunning = true;
System.out.println("Please, enter your name:");
p.setName(scan.nextLine());

while(isRunning) {
displayScore();
p.selectChoice();
com.selectChoice();
displayChoices();
displayWinner(decideWinner());
updateScore(decideWinner());
playAgain();
}
}

private void displayScore() {
System.out.println(p.getName());
System.out.println("----------");
System.out.println("Wins: " + playerWins);
System.out.println("Loses: " + playerLoses);
System.out.println("Ties: " + ties);
System.out.println("----------");
}

private int decideWinner() {
// 0 - User wins
// 1 - Computer wins
// 2 - tie

if(p.getChoice().equals("ROCK") && com.getChoice().equals("SCISSORS"))
return 0;
else if(p.getChoice().equals("PAPER") && com.getChoice().equals("ROCK"))
return 0;
else if(p.getChoice().equals("SCISSORS") && com.getChoice().equals("PAPER"))
return 0;
else if(com.getChoice().equals("ROCK") && p.getChoice().equals("SCISSORS"))
return 1;
else if(com.getChoice().equals("PAPER") && p.getChoice().equals("ROCK"))
return 1;
else if(com.getChoice().equals("SCISSORS") && p.getChoice().equals("PAPER"))
return 1;
else
return 2;
}

private void displayChoices() {
System.out.println("User has selected: " + p.getChoice());
System.out.println("Computer has selected: " + com.getChoice());
}

private void displayWinner(int winner) {
switch(winner) {
case 0:
System.out.println("User has won!");
break;
case 1:
System.out.println("Computer has won!");
break;
case 2:
System.out.println("It is a tie!");
}
}

private void playAgain() {
String choice;
System.out.println("Do you want to play again? Enter Yes to play again.");
choice = scan.nextLine();
if(!(choice.toUpperCase().equals("YES") ))
isRunning = false;

}

private void updateScore(int winner) {
if(winner == 0)
playerWins++;
else if(winner == 1)
playerLoses++;
else if(winner == 2)
ties++;
}
}






java beginner rock-paper-scissors






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 10 at 2:59









200_success

128k15150412




128k15150412










asked Dec 10 at 0:57









Žiga Černič

6113




6113








  • 3




    What problem do you expect an OOP approach to solve for you? Design decisions should never be made in a vacuum.
    – jpmc26
    Dec 10 at 4:15






  • 1




    I suggest you do some validation on the user's input. If the user types anything but the 3 options it always results in a tie now. And you also misleadingly instruct the user to input R, P or S while in fact he needs to type it out
    – Ivo Beckers
    Dec 10 at 10:34






  • 1




    @jpmc26 come on, it's a programming assignment. You might as well ask what problem is solved by making computer write "Hello world".
    – IMil
    Dec 11 at 2:03






  • 1




    @IMil If it's an assignment, that's even more reason to focus on what the tool is best used for rather than apply it blindly. During coursework is the time you're supposed to be learning. Sadly, our discipline does a very poor job in the classroom. It teaches platitudes and incorrect absolutes, leaving new recruits a net cost for employers and struggling to learn the basics on the job instead.
    – jpmc26
    Dec 11 at 2:10












  • @jpmc26 I once had a similar assignment. Not in a freshman course, but as part of the hiring process for a senior software developer position that I applied for (with ~20 years of programming experience). You can implement "rock-paper-scissors" with maybe 50 LOC. That's not the point. (I'll probably post my code from back then as part of an answer. I didn't want the job anyhow.)
    – Marco13
    Dec 11 at 10:43














  • 3




    What problem do you expect an OOP approach to solve for you? Design decisions should never be made in a vacuum.
    – jpmc26
    Dec 10 at 4:15






  • 1




    I suggest you do some validation on the user's input. If the user types anything but the 3 options it always results in a tie now. And you also misleadingly instruct the user to input R, P or S while in fact he needs to type it out
    – Ivo Beckers
    Dec 10 at 10:34






  • 1




    @jpmc26 come on, it's a programming assignment. You might as well ask what problem is solved by making computer write "Hello world".
    – IMil
    Dec 11 at 2:03






  • 1




    @IMil If it's an assignment, that's even more reason to focus on what the tool is best used for rather than apply it blindly. During coursework is the time you're supposed to be learning. Sadly, our discipline does a very poor job in the classroom. It teaches platitudes and incorrect absolutes, leaving new recruits a net cost for employers and struggling to learn the basics on the job instead.
    – jpmc26
    Dec 11 at 2:10












  • @jpmc26 I once had a similar assignment. Not in a freshman course, but as part of the hiring process for a senior software developer position that I applied for (with ~20 years of programming experience). You can implement "rock-paper-scissors" with maybe 50 LOC. That's not the point. (I'll probably post my code from back then as part of an answer. I didn't want the job anyhow.)
    – Marco13
    Dec 11 at 10:43








3




3




What problem do you expect an OOP approach to solve for you? Design decisions should never be made in a vacuum.
– jpmc26
Dec 10 at 4:15




What problem do you expect an OOP approach to solve for you? Design decisions should never be made in a vacuum.
– jpmc26
Dec 10 at 4:15




1




1




I suggest you do some validation on the user's input. If the user types anything but the 3 options it always results in a tie now. And you also misleadingly instruct the user to input R, P or S while in fact he needs to type it out
– Ivo Beckers
Dec 10 at 10:34




I suggest you do some validation on the user's input. If the user types anything but the 3 options it always results in a tie now. And you also misleadingly instruct the user to input R, P or S while in fact he needs to type it out
– Ivo Beckers
Dec 10 at 10:34




1




1




@jpmc26 come on, it's a programming assignment. You might as well ask what problem is solved by making computer write "Hello world".
– IMil
Dec 11 at 2:03




@jpmc26 come on, it's a programming assignment. You might as well ask what problem is solved by making computer write "Hello world".
– IMil
Dec 11 at 2:03




1




1




@IMil If it's an assignment, that's even more reason to focus on what the tool is best used for rather than apply it blindly. During coursework is the time you're supposed to be learning. Sadly, our discipline does a very poor job in the classroom. It teaches platitudes and incorrect absolutes, leaving new recruits a net cost for employers and struggling to learn the basics on the job instead.
– jpmc26
Dec 11 at 2:10






@IMil If it's an assignment, that's even more reason to focus on what the tool is best used for rather than apply it blindly. During coursework is the time you're supposed to be learning. Sadly, our discipline does a very poor job in the classroom. It teaches platitudes and incorrect absolutes, leaving new recruits a net cost for employers and struggling to learn the basics on the job instead.
– jpmc26
Dec 11 at 2:10














@jpmc26 I once had a similar assignment. Not in a freshman course, but as part of the hiring process for a senior software developer position that I applied for (with ~20 years of programming experience). You can implement "rock-paper-scissors" with maybe 50 LOC. That's not the point. (I'll probably post my code from back then as part of an answer. I didn't want the job anyhow.)
– Marco13
Dec 11 at 10:43




@jpmc26 I once had a similar assignment. Not in a freshman course, but as part of the hiring process for a senior software developer position that I applied for (with ~20 years of programming experience). You can implement "rock-paper-scissors" with maybe 50 LOC. That's not the point. (I'll probably post my code from back then as part of an answer. I didn't want the job anyhow.)
– Marco13
Dec 11 at 10:43










2 Answers
2






active

oldest

votes


















18














Good job so far!



The previous answers already cover a lot, I just want to add this:



Don't use String for state!



Currently you use String to encode the Players Choice. This is hard to refactor and it is difficult to add functionality. Prefer its own Class or Enum.



For example



 enum Choice  { ROCK, PAPER, SCISSORS}


Then, you can have a variable containing the choice, for example:



 Choice choice = Choice.ROCK;


You can add behaviour to the enum:



enum Choice  { 
ROCK, PAPER, SCISSORS

public boolean beats(Choice other)
{
switch (this)
{
case ROCK:
return other == SCISSORS;
case PAPER:
return other == ROCK;
case SCISSORS:
return other == PAPER;
}

}
}


Now, your other code can just call myChoice.beats(otherChoice).



Also, you can implement random() in the enum, as well as parseFromUserInput(String s). If you do this correctly, you can change the enum, adding different choices, without needing to change any other code in your application.



So, if you want to implement RockPaperScissorsLizardSpock , you just extend the Enum, and be done!



Also:



Use Enum instead of magic int values



Instead of returning int that encodes the result of the round, use a explicit enum as well, replacing the boolean beats() method above:



enum Result { WIN, LOSS, DRAW }

public Result fights(Choice other)
{
switch (this)
{
case ROCK:
if (other == ROCK)
return Result.DRAW
return other == SCISSORS ? Result.WIN : Result.LOSS;
....
}

}





share|improve this answer































    9














    This code really isn't a mess! While there are a few relatively minor points I can make, your code is generally easy to read and understand, and there's nothing horribly wrong about it.




    1. Watch out for user input! I can enter Z (or anything but rock/paper/scissors) and the result will always be a tie. You should tell the user when they enter something invalid and have them correct it.


    2. Both Computer and Player use setName to set their name - once. I would prefer requiring the use of the Player constructor with the name parameter since you could then mark name as final.


    3. Why is setChoice public? It is (and should) only used by selectChoice, so mark it protected.


    4. What happens when I want to play a game between two computer opponents (or two people)? Right now I can't. It would be nice if Game let me pass the two Player objects in that will be opponents.


    5. While I appreciate the MAX_NUMBER constant in the Computer class instead of just including a magic number, it's a better idea to store your choices in an array and then select a random element of the array.



    6. Passing around strings for choices isn't so bad when just dealing with Rock/Paper/Scissors, but it will quickly become unmanagable. Enum Types were introduced to fix this problem, and generally do a pretty good job of it! It wouldn't hurt to start using them now. Another good spot for an enumeration is in the decideWinner method.



      The Choice enum type could also provide a method winsAgainst(Choice other) that can be used to simplify decideWinner.



    7. For the most part, your names are great... until we get to Game and see p and com.


    8. It would be nice to use the user's name instead of User when displaying the winner and when displaying choices.



    The following points may directly contradict what your teacher says, as they are more opinion based. Follow whatever your team's (or assignment's) guidelines say.





    1. Don't be afraid to include more than one line of code in main. If I wrote this program my main function would look something like this:



      Scanner scanner = new Scanner(System.in);
      System.out.println("Please enter your name:");

      Player user = new User(scanner.nextLine());
      Player computer = new Computer();
      Game game = new Game(user, computer);

      do {
      game.play();
      System.out.println("Play again? [Yes/No]");
      } while (scanner.nextLine().toUpperCase().equals("YES"));


    2. Use braces on all if statements that aren't one line long. I would be fine with if (winner == 0) playerWins++;, but if (winner == 0)n playerWins++; is much easier to mess up, especially if you don't have automatic indentation.


    3. Don't declare variables before initializing them, if possible. There's no reason to declare choice before printing out instructions in the playAgain method.







    share|improve this answer





















    • Enums (or constants) avoid spelling errors. You don't get a clear idea of what's wrong from an error message if you just write "SCISORS" once.
      – JollyJoker
      Dec 10 at 8:44






    • 1




      BTW this part should be emphasized: Player computer = new Computer(). The OP had them declared as derived types, which is... ok, but inflexible.
      – IMil
      Dec 11 at 1:56













    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209331%2frock-paper-scissors-game-using-oop%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    18














    Good job so far!



    The previous answers already cover a lot, I just want to add this:



    Don't use String for state!



    Currently you use String to encode the Players Choice. This is hard to refactor and it is difficult to add functionality. Prefer its own Class or Enum.



    For example



     enum Choice  { ROCK, PAPER, SCISSORS}


    Then, you can have a variable containing the choice, for example:



     Choice choice = Choice.ROCK;


    You can add behaviour to the enum:



    enum Choice  { 
    ROCK, PAPER, SCISSORS

    public boolean beats(Choice other)
    {
    switch (this)
    {
    case ROCK:
    return other == SCISSORS;
    case PAPER:
    return other == ROCK;
    case SCISSORS:
    return other == PAPER;
    }

    }
    }


    Now, your other code can just call myChoice.beats(otherChoice).



    Also, you can implement random() in the enum, as well as parseFromUserInput(String s). If you do this correctly, you can change the enum, adding different choices, without needing to change any other code in your application.



    So, if you want to implement RockPaperScissorsLizardSpock , you just extend the Enum, and be done!



    Also:



    Use Enum instead of magic int values



    Instead of returning int that encodes the result of the round, use a explicit enum as well, replacing the boolean beats() method above:



    enum Result { WIN, LOSS, DRAW }

    public Result fights(Choice other)
    {
    switch (this)
    {
    case ROCK:
    if (other == ROCK)
    return Result.DRAW
    return other == SCISSORS ? Result.WIN : Result.LOSS;
    ....
    }

    }





    share|improve this answer




























      18














      Good job so far!



      The previous answers already cover a lot, I just want to add this:



      Don't use String for state!



      Currently you use String to encode the Players Choice. This is hard to refactor and it is difficult to add functionality. Prefer its own Class or Enum.



      For example



       enum Choice  { ROCK, PAPER, SCISSORS}


      Then, you can have a variable containing the choice, for example:



       Choice choice = Choice.ROCK;


      You can add behaviour to the enum:



      enum Choice  { 
      ROCK, PAPER, SCISSORS

      public boolean beats(Choice other)
      {
      switch (this)
      {
      case ROCK:
      return other == SCISSORS;
      case PAPER:
      return other == ROCK;
      case SCISSORS:
      return other == PAPER;
      }

      }
      }


      Now, your other code can just call myChoice.beats(otherChoice).



      Also, you can implement random() in the enum, as well as parseFromUserInput(String s). If you do this correctly, you can change the enum, adding different choices, without needing to change any other code in your application.



      So, if you want to implement RockPaperScissorsLizardSpock , you just extend the Enum, and be done!



      Also:



      Use Enum instead of magic int values



      Instead of returning int that encodes the result of the round, use a explicit enum as well, replacing the boolean beats() method above:



      enum Result { WIN, LOSS, DRAW }

      public Result fights(Choice other)
      {
      switch (this)
      {
      case ROCK:
      if (other == ROCK)
      return Result.DRAW
      return other == SCISSORS ? Result.WIN : Result.LOSS;
      ....
      }

      }





      share|improve this answer


























        18












        18








        18






        Good job so far!



        The previous answers already cover a lot, I just want to add this:



        Don't use String for state!



        Currently you use String to encode the Players Choice. This is hard to refactor and it is difficult to add functionality. Prefer its own Class or Enum.



        For example



         enum Choice  { ROCK, PAPER, SCISSORS}


        Then, you can have a variable containing the choice, for example:



         Choice choice = Choice.ROCK;


        You can add behaviour to the enum:



        enum Choice  { 
        ROCK, PAPER, SCISSORS

        public boolean beats(Choice other)
        {
        switch (this)
        {
        case ROCK:
        return other == SCISSORS;
        case PAPER:
        return other == ROCK;
        case SCISSORS:
        return other == PAPER;
        }

        }
        }


        Now, your other code can just call myChoice.beats(otherChoice).



        Also, you can implement random() in the enum, as well as parseFromUserInput(String s). If you do this correctly, you can change the enum, adding different choices, without needing to change any other code in your application.



        So, if you want to implement RockPaperScissorsLizardSpock , you just extend the Enum, and be done!



        Also:



        Use Enum instead of magic int values



        Instead of returning int that encodes the result of the round, use a explicit enum as well, replacing the boolean beats() method above:



        enum Result { WIN, LOSS, DRAW }

        public Result fights(Choice other)
        {
        switch (this)
        {
        case ROCK:
        if (other == ROCK)
        return Result.DRAW
        return other == SCISSORS ? Result.WIN : Result.LOSS;
        ....
        }

        }





        share|improve this answer














        Good job so far!



        The previous answers already cover a lot, I just want to add this:



        Don't use String for state!



        Currently you use String to encode the Players Choice. This is hard to refactor and it is difficult to add functionality. Prefer its own Class or Enum.



        For example



         enum Choice  { ROCK, PAPER, SCISSORS}


        Then, you can have a variable containing the choice, for example:



         Choice choice = Choice.ROCK;


        You can add behaviour to the enum:



        enum Choice  { 
        ROCK, PAPER, SCISSORS

        public boolean beats(Choice other)
        {
        switch (this)
        {
        case ROCK:
        return other == SCISSORS;
        case PAPER:
        return other == ROCK;
        case SCISSORS:
        return other == PAPER;
        }

        }
        }


        Now, your other code can just call myChoice.beats(otherChoice).



        Also, you can implement random() in the enum, as well as parseFromUserInput(String s). If you do this correctly, you can change the enum, adding different choices, without needing to change any other code in your application.



        So, if you want to implement RockPaperScissorsLizardSpock , you just extend the Enum, and be done!



        Also:



        Use Enum instead of magic int values



        Instead of returning int that encodes the result of the round, use a explicit enum as well, replacing the boolean beats() method above:



        enum Result { WIN, LOSS, DRAW }

        public Result fights(Choice other)
        {
        switch (this)
        {
        case ROCK:
        if (other == ROCK)
        return Result.DRAW
        return other == SCISSORS ? Result.WIN : Result.LOSS;
        ....
        }

        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 11 at 7:43

























        answered Dec 10 at 8:38









        RobAu

        2,494819




        2,494819

























            9














            This code really isn't a mess! While there are a few relatively minor points I can make, your code is generally easy to read and understand, and there's nothing horribly wrong about it.




            1. Watch out for user input! I can enter Z (or anything but rock/paper/scissors) and the result will always be a tie. You should tell the user when they enter something invalid and have them correct it.


            2. Both Computer and Player use setName to set their name - once. I would prefer requiring the use of the Player constructor with the name parameter since you could then mark name as final.


            3. Why is setChoice public? It is (and should) only used by selectChoice, so mark it protected.


            4. What happens when I want to play a game between two computer opponents (or two people)? Right now I can't. It would be nice if Game let me pass the two Player objects in that will be opponents.


            5. While I appreciate the MAX_NUMBER constant in the Computer class instead of just including a magic number, it's a better idea to store your choices in an array and then select a random element of the array.



            6. Passing around strings for choices isn't so bad when just dealing with Rock/Paper/Scissors, but it will quickly become unmanagable. Enum Types were introduced to fix this problem, and generally do a pretty good job of it! It wouldn't hurt to start using them now. Another good spot for an enumeration is in the decideWinner method.



              The Choice enum type could also provide a method winsAgainst(Choice other) that can be used to simplify decideWinner.



            7. For the most part, your names are great... until we get to Game and see p and com.


            8. It would be nice to use the user's name instead of User when displaying the winner and when displaying choices.



            The following points may directly contradict what your teacher says, as they are more opinion based. Follow whatever your team's (or assignment's) guidelines say.





            1. Don't be afraid to include more than one line of code in main. If I wrote this program my main function would look something like this:



              Scanner scanner = new Scanner(System.in);
              System.out.println("Please enter your name:");

              Player user = new User(scanner.nextLine());
              Player computer = new Computer();
              Game game = new Game(user, computer);

              do {
              game.play();
              System.out.println("Play again? [Yes/No]");
              } while (scanner.nextLine().toUpperCase().equals("YES"));


            2. Use braces on all if statements that aren't one line long. I would be fine with if (winner == 0) playerWins++;, but if (winner == 0)n playerWins++; is much easier to mess up, especially if you don't have automatic indentation.


            3. Don't declare variables before initializing them, if possible. There's no reason to declare choice before printing out instructions in the playAgain method.







            share|improve this answer





















            • Enums (or constants) avoid spelling errors. You don't get a clear idea of what's wrong from an error message if you just write "SCISORS" once.
              – JollyJoker
              Dec 10 at 8:44






            • 1




              BTW this part should be emphasized: Player computer = new Computer(). The OP had them declared as derived types, which is... ok, but inflexible.
              – IMil
              Dec 11 at 1:56


















            9














            This code really isn't a mess! While there are a few relatively minor points I can make, your code is generally easy to read and understand, and there's nothing horribly wrong about it.




            1. Watch out for user input! I can enter Z (or anything but rock/paper/scissors) and the result will always be a tie. You should tell the user when they enter something invalid and have them correct it.


            2. Both Computer and Player use setName to set their name - once. I would prefer requiring the use of the Player constructor with the name parameter since you could then mark name as final.


            3. Why is setChoice public? It is (and should) only used by selectChoice, so mark it protected.


            4. What happens when I want to play a game between two computer opponents (or two people)? Right now I can't. It would be nice if Game let me pass the two Player objects in that will be opponents.


            5. While I appreciate the MAX_NUMBER constant in the Computer class instead of just including a magic number, it's a better idea to store your choices in an array and then select a random element of the array.



            6. Passing around strings for choices isn't so bad when just dealing with Rock/Paper/Scissors, but it will quickly become unmanagable. Enum Types were introduced to fix this problem, and generally do a pretty good job of it! It wouldn't hurt to start using them now. Another good spot for an enumeration is in the decideWinner method.



              The Choice enum type could also provide a method winsAgainst(Choice other) that can be used to simplify decideWinner.



            7. For the most part, your names are great... until we get to Game and see p and com.


            8. It would be nice to use the user's name instead of User when displaying the winner and when displaying choices.



            The following points may directly contradict what your teacher says, as they are more opinion based. Follow whatever your team's (or assignment's) guidelines say.





            1. Don't be afraid to include more than one line of code in main. If I wrote this program my main function would look something like this:



              Scanner scanner = new Scanner(System.in);
              System.out.println("Please enter your name:");

              Player user = new User(scanner.nextLine());
              Player computer = new Computer();
              Game game = new Game(user, computer);

              do {
              game.play();
              System.out.println("Play again? [Yes/No]");
              } while (scanner.nextLine().toUpperCase().equals("YES"));


            2. Use braces on all if statements that aren't one line long. I would be fine with if (winner == 0) playerWins++;, but if (winner == 0)n playerWins++; is much easier to mess up, especially if you don't have automatic indentation.


            3. Don't declare variables before initializing them, if possible. There's no reason to declare choice before printing out instructions in the playAgain method.







            share|improve this answer





















            • Enums (or constants) avoid spelling errors. You don't get a clear idea of what's wrong from an error message if you just write "SCISORS" once.
              – JollyJoker
              Dec 10 at 8:44






            • 1




              BTW this part should be emphasized: Player computer = new Computer(). The OP had them declared as derived types, which is... ok, but inflexible.
              – IMil
              Dec 11 at 1:56
















            9












            9








            9






            This code really isn't a mess! While there are a few relatively minor points I can make, your code is generally easy to read and understand, and there's nothing horribly wrong about it.




            1. Watch out for user input! I can enter Z (or anything but rock/paper/scissors) and the result will always be a tie. You should tell the user when they enter something invalid and have them correct it.


            2. Both Computer and Player use setName to set their name - once. I would prefer requiring the use of the Player constructor with the name parameter since you could then mark name as final.


            3. Why is setChoice public? It is (and should) only used by selectChoice, so mark it protected.


            4. What happens when I want to play a game between two computer opponents (or two people)? Right now I can't. It would be nice if Game let me pass the two Player objects in that will be opponents.


            5. While I appreciate the MAX_NUMBER constant in the Computer class instead of just including a magic number, it's a better idea to store your choices in an array and then select a random element of the array.



            6. Passing around strings for choices isn't so bad when just dealing with Rock/Paper/Scissors, but it will quickly become unmanagable. Enum Types were introduced to fix this problem, and generally do a pretty good job of it! It wouldn't hurt to start using them now. Another good spot for an enumeration is in the decideWinner method.



              The Choice enum type could also provide a method winsAgainst(Choice other) that can be used to simplify decideWinner.



            7. For the most part, your names are great... until we get to Game and see p and com.


            8. It would be nice to use the user's name instead of User when displaying the winner and when displaying choices.



            The following points may directly contradict what your teacher says, as they are more opinion based. Follow whatever your team's (or assignment's) guidelines say.





            1. Don't be afraid to include more than one line of code in main. If I wrote this program my main function would look something like this:



              Scanner scanner = new Scanner(System.in);
              System.out.println("Please enter your name:");

              Player user = new User(scanner.nextLine());
              Player computer = new Computer();
              Game game = new Game(user, computer);

              do {
              game.play();
              System.out.println("Play again? [Yes/No]");
              } while (scanner.nextLine().toUpperCase().equals("YES"));


            2. Use braces on all if statements that aren't one line long. I would be fine with if (winner == 0) playerWins++;, but if (winner == 0)n playerWins++; is much easier to mess up, especially if you don't have automatic indentation.


            3. Don't declare variables before initializing them, if possible. There's no reason to declare choice before printing out instructions in the playAgain method.







            share|improve this answer












            This code really isn't a mess! While there are a few relatively minor points I can make, your code is generally easy to read and understand, and there's nothing horribly wrong about it.




            1. Watch out for user input! I can enter Z (or anything but rock/paper/scissors) and the result will always be a tie. You should tell the user when they enter something invalid and have them correct it.


            2. Both Computer and Player use setName to set their name - once. I would prefer requiring the use of the Player constructor with the name parameter since you could then mark name as final.


            3. Why is setChoice public? It is (and should) only used by selectChoice, so mark it protected.


            4. What happens when I want to play a game between two computer opponents (or two people)? Right now I can't. It would be nice if Game let me pass the two Player objects in that will be opponents.


            5. While I appreciate the MAX_NUMBER constant in the Computer class instead of just including a magic number, it's a better idea to store your choices in an array and then select a random element of the array.



            6. Passing around strings for choices isn't so bad when just dealing with Rock/Paper/Scissors, but it will quickly become unmanagable. Enum Types were introduced to fix this problem, and generally do a pretty good job of it! It wouldn't hurt to start using them now. Another good spot for an enumeration is in the decideWinner method.



              The Choice enum type could also provide a method winsAgainst(Choice other) that can be used to simplify decideWinner.



            7. For the most part, your names are great... until we get to Game and see p and com.


            8. It would be nice to use the user's name instead of User when displaying the winner and when displaying choices.



            The following points may directly contradict what your teacher says, as they are more opinion based. Follow whatever your team's (or assignment's) guidelines say.





            1. Don't be afraid to include more than one line of code in main. If I wrote this program my main function would look something like this:



              Scanner scanner = new Scanner(System.in);
              System.out.println("Please enter your name:");

              Player user = new User(scanner.nextLine());
              Player computer = new Computer();
              Game game = new Game(user, computer);

              do {
              game.play();
              System.out.println("Play again? [Yes/No]");
              } while (scanner.nextLine().toUpperCase().equals("YES"));


            2. Use braces on all if statements that aren't one line long. I would be fine with if (winner == 0) playerWins++;, but if (winner == 0)n playerWins++; is much easier to mess up, especially if you don't have automatic indentation.


            3. Don't declare variables before initializing them, if possible. There's no reason to declare choice before printing out instructions in the playAgain method.








            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Dec 10 at 3:31









            Gerrit0

            3,0291524




            3,0291524












            • Enums (or constants) avoid spelling errors. You don't get a clear idea of what's wrong from an error message if you just write "SCISORS" once.
              – JollyJoker
              Dec 10 at 8:44






            • 1




              BTW this part should be emphasized: Player computer = new Computer(). The OP had them declared as derived types, which is... ok, but inflexible.
              – IMil
              Dec 11 at 1:56




















            • Enums (or constants) avoid spelling errors. You don't get a clear idea of what's wrong from an error message if you just write "SCISORS" once.
              – JollyJoker
              Dec 10 at 8:44






            • 1




              BTW this part should be emphasized: Player computer = new Computer(). The OP had them declared as derived types, which is... ok, but inflexible.
              – IMil
              Dec 11 at 1:56


















            Enums (or constants) avoid spelling errors. You don't get a clear idea of what's wrong from an error message if you just write "SCISORS" once.
            – JollyJoker
            Dec 10 at 8:44




            Enums (or constants) avoid spelling errors. You don't get a clear idea of what's wrong from an error message if you just write "SCISORS" once.
            – JollyJoker
            Dec 10 at 8:44




            1




            1




            BTW this part should be emphasized: Player computer = new Computer(). The OP had them declared as derived types, which is... ok, but inflexible.
            – IMil
            Dec 11 at 1:56






            BTW this part should be emphasized: Player computer = new Computer(). The OP had them declared as derived types, which is... ok, but inflexible.
            – IMil
            Dec 11 at 1:56




















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209331%2frock-paper-scissors-game-using-oop%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            If I really need a card on my start hand, how many mulligans make sense? [duplicate]

            Alcedinidae

            Can an atomic nucleus contain both particles and antiparticles? [duplicate]