Jeu de roche, papier, ciseaux - Simulation de jeu de base

Oct 03 2020

J'ai apprécié les nombreux maux de tête que ce projet m'a donné car j'ai beaucoup appris! J'étudie Java depuis moins d'un an et je suis nouveau dans la programmation en général. J'ai lu les règles des commentaires et j'espère les avoir suivies correctement. Je ne connais pas beaucoup de gens qui codent et j'aimerais avoir des commentaires. C'était un projet scolaire sur lequel j'ai travaillé très dur, mais je sais que j'ai un long chemin à parcourir. S'il vous plaît, faites-moi savoir si vous pouvez m'aider à aller mieux ...

import java.util.Scanner;
    import java.util.Random;
    
    public class RPS {
        public static void main(String[] args) {
            Boolean playAgain = true;
            Scanner input = new Scanner(System.in);
            String play;
            
            while (playAgain = true) {      
            WelcomeP1(); //  Welcome & basic rule example
            
            // Final Result & Replay Option
            System.out.print("*********************" );
            System.out.print("-------------> You " +Game()+ "!!!" );
            System.out.println("\n*********************" );
            System.out.println("Play Again?!");
            System.out.println("Please press y for (Y)es or n for (N)o: ");
            play = input.nextLine().trim();
            while (play.isEmpty()){
                System.out.println("Do you want to play Rock, Paper, Scissors?");
                System.out.println("Please press y for (Y)es \nor n for (N)o: ");
                play = input
                        .nextLine().trim();
                } // end while ~ validate/catch error ~ for empty space
            switch ( play.charAt(0) ){
                    case 'n' : case 'N':
                        playAgain = false;
                        System.exit(0);
                    case 'y': case 'Y':
                        System.out.println("\n*********************" );
                        System.out.print("Excellent;\nGlad you enjoyed playing!"); 
                        System.out.println("\nJust checking again...");
              } // end while 
            } // end switch 
        } // end main
        
        
            // Welcome Validation Start
            public static void WelcomeP1(){
                Scanner stdIn= new Scanner(System.in);
                Boolean validGame = false;
                String userPlay;
                
                while( validGame == false ){
                System.out.println("Do you want to play Rock, Paper, Scissors?");
                System.out.println("Please press y for (Y)es \nor n for (N)o: ");
                userPlay = stdIn.nextLine().trim();
                while (userPlay.isEmpty()){
                    System.out.println("Do you want to play Rock, Paper, Scissors?");
                    System.out.println("Please press y for (Y)es \nor n for (N)o: ");
                    userPlay = stdIn.nextLine().trim();
                } // end while ~ validate/catch error ~ for empty space
                // below valiates user entry    
                switch ( userPlay.charAt(0) ){
                    case 'n' : case 'N':
                        System.exit(0);
                    case 'y': case 'Y':
                        validGame = true;
                        System.out.println("*************************************");
                        System.out.println("Excellent! Thank you...\nLet's Play!");
                        break;
                    default: 
                } // end switch
            } // end while loop 
            } // end class Welcome ~ End Welcome Validation
            
            
            // User Input Validation Start
            public static int P1Choice(){
                Scanner userIn = new Scanner(System.in);
                Boolean validUserIn = false;
                String userInput; 
                int userPiece = 0;
            
                while (validUserIn == false){
                    System.out.println("*************************************");
                    System.out.println("Choose (R)ock, (P)aper, or (S)cissors ");
                    System.out.println("Please type the first letter only.");
                    System.out.println("Your Choice: ");
                    userInput = userIn.nextLine();
                while (userInput.isEmpty()){
                    System.out.println("Choose (R)ock, (P)aper, or (S)cissors ");
                    System.out.println("Please type the first letter only.");
                    System.out.println("Your Choice: ");
                    userInput = userIn.nextLine();
                } // end while ~ validate/catch error ~ for empty space
                  // below valiates user entry further   
                    userPiece = userInput.charAt(0);
                if (userInput.equalsIgnoreCase("r")){
                    userPiece = 0;
                    System.out.println("You Chose: Rock");
                    validUserIn = true;
                }
                    else if (userInput.equalsIgnoreCase("p")){
                        userPiece = 1;
                        System.out.println("You Chose: Paper");
                        validUserIn = true;
                    }
                        else if (userInput.equalsIgnoreCase("s")) {
                            userPiece = 2;
                            System.out.println("You Chose: Scissors");
                            validUserIn = true;
                        }  
                        else {
                            System.out.println("Invalid Choice.");
                            validUserIn = false;
                        } 
                } // end while loop 
            return userPiece;
            } // end class UserPiece ~ End User Input Validation & Return
            
            
            // Computer Choice Calculation & Print ~ Start
            public static int ComputerChoice(){
            Random random = new Random();
            int choiceStart;
            choiceStart = random.nextInt(3); // max number 3 ~ 0-2
            int computerInput = 0;
            String computerPiece = null;
            
            switch (choiceStart) {
                case 0:
                    computerInput = 0; 
                    computerPiece = "Rock";
                    break;
                case 1:
                    computerInput = 1; //Paper
                    computerPiece = "Paper";
                    break;
                case 2:
                    computerInput = 2; //Scissors
                    computerPiece = "Scissors";
                    break;
            } // end switch
            System.out.println("*************************************");
            System.out.println("*************************************");
            System.out.println("The computer has decided as well...");
            System.out.println("|||||||||||||||||||||||||||||||||||||");
            System.out.println("|||||||||||||||||||||||||||||||||||||");
            System.out.println("The computer's choice was " +computerPiece+ "...");
            System.out.println("*************************************");
            System.out.println("*************************************");
            return computerInput;    
            } // end class ComputerChoice ~ End Computer Choice Calculation & Print
            
            
            // Calculate Game & Return Win/Loss/Tie ~ Calculations
            public static String Game(){
                int user = P1Choice();
                int computer = ComputerChoice();
                String error = "*** If you are reading this, there has been a"
                        +" system error. Please restart the program. ***";
                
                // 0 = rock
                // 1 = paper
                // 2 = scissors
                if (user == 0) {
                    if (computer != 1){
                        if (computer != 0){
                            return "Win";
                        }
                        return "Tie";
                    }
                    return "Lose";
                } // end first nested for loop logic
                if (user == 1){
                    if (computer != 2){
                        if (computer != 1) {
                            return "Win";
                        }
                        return "Tie";
                    }
                    return "Lose";       
                } // end second nested for loop logic
                if (user == 2){
                    if (computer != 0){
                        if (computer != 2) {
                            return "Win";
                        }
                        return "Tie";
                    }
                    return "Lose";       
                } // end third nested for loop logic
                return error; // null  -- Needed to return something 
                // -- better practice teacher?
            } // end class Game ~ End Calculate Game & Return     
    } // end class RPS

```

Réponses

10 user985366 Oct 03 2020 at 06:46

Formatage du code

Vous rencontrez des problèmes de formatage et d'indentation. Veuillez exécuter votre code via un formateur, par exemple celui-ci

https://www.tutorialspoint.com/online_java_formatter.htm

pour le rendre plus lisible et respecter les normes.

Logique

while (playAgain = true) {

C'est faux, c'est censé l'être ==, non =. Cela fonctionne de toute façon puisque ce que vous faites est simplement de définir la playAgainvariable à truela première exécution, qui est la même valeur qu'elle a déjà, et puisque pendant la whileboucle, il vérifie la valeur de vérité de playAgain.

while(playAgain) est équivalent à while(playAgain == true)

commentaires

    } // end while 
} // end switch 

Ces commentaires sont dans le mauvais ordre. Le switchest à l'intérieur du while, donc il se termine en premier. Mais vous ne devriez pas du tout avoir besoin de ces commentaires. Si vous utilisez un bon éditeur de code et une indentation appropriée, vous verrez facilement (et obtiendrez une mise en surbrillance automatique) sur quel crochet correspond lequel. Je suggère d'utiliser un éditeur tel que IntelliJ ou Visual Studio Code.

Logique 2

Le code gagnant / perdant / égalité est très long et compliqué.

Tout d'abord, pour les cravates, vous pouvez simplement vérifier

if (user == computer) {
    return "Tie";
}

Cela couvre toutes les combinaisons qui créent une cravate. Avec ces cas à l'écart, la logique restante devient plus simple.

Puisque le papier bat le rock (1 temps 0) et les ciseaux bat le papier (2 temps 1), avec vos définitions de nombres pratiques, vous pouvez ensuite vérifier user == computer + 1, mais nous avons également besoin de l'étui pour les ciseaux rock beats.

if (user == computer + 1 || user == 0 && computer == 2) {
    return "Win";
}

Puisque nous avons maintenant couvert tous les cas d'égalité ou de victoire, tout autre cas perdra

else {
    return "Lose";
}
8 Doi9t Oct 04 2020 at 07:45

Convention de dénomination Java

Le nom de la méthode doit toujours commencer par une minuscule.

  • WelcomeP1 -> welcomeP1
  • P1Choice -> p1Choice
  • ComputerChoice -> computerChoice
  • Game -> game

Utilisez java.io.PrintStream#printfplutôt que java.io.PrintStream#printlnlorsque vous devez concaténer

java.io.PrintStream#printfvous propose d'utiliser des modèles pour construire la chaîne sans la concaténer manuellement. Le seul inconvénient est que vous serez obligé d'ajouter vous-même le caractère de ligne de rupture; en java, vous pouvez utiliser le %npour briser la ligne (portable entre différentes plates-formes) ou utiliser le traditionnel \n/ \r\n.

Avant

System.out.print("-------------> You " + game() + "!!!");

Après

System.out.printf("-------------> You %s!!!",  game());

Avant

System.out.println("The computer's choice was " + computerPiece + "...");

Après

System.out.printf("The computer's choice was %s...%n", computerPiece); //With a new line

Utilisez toujours les primitives lorsque cela est possible

Lorsque vous savez qu'il est impossible d'obtenir une valeur nulle avec le nombre, essayez d'utiliser les primitives; cela peut empêcher le déballage de la valeur dans certains cas.

Dans votre code, vous pouvez remplacer le Booleanà booleanpuisque vous n'avez que les valeurs trueet false.

Extrayez une partie de la logique des méthodes.

Lorsque vous avez une logique qui fait la même chose, vous pouvez généralement la déplacer dans une méthode et la réutiliser.

Vous pouvez extraire une partie de la logique qui demande si l'utilisateur souhaite jouer à Rock, Paper ou Scissors dans une méthode et la réutilise.

private static String askIfWantToPlay(Scanner scanner) {
   String userPlay = "";
   while (userPlay.isEmpty()) {
      System.out.println("Do you want to play Rock, Paper, Scissors?");
      System.out.println("Please press y for (Y)es \nor n for (N)o: ");
      userPlay = scanner.next().trim();
   }
   return userPlay;
}

Cette méthode supprimera certaines duplications.

Si vous le souhaitez, vous pouvez centraliser la logique de sortie dans cette nouvelle méthode; vérifiez si l'utilisateur souhaite quitter ou non.

private static void askIfWantToPlayAndExitOtherwise(Scanner scanner) {
   String userPlay = "";

   while (!"n".equalsIgnoreCase(userPlay) && !"y".equalsIgnoreCase(userPlay)) {
      System.out.println("Do you want to play Rock, Paper, Scissors?");
      System.out.println("Please press y for (Y)es \nor n for (N)o: ");
      userPlay = scanner.next();
   }

   if ("y".equalsIgnoreCase(userPlay)) {
      System.exit(0);
   } else {
      System.out.println("*************************************");
      System.out.println("Excellent! Thank you...\nLet's Play!");
   }
}

Avec cette méthode, le code est plus facile à lire et ne propage pas la logique partout dans l'application; vous pouvez faire la même chose avec le choix de l'utilisateur pour les ciseaux (R) ock, (P) aper ou (S) et ne renvoyer qu'un choix valide.

5 ZoranJankov Oct 06 2020 at 18:45

Je peux être d'accord avec l'ensemble des deux réponses précédentes, mais je dois aborder la question de la mise en œuvre de la logique du jeu elle-même. Il se trouve que nous comprenons la logique de jeu du jeu parce que nous connaissons tous le jeu, mais si nous regardons le code, il est difficile d'extraire la logique du jeu du code. Il n'est pas écrit de manière claire et facile à comprendre, en particulier avec l' ifimbrication profonde des instructions.

public static String Game(){
                int user = P1Choice();
                int computer = ComputerChoice();
                String error = "*** If you are reading this, there has been a"
                        +" system error. Please restart the program. ***";
                
                // 0 = rock
                // 1 = paper
                // 2 = scissors
                if (user == 0) {
                    if (computer != 1){
                        if (computer != 0){
                            return "Win";
                        }
                        return "Tie";
                    }
                    return "Lose";
                } // end first nested for loop logic
                if (user == 1){
                    if (computer != 2){
                        if (computer != 1) {
                            return "Win";
                        }
                        return "Tie";
                    }
                    return "Lose";       
                } // end second nested for loop logic
                if (user == 2){
                    if (computer != 0){
                        if (computer != 2) {
                            return "Win";
                        }
                        return "Tie";
                    }
                    return "Lose";       
                } // end third nested for loop logic
                return error; // null  -- Needed to return something 
                // -- better practice teacher?
            } // end class Game ~ End Calculate Game & Return     
    } // end class RPS

J'ai trouvé un moyen d'implémenter cette logique de jeu de manière plus claire et plus facile à lire et à comprendre.

Utiliser des énumérations

Les énumérations peuvent grandement contribuer à la clarté du code

public enum PlayedMove
{
    ROCK,
    PAPER,
    SCISSORS;
}

Ils sont explicites

public enum Winer
{
    DRAW,
    PLAYER,
    COMPUTER;
}

La nouvelle logique de jeu

Comme si vous l'expliquiez à un homme et non à un ordinateur

public class GameLogic
{
    public static Winer getWiner(PlayedMove player, PlayedMove computer)
    {
        if (player == computer)
        {
            return Winer.DRAW;
        }
        else if (isPlayerWiner(player, computer))
        {
            return Winer.PLAYER;
        }
        else
        {
            return Winer.COMPUTER;
        }
    }
    
    private static boolean isPlayerWiner(PlayedMove player, PlayedMove computer)
    {
        return ((player == PlayedMove.ROCK && computer == PlayedMove.SCISSORS)
             || (player == PlayedMove.SCISSORS && computer == PlayedMove.PAPER)
             || (player == PlayedMove.PAPER && computer == PlayedMove.ROCK));
    }
}