Як написати гру "Камінь, ножиці, папір" на Java

" камінь, ножиці, папір» – це гра «на пальцях» для двох. Гравці разом говорять " камінь, ножиці, папір» і викидають вперед руку, пальцями формуючи одну з трьох фігур (камінь, ножиці або папір). Переможець визначається наступним чином: ножиці б'ють папір, папір б'є камінь, камінь б'є ножиці. Якщо обидва гравці показують одну і ту ж фігуру, це вважається нічиєю. Ми напишемо просту гру на Java, яка дозволить грати в " Камінь, ножиці, папір» з комп'ютером.

Кроки

  1. Створіть основний клас і назвіть йогоRockPaperScissors. У цьому класі ми опишемо гру. Ви можете назвати його інакше, наприклад Game абоMain . Напишіть оголошення конструктора і методу main.

    Public Class RockPaperScissors {
        Public RockPaperScissors() {
            
        }
        
        Public Static Void Main(String[] Args) {
            
        }
    }
    
  2. Створіть список (enum) для опису можливих ходів (камінь, ножиці, папір). Ми можемо задати ходи рядками, але перерахування дозволяє нам зумовити константи, тому використання enum краще. Назвемо наше перерахування Move і задамо значення ROCK, PAPERі SCISSORS.

    Private Enum Move {
        ROCK, PAPER, SCISSORS
    }
    
  3. Створіть два закритих (ключове слово private) класуUser і Computer.ці класи представлятимуть гравців. Ви також можете зробити ці класи відкритими (ключове слово public). Клас User буде запитувати у користувача, який хід він робить-камінь, ножиці або папір – тому нам потрібно написати метод getMove(). Клас Computer також повинен мати метод getMove (), щоб ми могли отримати хід комп'ютера. Поки що ми просто оголосимо ці методи, а реалізацію напишемо пізніше. Клас User повинен мати конструктор, в якому ініціалізується об'єкт Scanner, який буде зчитувати введення користувача. Оголосимо Scanner закритим членом даних класу User і ініціалізуємо його в конструкторі. Оскільки ми збираємося використовувати клас Scanner, ми повинні підключити його, використовуючи ключове слово import . КласуComputer конструктор не потрібен, тому ми не будемо його писати; при ініціалізації об'єкта Computer ми просто викличемо конструктор за замовчуванням. Ось як клас RockPaperScissors виглядає зараз:

    Import Java.util.Scanner;
    
    Public Class RockPaperScissors {
        Private Enum Move {
            ROCK, PAPER, SCISSORS
        }
        
        Private Class User {
            Private Scanner InputScanner;
            
            Public User() {
                InputScanner = New Scanner(System.In);
            }
            
            Public Move GetMove() {
             / / TODO: реалізація методу
                Return Null;
            }
        }
        
        Private Class Computer {
            Public Move GetMove() {
                / / TODO: реалізація методу
                Return Null;
            }
        }
        
        Public RockPaperScissors() {
            
        }
        
        Public Static Void Main(String[] Args) {
            
        }
    }
    
  4. Напишіть реалізацію методуgetMove () для класуComputer . цей метод буде повертати випадкове значення Move. Ми можемо отримати масив значень Move викликавши метод values () ось так: Move.values(). Щоб вибрати випадкове значення Move з цього масиву, нам потрібно згенерувати випадковий Індекс між 0 і кількістю елементом масиву. Для цього викличемо метод nextInt () класу Random, який ми підключимо так: import java.util.Random. Отримавши випадковий Індекс, повернемо значення Move з цим індексом в нашому масиві.

    Public Move GetMove() {
        Move[] Moves = Move.Values();
        Random Random = New Random();
        Int Index = Random.NextInt(Moves.Length);
        Return Moves[Index];
    }
    
  5. Напишіть реалізацію методуgetMove () для класу User. цей метод буде повертати значенняMove відповідне введенню користувача. Користувач може ввести "камінь", "ножиці", або "папір". Спочатку виведемо повідомлення: System.out.print ("камінь, ножиці або папір?"). Потім, за допомогою методу nextLine () об'єкта Scanner, ми отримаємо введення користувача у вигляді рядка. Тепер потрібно перевірити коректність введення користувача. Однак ми не буде звертати увагу на помилки, а просто перевіримо першу букву «К», «Н» або «Б». Також ми не будемо звертати увагу на регістр букв, так як, попередньо, ми викличемо метод toUpperCase() класу String, приводячи введення користувача до верхнього регістру. Якщо Користувач не ввів навіть приблизно коректний вибір, запитаємо його хід ще раз. Потім, залежно від введення користувача, наш метод поверне відповідне значення Move.

    Public Move GetMove() {
        // виведемо запит на введення
        System.Out. Print(" камінь, ножиці або папір? ");
    
        / / прочитаємо введення користувача
        String UserInput = InputScanner.NextLine();
        UserInput = UserInput.ToUpperCase();
        Char FirstLetter = UserInput.CharAt(0);
        If (FirstLetter == 'до' || FirstLetter == 'н' || Firstletter == 'б') {
            / / введення коректний
            Switch (FirstLetter) {
            Case 'к':
                Return Move.ROCK;
            Case 'Н':
                Return Move.PAPER;
            Case 'Б':
                Return Move.SCISSORS;
            }
        }
        
        / / введення некоректне. Виведемо запит на введення знову.
        Return GetMove();
    }
    
  6. Напишіть реалізацію методуplayAgain () класуUser . Користувач повинен мати можливість грати знову і знову. Щоб визначити чи хоче користувач зіграти ще раз, напишіть метод playAgain(), який буде повертати значення типу bool і, таким чином, повідомляти грі чи хоче користувач зіграти ще раз. У цьому методі ми використовуємо об'єкт Scanner, який ми ініціалізували в конструкторі, щоб отримати" так " або " ні " від користувача. Ми всього лише перевіримо першу букву, якщо вона 'Д', значить, користувач хоче зіграти ще раз, будь-яка інша буква буде означати "ні".

    Public Boolean PlayAgain() {
        System.Out.Print(" хочете зіграти ще раз? ");
        String UserInput = InputScanner.NextLine();
        UserInput = UserInput.ToUpperCase();
        Return UserInput.CharAt(0) == ' Д ';
    }
    
  7. Зв'яжіть Код класуUser І класу Computer в класі RockPaperScissors. написавши код для класівUser І Computer, ми можемо зайнятися самою грою. Оголосіть класи User і Computer закритими членами даних класу RockPaperScissors. Ми будемо звертатися до них, викликаючи метод getMove (), щоб отримати ходи гравців. Ініціалізуйте їх у конструкторі класу RockPaperScissors. Також нам потрібно зберігати рахунок. Оголосіть userScore і computerScore, потім ініціалізуйте їх нулем. І, нарешті, створіть поле даних для зберігання кількості ігор, також ініціалізувавши його нулем.

    Private User User;
    Private Computer Computer;
    Private Int UserScore;
    Private Int ComputerScore;
    Private Int NumberOfGames;
    
    Public RockPaperScissors() {
        User = New User();
        Computer = New Computer();
        UserScore = 0;
        ComputerScore = 0;
        NumberOfGames = 0;
    }
    
  8. Доповніть перерахуванняMove методом, який буде порівнювати ходи і визначати переможця. напишемо код для методу compareMoves () який буде повертати 0, якщо ходи однакові, 1 – Якщо поточний хід б'є інший і -1 – якщо інший хід б'є поточний. Поточний хід представлений покажчиком this, а інший передається в параметрі otherMove. Це стане в нагоді для визначення переможця. Спочатку напишемо код визначає нічию і повертає 0, а потім напишемо інструкцію switch для визначення переможця.

    Private Enum Move {
        ROCK, PAPER, SCISSORS;
    
        /**
    * порівнює поточний хід з переданим в параметрі otherMove і визначає
    * перемогу, поразку або нічию.
    *
    * @param otherMove
    * хід, з яким порівнюється поточний
    * @return 1 якщо поточний хід б'є інший, -1 якщо інший хід б'є поточний,
    * 0 у разі нічиєї
    */
        Public Int CompareMoves(Move OtherMove) {
            / / нічия
            If (This == OtherMove)
                Return 0;
    
            Switch (This) {
            Case ROCK:
                Return (OtherMove == SCISSORS ? 1 : -1);
            Case PAPER:
                Return (OtherMove == ROCK ? 1 : -1);
            Case SCISSORS:
                Return (OtherMove == PAPER ? 1 : -1);
            }
    
            // цей код не повинен виконуватися ніколи
            Return 0;
        }
    }
    
  9. Оголосіть методstartGame () у класі RockPaperScissors.у цьому методі буде відбуватися гра. Почніть викликом методу System.out.println.

    Public Void StartGame() {
            System.Out. Println(" камінь, ножиці, папір!");
    }
    
  10. Отримайте ходи комп'ютера і Користувача. у методі startGame () викличте getMove () КЛАСІВ User і Computer , щоб отримати їх ходи.

    Move UserMove = User.GetMove();
    Move ComputerMove = Computer.GetMove();
    System.Out.Println("\пВаш хід" + UserMove + ".");
    System.Out.Println("хід комп'ютера" + ComputerMove + ".\n");
    
  11. Порівняйте хід комп'ютера і хід гравця, щоб визначити хто виграв. викличте метод compareMoves () перерахування Move, щоб визначити чи виграв Користувач. Якщо так, збільште його рахунок на 1. Якщо ні, збільште рахунок комп'ютера. У разі нічиєї рахунок залишається колишнім. Після цього збільште кількість зіграних ігор на 1.

    Int CompareMoves = UserMove.CompareMoves(ComputerMove);
    Switch (CompareMoves) {
    Case 0: / / нічия
        System.Out.Println(" нічия!");
        Break;
    Case 1: / / переміг гравець
        System.Out.Println(UserMove + " beats " + ComputerMove + ". Ви перемогли!");
        UserScore++;
        Break;
    Case -1: / / переміг комп'ютер
        System.Out.Println(ComputerMove + " beats " + UserMove + ". Ви програли.");
        ComputerScore++;
        Break;
    }
    NumberOfGames++;
    
  12. Запитайте користувача чи хоче він зіграти ще раз. якщо так, викличте метод startGame () ще раз. Якщо ж ні, викличте метод printGameStats (), який виведе статистику гри. Ми напишемо його реалізацію в наступному кроці.

    If (User.PlayAgain()) {
        System.Out.Println();
        StartGame();
    } Else {
        PrintGameStats();
    }
    
  13. Напишіть реалізацію методуprintGameStats () . цей метод буде виводити статистику гри: кількість перемог, поразок, нічиїх, кількість зіграних ігор і відсоток перемог гравця. Відсоток виграних ігор вважається так: (кількість перемог + (кількість нічиїх/2))/(кількість зіграних ігор). Цей метод використовує System.out.printf для форматованого виведення тексту.

    Private Void PrintGameStats() {
        Int Wins = UserScore;
        Int Losses = ComputerScore;
        Int Ties = NumberOfGames - UserScore - ComputerScore;
        Double PercentageWon = (Wins + ((Double) Ties) / 2) / NumberOfGames;
    
        / / висновок лінії
        System.Out.Print("+");
        PrintDashes(68);
        System.Out.Println("+");
    
        / / висновок заголовків таблиці
        System.Out.Printf("|  %6s  |  %6s  |  %6s  |  %12s  |  %14s  |\n",
                "перемога", "поразка", "нічия", "всього ігор", "відсоток перемог");
    
        / / висновок лінії
        System.Out.Print("|");
        PrintDashes(10);
        System.Out.Print("+");
        PrintDashes(10);
        System.Out.Print("+");
        PrintDashes(10);
        System.Out.Print("+");
        PrintDashes(16);
        System.Out.Print("+");
        PrintDashes(18);
        System.Out.Println("|");
    
        / / виведення значень
        System.Out.Printf("|  %6d  |  %6d  |  %6d  |  %12d  |  %13.2f%%  |\n",
                Wins, Losses, Ties, NumberOfGames, PercentageWon * 100);
    
        / / висновок лінії
        System.Out.Print("+");
        PrintDashes(68);
        System.Out.Println("+");
    }
    
  14. Почніть гру. в основному класі ініціалізуйте об'єкт RockPaperScissors і викличте його метод startGame ().

    Public Static Void Main(String[] Args) {
        RockPaperScissors Game = New RockPaperScissors();
        Game.StartGame();
    }
    
  15. Протестуйте гру.тепер, коли вся робота позаду, настав час скомпілювати і протестувати нашу гру!

Приклад програми

Import Java.util.Random;
Import Java.util.Scanner;

Public Class RockPaperScissors {
    Private User User;
    Private Computer Computer;
    Private Int UserScore;
    Private Int ComputerScore;
    Private Int NumberOfGames;

    Private Enum Move {
        ROCK, PAPER, SCISSORS;

            /**
* порівнює поточний хід з переданим в параметрі otherMove і визначає
* перемогу, поразку або нічию.
*
* @param otherMove
* хід, з яким порівнюється поточний
* @return 1 якщо поточний хід б'є інший, -1 якщо інший хід б'є поточний,
* 0 у разі нічиєї
*/
        Public Int CompareMoves(Move OtherMove) {
            / / нічия
            If (This == OtherMove)
                Return 0;

            Switch (This) {
            Case ROCK:
                Return (OtherMove == SCISSORS ? 1 : -1);
            Case PAPER:
                Return (OtherMove == ROCK ? 1 : -1);
            Case SCISSORS:
                Return (OtherMove == PAPER ? 1 : -1);
            }

           // цей код не повинен виконуватися ніколи

            Return 0;
        }
    }

    Private Class User {
        Private Scanner InputScanner;

        Public User() {
            InputScanner = New Scanner(System.In);
        }

        Public Move GetMove() {
            // виведемо запит на введення
    System.Out. Print(" камінь, ножиці або папір? ");

    / / прочитаємо введення користувача
    String UserInput = InputScanner.NextLine();
    UserInput = UserInput.ToUpperCase();
    Char FirstLetter = UserInput.CharAt(0);
    If (FirstLetter == 'до' || FirstLetter == 'н' || Firstletter == 'б') {
        / / введення коректний
        Switch (FirstLetter) {
        Case 'к':
            Return Move.ROCK;
        Case 'Н':
            Return Move.PAPER;
        Case 'Б':
            Return Move.SCISSORS;
        }
    }
    
      / / введення некоректне. Виведемо запит на введення знову.
      Return GetMove();
        }

        Public Boolean PlayAgain() {
            System.Out.Print(" хочете зіграти ще раз? ");
            String UserInput = InputScanner.NextLine();
            UserInput = UserInput.ToUpperCase();
            Return UserInput.CharAt(0) == 'Y';
        }
    }

    Private Class Computer {
        Public Move GetMove() {
            Move[] Moves = Move.Values();
            Random Random = New Random();
            Int Index = Random.NextInt(Moves.Length);
            Return Moves[Index];
        }
    }

    Public RockPaperScissors() {
        User = New User();
        Computer = New Computer();
        UserScore = 0;
        ComputerScore = 0;
        NumberOfGames = 0;
    }

    Public Void StartGame() {
        System.Out. Println(" камінь, ножиці, папір!");

        / / отримання ходів
        Move UserMove = User.GetMove();
        Move ComputerMove = Computer.GetMove();
        System.Out.Println("\пВаш хід" + UserMove + ".");
        System.Out.Println("хід комп'ютера" + ComputerMove + ".\n");

        / / порівняння ходів і визначення переможця
        Int CompareMoves = UserMove.CompareMoves(ComputerMove);
        Switch (CompareMoves) {
        Case 0: / / нічия
            System.Out.Println("Tie!");
            Break;
        Case 1: / / переміг гравець
    	System.Out.Println(UserMove + " beats " + ComputerMove + ". Ви перемогли!");
    	UserScore++;
   	 Break;
Case -1: / / переміг комп'ютер
   	 System.Out.Println(ComputerMove + " beats " + UserMove + ". Ви програли.");
    	ComputerScore++;
    	Break;
}
        NumberOfGames++;

        / / запропонуємо користувачеві зіграти ще раз
        If (User.PlayAgain()) {
            System.Out.Println();
            StartGame();
        } Else {
            PrintGameStats();
        }
    }

    /**
* висновок статистики. Нічиї враховуються як полпобеди
* при підрахунку відсотка перемог.
*/
    Private Void PrintGameStats() {
        Int Wins = UserScore;
        Int Losses = ComputerScore;
        Int Ties = NumberOfGames - UserScore - ComputerScore;
        Double PercentageWon = (Wins + ((Double) Ties) / 2) / NumberOfGames;
    
        / / висновок лінії
        System.Out.Print("+");
        PrintDashes(68);
        System.Out.Println("+");
    
        / / висновок заголовків таблиці
        System.Out.Printf("|  %6s  |  %6s  |  %6s  |  %12s  |  %14s  |\n",
                "WINS", "LOSSES", "TIES", "GAMES PLAYED", "PERCENTAGE WON");
    
        / / висновок лінії
        System.Out.Print("|");
        PrintDashes(10);
        System.

Ще почитати: