[Introduction to rock-paper-scissors games] Java

1.First of all

We will check the grammar and specifications of ** Java ** using the rock-paper-scissors (like) game that we made.

1-1. Game specifications

The rules follow the general rules of rock-paper-scissors. However, the player and COM have 5 points of physical strength, and if you win the rock-paper-scissors, you can do 1 point of damage to your opponent. The winner is the one who reduces the opponent's physical strength to 0 points or less first. No draw will occur and the process will continue until either the player or COM wins.

The processing content is displayed on the console, and the content displayed on the console is also output to the log file.

1-2. What is Java?

Java is a language developed by the once-existing US IT company ** Sun Microsystems (now Oracle America) **. Since the announcement of JDK 1.0 in January 1996, the version has been continuously upgraded, and Java SE 14 announced in March 2020 will be the latest version.

Tracing the origin of the language, it seems that the development originally started as an embedded language for home appliances based on C ++. However, in the middle of development, the embedded target has shifted from home appliances to PDAs, and it has also become a language for Web development. Perhaps because of such various fields, it has grown into an extremely versatile language used in a wide range of industries today. If you are familiar with it, it is also used in the development of Android applications. ~~ Kotlin "(No longer in the Java Paisen era)" ~~

Java has built up high reliability from its track record of being active on the front lines for over 20 years, but due to the rise of the JVM language and ~~ Oracle's announcement method was bad ~~ "Paid from Java SE 11" It is undeniable that the popularity of Java has been bathed in cold water due to the widespread misunderstanding that it will be done !?

However, demand is still one of the highest in all languages, and even if the options for new development projects are removed, system maintenance and repair projects written in Java will remain, so we will continue to do so in the future. There is no doubt that it will continue to be used for decades.

1-3. Development environment construction procedure

To build a Java development environment, use a package called ** JDK (Java Development Kit) , which is a collection of programs required for Java development, or an IDE that includes a JDK ( Eclipse ** and ** IntelliJ IDEA ** are the major ones).

In this article, we will explain the procedure for building a development environment using ** OpenJDK (strictly speaking, OpenJDK 14x series) **, which is one of the JDKs announced by various organizations.

** * This is a commentary for Windows 10 64bit version. We have not confirmed the operation in other environments. ** **

1-3a. Download OpenJDK

First, let's download OpenJDK. Go to the site that handles OpenJDK.

OpenJDK

In the block under the heading ** Download ** in the center of the site, there is a link to jump to the OpenJDK 14x download page. Click the link to go to the target page.

JDK 14.0.1 GA Release

Near the center of the download page, there is a download link for the JDK corresponding to each OS of Linux, macOS, and Windows. Click the JDK for Windows link to start the download. I was able to download the fucking small fish Wi-Fi at my home in about 1 minute, so if it is an average level Wi-Fi or wired, it should be completed immediately.

The downloaded file should be compressed in .zip format, so unzip it. The unzipped directory should have a directory with a name like ** jdk-14.0.1 **. This is the main body of OpenJDK, which contains the Java compiler and so on.

In the development environment construction work in other programming languages, it may be necessary to launch the installer etc. from here and proceed with the construction of the development environment, but in Java this is the end for the time being.

1-3b. Operation check

Check if OpenJDK has been downloaded and unzipped correctly.

First, place the main body of OpenJDK (a directory named ** jdk-14.0.1 **) directly under the C drive.

Next, make sure that the ** bin ** directories stored in that directory contain the ** java.exe ** and ** javac.exe ** executable files. The former is an application for executing programs written in Java, and the latter is a Java compiler.

To check the operation, launch a shell such as a command prompt or PowerShell, and try typing the command as shown below. It is OK when the following is displayed.

If it is displayed like this, it's OK


C:\jdk-14.0.1\bin> .\java.exe -version
openjdk version "14.0.1" 2020-04-14
OpenJDK Runtime Environment (build 14.0.1+7)
OpenJDK 64-Bit Server VM (build 14.0.1+7, mixed mode, sharing)

C:\jdk-14.0.1\bin>.\javac.exe -version
javac 14.0.1

C:\jdk-14.0.1\bin>

1-3c. Let's go through Path

You can develop Java in the above state, but let's put Path in the directory ** bin ** above so that it is easy to develop.

It's perfect if you can do this. Thank you for your hard work.

2. Special notes

As for the basic grammar, please read the source code at the end of the article, and note the things that cannot be read from the source code and the points to be noted.

2-1. Extension

The extension is **. Java **.

2-2. Character code

If you build the development environment according to the procedure described in this article (it seems to be different for each development environment), the standard character code will be ** MS932 **. MS932 is an extension of ** Shift JIS ** with a character code also known as ** windows-31j **. After all, if the source code does not include Japanese, you can write it in Shift JIS or UTF-8, and if the source code contains Japanese, you can write it in Shift JIS.

If you want to know the standard character code of your environment, please execute the following program.

Test.java


class Test {
    public static void main(String[] args) {
        System.out.println(System.getProperty("file.encoding"));
    }
}

By the way (this is the case with me), I think there are quite a few people who want to include Japanese in the source file, but want to write the character code in UTF-8. The Java compiler allows you to specify the character code at compile time, so refer to the following command.

UTF-Compile with 8


C:\Users\AGadget> javac .\Test.java -encoding UTF-8

2-3. Coding convention

It seems that Java coding standards have been announced by various organizations.

Isn't it better to refer to one of the coding standards?

2-4. Flow from compilation to execution

This section describes the procedure from compilation to execution.

First, prepare the source file. In Java, it seems to be a coding etiquette to store one class in one file and match the file name with the class name (Note: According to the poster). The sample files below follow this.

Test.java


class Test {
    public static void main(String[] args) {
        System.out.println("Hello world.");
    }
}

Once the source file is ready, compile it to generate an intermediate file (.class file).

compile


C:\Users\AGadget> javac .\Test.java

C:\Users\AGadget>

You should now have an intermediate file called ** Test.class **. Run this with java.exe.

Run


C:\Users\AGadget> java Test
Hello world.

C:\Users\AGadget>

The Java compilation / execution procedure is a little complicated, so please refer to another commentary article if necessary.

2-5. Compile by specifying the character code

In the development environment built by the procedure described in this article, the standard character code of the compiler is ** Shift JIS **. If you want to compile with any character code, hit the command as follows.

UTF-Compile with 8


C:\Users\AGadget> javac .\Test.javaa -encoding UTF-8

C:\Users\AGadget>

2-6. Entry point

Java entry points are the following methods.

public static void main(String[] args) {
    //This is the entry point
}

As a general rule, changing the above format-for example, changing ** public ** to ** private ** or changing the method name from ** main ** to ** Main ** will serve as an entry point. Please note that it will not be recognized.

2-7. All processing is contained in the class

Unlike languages that use classes in any language or languages that do not have classes in the first place, Java requires all processing to be stored in one of the classes. This also applies to the main method, which is the Java entry point, and you need to define a class to store the main method.

Main.java


/**
 *Main class containing the main method
 */
class Main {

    /**
     *Main method
     */
    public static void main(String[] args) {
        System.out.println("Hello world.");
    }
}

As an aside-this was one of the confusing specs when I first touched Java. Until then, I had only touched C / JavaScript, so this specification seemed quite strange. ~~ To be honest, I'm still not used to it. ~~

2-8. == Operator and equals method

In Java, the ** == operator ** is used to compare and determine whether the references are equal, and the ** equals method ** is used to compare and determine whether the values are the same.

Test.java


class Test {
    public static void main(String[] args) {
        StringBuilder a = new StringBuilder("Hello world.");
        StringBuilder b = new StringBuilder("Hello world.");
        System.out.println(a.toString() == b.toString());
        System.out.println(a.toString().equals(b.toString()));
    }
}

Try to run


C:\Users\AGadget> javac .\Test.java

C:\Users\AGadget> java Test
false
true

C:\Users\AGadget>

2-9. A return statement is required for all conditional branches in a method that has a return value.

See the example below.

Test.java


class Test {

    public static void main(String[] args) {
        System.out.println(testMethod("Windows Mobile"));
    }

    private static String testMethod(String OS) {
        if (OS.equals("AndroidOS")) {
            return "Android OS is the orientation";
        }
        if (OS.equals("iOS")) {
            return "iOS is the orientation";
        }
        if (OS.equals("BlackBerry")) {
            return "BlackBerry is oriented";
        }
        System.out.println("[Error]Winmo is NG. . . ");
        System.exit(0);
    }

}

At first glance, this program seems to compile without any problems, but it is actually played as a syntax error.

C:\Users\AGadget> javac .\Test.java
.\Test.java:19:error:No return statement specified
    }
    ^
1 error

C:\Users\AGadget>

In Java, it seems that when a method returns a return value, the return statement must be written with ** all possible branches **.

You can compile it by modifying it as follows.

Test.java


class Test {

    public static void main(String[] args) {
        System.out.println(testMethod("Windows Mobile"));
    }

    private static String testMethod(String OS) {
        if (OS.equals("AndroidOS")) {
            return "Android OS is the orientation";
        }
        if (OS.equals("iOS")) {
            return "iOS is the orientation";
        }
        if (OS.equals("BlackBerry OS")) {
            return "BlackBerry OS is the orientation";
        }
        System.out.println("[Error]Winmo is NG. . . ");
        System.exit(0);
        return "";    //Implemented because it is syntactically necessary
    }

}

3. Source code

Main.java


import java.util.Scanner;

/**
 *This is the main class of rock-paper-scissors games.
 * @author AGadget
 */
class Main {

    /**
     *This is the main method
     */
    public static void main(String[] args) {
        StandardIO standardIO = StandardIO.getInstance();
        Player player = new Player(5, "Qii Taro");
        COM com = new COM(5, "COM");
        TurnCount turnCount = new TurnCount();
        while (player.canGame() && com.canGame()) {
            turnCount.countUp();
            turnCount.printTurnCountMessage();
            player.printStatusMessage(com.getNameWidth());
            com.printStatusMessage(player.getNameWidth());
            standardIO.printlnEmptyLine(1);
            player.choiceAction();
            com.choiceAction();
            standardIO.printlnEmptyLine(1);
            standardIO.println(generateChoicedActionMessage(player.getAction(), com.getAction()));
            player.damageProcess(com.getAction());
            com.damageProcess(player.getAction());
            standardIO.printlnEmptyLine(5);
        }
        standardIO.println(generateGameResultMessage(player.canGame(), com.canGame(), player.getName(), com.getName()));
        standardIO.printlnEmptyLine(1);
        pause();
    }

    /**
     *A method that creates and returns a message that represents the action selected by both game characters.
     * @param action1 This is the action selected by game character 1.
     * @param action2 This is the action selected by game character 2.
     * @return message
     */
    private static String generateChoicedActionMessage(String action1, String action2) {
        return "> " + action1 + " vs " + action2;
    }

    /**
     *A method that creates and returns a message that represents the result of the game
     * @param canGame1 Flag for whether game character 1 can continue the game
     * @param canGame2 Flag for whether game character 2 can continue the game
     * @param name1 The name of the game character 1.
     * @param name2 The name of the game character 2.
     * @return message
     */
    private static String generateGameResultMessage(boolean canGame1, boolean canGame2, String name1, String name2) {
        if (canGame1 && !canGame2) {
            return "> " + name1 + "It ’s a victory!";
        }
        if (!canGame1 && canGame2) {
            return "> " + name2 + "It ’s a victory!";
        }
        System.out.println("[Error]A draw has occurred");
        System.exit(0);
        return "";    //I am writing a return statement that is unnecessary for processing because it causes a grammatical error
    }

    /**
     *A method that stops processing until the Enter key is pressed.
     */
    private static void pause() {
        System.out.print("Press enter. . . ");
        Scanner scanner = new Scanner(System.in);
        scanner.nextLine();
    }
}

StandardIO.java


import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.io.IOException;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 *This class is responsible for input / output to the console log file.
 *Adopts Singleton design pattern
 * @author AGadget
 */
class StandardIO {
    private static StandardIO instanceStandardIO = new StandardIO();    //It is an instance of this object
    private String logFilePath;    //The path of the log file

    /**
     *Is a constructor
     *Using Calendar object, log file name is created from the current date and time
     */
    private StandardIO() {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyMMddHHmmss");
        this.logFilePath = "log_" + simpleDateFormat.format(calendar.getTime()) + ".txt";
    }

    /**
     *A method that returns an instance of this object
     *This method is required because it uses the Singleton design pattern.
     * @return An instance of this object
     */
    public static StandardIO getInstance() {
        return instanceStandardIO;
    }

    /**
     *It is a method that outputs the character string specified in the argument to the console and log file.
     *A newline character is added to the end of the output value
     * @param message The output string
     */
    void println(String message) {
        System.out.println(message);
        try {
            FileWriter fileWriter = new FileWriter(this.logFilePath, true);
            PrintWriter printWriter = new PrintWriter(new BufferedWriter(fileWriter));
            printWriter.println(message);
            printWriter.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     *A method that outputs an arbitrary number of blank lines to the console and log file.
     *The number of lines can be specified by an argument
     * @param numberOfEmptyLine
     */
    void printlnEmptyLine(int numberOfEmptyLine) {
        for (int i = 0; i < numberOfEmptyLine; i += 1) {
            this.println("");
        }
    }

    /**
     *It is a method that outputs the character string specified in the argument to the console and log file.
     *There is no newline character at the end of the output value
     * @param message The output string
     */
    void print(String message) {
        System.out.print(message);
        try {
            FileWriter fileWriter = new FileWriter(this.logFilePath, true);
            PrintWriter printWriter = new PrintWriter(new BufferedWriter(fileWriter));
            printWriter.print(message);
            printWriter.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     *A method that accepts standard input, outputs the input value to a log file, and returns it to the caller.
     * @return Standard input value
     */
    String readLine() {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        this.printlnOnlyToLogFile(input);
        return input;
    }

    /**
     *It is a method that outputs the character string specified in the argument "only" to the log file.
     *→ It is assumed that it will be used as a set with the method in charge of standard input processing.
     *A newline character is added to the end of the output value
     * @param message The output string
     */
    private void printlnOnlyToLogFile(String message) {
        try {
            FileWriter fileWriter = new FileWriter(this.logFilePath, true);
            PrintWriter printWriter = new PrintWriter(new BufferedWriter(fileWriter));
            printWriter.println(message);
            printWriter.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

GameCharacter.java


/**
 *An abstract class that represents a game character
 * @author AGadget
 */
abstract class GameCharacter {
    protected StandardIO standardIO = StandardIO.getInstance();    //The object responsible for output processing
    private final int MAX_LIFE = 5;    //This is the upper limit of physical strength common to all game characters.
    private int life;    //It is physical strength
    private String name;    //Is the name
    protected final String[] ACTIONS = {"Goo", "Choki", "Par"};    //A list of actions you can choose
    protected String action;    //The action of choice

    /**
     *An abstract method to select an action
     *Please implement the process of selecting an action in some way and assigning the selected action to the field that holds the selected action.
     */
    abstract void choiceAction();

    /**
     *Is a constructor
     * @param initialLife Physical strength at the start of the game
     * @param name The name of the game character
     */
    GameCharacter(int initialLife, String name) {
        if (initialLife < 0 && initialLife > this.MAX_LIFE ? true : false) {
            System.out.println("[Error]The initial value at the start of the game is invalid (" + initialLife + ")");
            System.exit(0);
        }
        this.life = initialLife;
        this.name = name;
    }

    /**
     *A method that responds if the game can be continued
     * @return Returns true if possible
     */
    boolean canGame() {
        return this.life > 0 ? true : false;
    }

    /**
     *A method that returns the width of the name
     * String.length()Unlike the value that can be obtained by, etc., the value counted with half-width characters as 1 and full-width characters as 2 is returned.
     */
    int getNameWidth() {
        char[] nameToCharArray = this.name.toCharArray();
        int nameWidth = 0;
        for (int i = 0; i < nameToCharArray.length; i += 1) {
            nameWidth += String.valueOf(nameToCharArray[i]).getBytes().length == 1 ? 1 : 2;
        }
        return nameWidth;
    }

    /**
     *A method that returns a message about its own state
     *The message consists of a name part and a physical strength part
     *→ Make sure that the name part has the same length and width as the other party's name.
     *→ The physical strength part is expressed like a physical strength gauge using symbols.
     * @param opponentNameWidth The width of the opponent's name (a special value counted as 1 for half-width characters and 2 for full-width characters).
     */
    void printStatusMessage(int opponentNameWidth) {
        StringBuilder namePart = new StringBuilder(this.name);
        for (int i = 0; i < opponentNameWidth - this.getNameWidth(); i += 1) {
            namePart.append(" ");
        }
        StringBuilder lifePart = new StringBuilder();
        for (int i = 0; i < this.life; i += 1) {
            lifePart.append("■");
        }
        for (int i = 0; i < this.MAX_LIFE - this.life; i += 1) {
            lifePart.append("□");
        }
        standardIO.println(namePart.toString() + ": " + lifePart.toString());
    }

    /**
     *A method that returns the selected action
     * @return The selected action
     */
    String getAction() {
        return this.action;
    }

    /**
     *It is a method that handles damage
     *Check if damage occurs from the combination of your own and the opponent's actions, and if damage occurs, reduce your physical strength
     * @param opponentAction The action of the opponent
     */
    void damageProcess(String opponentAction) {
        if (this.action.equals(this.ACTIONS[0]) && opponentAction.equals(this.ACTIONS[2])
            || this.action.equals(this.ACTIONS[1]) && opponentAction.equals(this.ACTIONS[0])
            || this.action.equals(this.ACTIONS[2]) && opponentAction.equals(this.ACTIONS[1])
        ) {
            this.life -= 1;
            return;
        }
    }

    /**
     *A method that returns a name
     * @return name
     */
    String getName() {
        return this.name;
    }
}

Player.java


/**
 *A class that represents a player
 * @author AGadget
 */
class Player extends GameCharacter {

    /**
     *Is a constructor
     * @param initialLife Physical strength at the start of the game
     * @param name The name of the game character
     */
    Player(int initialLife, String name) {
        super(initialLife, name);
    }

    /**
     *A method to select an action
     *Since it is a process for players, I implemented a process using standard input
     */
    @Override
    void choiceAction() {
        String prompt = this.generatePrompt();
        while (true) {
            standardIO.print(prompt);
            String input = standardIO.readLine();
            try {
                this.action = this.ACTIONS[Integer.parseInt(input) - 1];
                return;
            } catch (Exception error) {
                standardIO.printlnEmptyLine(1);
                standardIO.println(">Illegal input");
                standardIO.println(">Please re-enter");
                standardIO.printlnEmptyLine(1);
            }
        }
    }

    /**
     *A method that creates and returns the prompt required for action selection processing.
     * @The string that will be the return prompt
     */
    private String generatePrompt() {
        StringBuilder prompt = new StringBuilder();
        for (int i = 0; i < this.ACTIONS.length; i += 1) {
            prompt.append("[" + (i + 1) + "] " + this.ACTIONS[i] + "    ");
        }
        prompt.append(": ");
        return prompt.toString();
    }
}

COM.java


import java.util.Random;

/**
 *A class that represents COM
 * @author AGadget
 */
class COM extends GameCharacter {

    /**
     *Is a constructor
     * @param initialLife Physical strength at the start of the game
     * @param name The name of the game character
     */
    COM(int initialLife, String name) {
        super(initialLife, name);
    }

    /**
     *A method to select an action
     *Since it is a process for COM, we implemented a process that uses random numbers.
     */
    @Override
    void choiceAction() {
        Random random = new Random();
        this.action = ACTIONS[random.nextInt(ACTIONS.length)];
    }
}

TurnCount.java


/**
 *A class that represents the number of turns
 * @author AGadget
 */
class TurnCount {
    private StandardIO standardIO = StandardIO.getInstance();    //The object responsible for output processing
    private int turnCount;    //The number of turns

    /**
     *Is a constructor
     */
    TurnCount() {
        turnCount = 0;
    }

    /**
     *It is a method to advance the count of the number of turns
     */
    void countUp() {
        this.turnCount += 1;
    }

    /**
     *A method that outputs the current number of turns as a message
     */
    void printTurnCountMessage() {
        standardIO.println("[No." + this.turnCount + "turn】");
    }
}

Recommended Posts

[Introduction to rock-paper-scissors games] Java
[Java] Introduction to Java
Introduction to java
Introduction to java command
[Java] Introduction to lambda expressions
[Java] Introduction to Stream API
[Java] Introduction
java rock-paper-scissors
[Introduction to Java] About lambda expressions
[Introduction to Java] About Stream API
Introduction to Functional Programming (Java, Javascript)
Initial introduction to Mac (Java engineer)
Introduction to Ruby 2
Introduction to java for the first time # 2
Introduction to SWING
Introduction to algorithms with java --Search (depth-first search)
[Introduction to Java] How to write a Java program
Rock-paper-scissors in Java
Introduction to web3j
Introduction to Micronaut 1 ~ Introduction ~
Introduction to migration
Output of the book "Introduction to Java"
[Introduction to Java] Variable declarations and types
Introduction to Doma
Introduction to Java Web Apps Performance Troubleshooting
Introduction to algorithms with java --Search (breadth-first search)
[Introduction to Java] About type conversion (cast, promotion)
Introduction to algorithms with java --Search (bit full search)
Road to Java Engineer Part1 Introduction & Environment Construction
[Monthly 2017/04] Introduction to groovy !! ~ Java grammar / specification comparison ~
[Introduction to Java] Basics of java arithmetic (for beginners)
Java Performance Chapter 1 Introduction
Rock-paper-scissors app in Java
Introduction to JAR files
Changes from Java 8 to Java 11
Sum from Java_1 to 100
Introduction to Ratpack (8)-Session
Introduction to RSpec 1. Test, RSpec
Introduction to bit operation
Introduction to Ratpack (6) --Promise
Introduction to Ratpack (9) --Thymeleaf
[Java] Connect to MySQL
Rock-paper-scissors game java practice
Introduction to PlayFramework 2.7 ① Overview
Introduction to Android Layout
Introduction to design patterns (introduction)
Kotlin's improvements to Java
Introduction to Practical Programming
Introduction to javadoc command
From Java to Ruby !!
Introduction to jar command
Introduction to Ratpack (2)-Architecture
Introduction to lambda expression
Introduction to RSpec 2. RSpec setup
Introduction to Keycloak development
Introduction to javac command
[Java] How to play rock-paper-scissors (equivalent to paiza rank A)
Introduction to Java for beginners Basic knowledge of Java language ①
Introduction to Design Patterns (Builder)
Introduction to Effective java by practicing and learning (Builder pattern)
How to lower java version