{"id":7915,"date":"2024-11-14T16:00:31","date_gmt":"2024-11-14T16:00:31","guid":{"rendered":"https:\/\/msgprogramator.sk\/?p=7915"},"modified":"2026-04-01T11:58:09","modified_gmt":"2026-04-01T11:58:09","slug":"rock-paper-scissors","status":"publish","type":"post","link":"https:\/\/msgprogramator.sk\/en\/rock-paper-scissors\/","title":{"rendered":"How to program an artificial intelligence (AI) game in Java &#8211; rock, paper, scissors"},"content":{"rendered":"<p>Who doesn\u2019t know the popular game Rock, Paper, Scissors we used to play as kids? But who would have thought back then that one day they would be able to program it in their favourite programming language, for example <a href=\"https:\/\/msgprogramator.sk\/en\/java\/\" target=\"_blank\" rel=\"noopener\">Java<\/a>.<\/p>\n<p>Few people know that Rock, Paper, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Rock_paper_scissors\" target=\"_blank\" rel=\"nofollow noopener\">Scissors<\/a> is a hand game that is said to have originated in China, from where it spread to Japan. There it originated in its modern form as we know it, and in the early 20th century it spread very quickly around the world.<\/p>\n<h2>Rock, paper, scissors rules<\/h2>\n<p>We certainly don&#8217;t need to imagine the rules of the game. But if there is anyone who doesn&#8217;t know it yet, we will briefly mention them.<\/p>\n<p>It is most often played by two players (or more), each of whom subconsciously chooses either a rock, paper or scissors. On the count of one, two, three, both players simultaneously show what they have chosen &#8211; rock (closed fist), or scissors (using index and middle fingers), or paper (open hand). The result of the game, which is of course played over multiple rounds, is a draw, a win, or a loss.<\/p>\n<p>The player who plays the stone beats the other player who chooses the scissors (the stone dulls the scissors), but loses to the player who played the paper (the paper covers the rock). The player with paper loses to the player who chose scissors (scissors cut the paper). If both players choose the same shape, the game is a tie and is usually repeated to break the tie.<\/p>\n<p>Rock, paper, scissors is often used as a method of fair selection among children when it comes to which child will start something first.<\/p>\n<p>Did you know that?<br \/>\nVarious competitive tournaments were also organized for Stone, Paper, Scissors. For example, the winners of the tournaments took home between $5,000 and $20,000.<\/p>\n<h2>Rock, paper, scissors in Java<\/h2>\n<p>Today we will program this game together in Java. To make this game more interesting for players to play, <strong>we will also program an artificial intelligence (AI)<\/strong> that will not randomly decide whether to use a rock, paper, or scissors in each round, but will choose one of the default strategies in each round. Of course the player will have no idea what gesture the computer AI has just chosen.<\/p>\n<h3>Interesting fact<\/h3>\n<p>You definitely don&#8217;t want to play Rock, Paper, Scissors with a robot. In 2012, researchers at the Ishikawa Watanabe Laboratory at the University of Tokyo created a robotic arm that can win any game against a human opponent. Using a high-speed camera, the robot recognizes within one millisecond what shape the human hand is making and then creates the corresponding winning shape.<\/p>\n<h2>Game concept with AI<\/h2>\n<p>The game will be played for a predefined number of rounds, which will be specified when the game instance is created. Since the game rounds are very fast and we want to test the behavior of the AI, we set the default value for the number of rounds to 20.<\/p>\n<p>At the start of each round we will need to record the player&#8217;s selection, select the AI strategy for that round and use that to determine the AI computer&#8217;s selection. The AI will choose randomly from the default strategies, making it difficult for the player to determine what gesture the computer will play.<\/p>\n<p>We then check who picked what and allocate points accordingly, +1 for a win, 0 for a draw or a loss. The first one to reach 20 points wins the game.<\/p>\n<h2>Game strategies for AI<\/h2>\n<p>The game&#8217;s artificial intelligence will record the player&#8217;s winning gestures and decide which gesture to play based on the history. Basic strategies will include:<\/p>\n<ul>\n<li>Random selection of gestures<br \/>\n<em>(RandomStrategy<\/em>)<\/li>\n<li>Repeat your gesture from the previous round<br \/>\n<em>(RepeatLastMoveStrategy<\/em>)<\/li>\n<li>Applying a counter-gesture to an opponent&#8217;s gesture from the previous round<em>(CounterLastPlayerMoveStrategy<\/em>)<\/li>\n<li>Repeating the most frequently played gesture by the opponent<em>(RepeatMostFrequentPlayerMoveStrategy<\/em>)<\/li>\n<li>Counter-gesture for the most frequently played gesture by the opponent<em>(CounterMostFrequentPlayerMoveStrategy<\/em>)<\/li>\n<\/ul>\n<p>People are still debating which game strategy is the best today. Our articles try to teach readers something new, show them how to solve some problems, and we&#8217;re most excited when they start experimenting with the program and coming up with their own game strategies. You can also get inspired by this <a href=\"https:\/\/www.youtube.com\/watch?v=rudzYPHuewc\" target=\"_blank\" rel=\"nofollow noopener\">video<\/a>, or by this <a href=\"https:\/\/remptongames.com\/2024\/08\/24\/how-to-win-rock-paper-scissors-and-why-it-matters-more-than-you-think\/\" target=\"_blank\" rel=\"nofollow noopener\">article on Rempton games<\/a> in English.<\/p>\n<p>So let&#8217;s get down to programming the game in Java.<\/p>\n<h2>Java Implementation of the game Rock, Paper, Scissors<\/h2>\n<p><a href=\"https:\/\/msgprogramator.sk\/en\/java-strategy\/\" target=\"_blank\" rel=\"noopener\">The <strong><em>Strategy<\/em><\/strong> design pattern<\/a> is well suited for implementing an AI strategy.<\/p>\n<p>This program will be a simple console game where the player chooses a rock, paper, or scissors and plays against the computer&#8217;s AI, which randomly chooses one of many strategies each round. The winner is determined based on the rules of the game.<\/p>\n<p><strong><u>Enum Move<\/u><\/strong><\/p>\n<p>Enum <strong><em>Move<\/em><\/strong> defines possible moves (rock, paper, scissors) and provides a method for comparing player and AI moves and a method for determining the best counter-move to a given move.<\/p>\n<pre><code class=\"language-java\" data-line=\"\">package games.rockpaperscissors;\n\npublic enum Move {\n    ROCK, PAPER, SCISSORS;\n\n    \/\/ Method to check who won\n    public static int compareMoves(Move player, Move ai) {\n        \/\/ Draw\n        if (player == ai) {\n            return 0;\n        }\n\n        switch (player) {\n            case ROCK:\n                \/\/ Rock beats Scissors, loses to Paper\n                return (ai == SCISSORS) ? 1 : -1;\n            case PAPER:\n                \/\/ Paper beats Rock, loses to Scissors\n                return (ai == ROCK) ? 1 : -1;\n            case SCISSORS:\n                \/\/ Scissors beats Paper, loses to Rock\n                return (ai == PAPER) ? 1 : -1;\n        }\n        return 0;\n    }\n\n    public static Move counterMove(Move move) {\n        switch (move) {\n            case ROCK:\n                return Move.PAPER;\n            case PAPER:\n                return Move.SCISSORS;\n            case SCISSORS:\n                return Move.ROCK;\n        }\n        throw new IllegalArgumentException();\n    }\n}<\/code><\/pre>\n<p><strong><u>Interface AIStrategy<\/u><\/strong><\/p>\n<p>Interface <strong><em>AIStrategy<\/em><\/strong> defines a <em>nextMove()<\/em> method that decides what move the AI will make based on history.<\/p>\n<p><strong>Specific Strategies<br \/>\n:<\/strong> AI has different strategies it can use. The strategy is chosen randomly before each round, which means that it is difficult for the player to predict what move the AI will choose.<\/p>\n<pre><code class=\"language-java\" data-line=\"\">package games.rockpaperscissors.ai.strategies;\n\nimport games.rockpaperscissors.Move;\nimport java.util.List;\n\npublic interface AIStrategy {\n    Move nextMove(List&lt;Move&gt; playerHistory, List&lt;Move&gt; aiHistory);\n}<\/code><\/pre>\n<p><strong><u>Class RandomStrategy<br \/>\n<\/u><\/strong>Random selection of a gesture.<\/p>\n<pre><code class=\"language-java\" data-line=\"\">package games.rockpaperscissors.ai.strategies;\n\nimport games.rockpaperscissors.Move;\nimport java.util.List;\nimport java.util.Random;\n\npublic class RandomStrategy implements AIStrategy {\n    private final Random random = new Random();\n\n    @Override\n    public Move nextMove(List&lt;Move&gt; playerHistory, List&lt;Move&gt; aiHistory) {\n        return Move.values()[random.nextInt(Move.values().length)];\n    }\n}<\/code><\/pre>\n<p><strong><u>Class RepeatLastMoveStrategy<br \/>\n<\/u><\/strong>Repeat the last gesture of the player.<\/p>\n<pre><code class=\"language-java\" data-line=\"\">package games.rockpaperscissors.ai.strategies;\n\nimport games.rockpaperscissors.Move;\nimport java.util.List;\n\npublic class RepeatLastMoveStrategy implements AIStrategy {\n    @Override\n    public Move nextMove(List&lt;Move&gt; playerHistory, List&lt;Move&gt; aiHistory) {\n        return aiHistory.isEmpty()\n                ? new RandomStrategy().nextMove(playerHistory, aiHistory)\n                : aiHistory.get(aiHistory.size() - 1);\n    }\n}<\/code><\/pre>\n<p><strong><u>Class CounterLastPlayerMoveStrategy<br \/>\n<\/u><\/strong>Counter-move to a player&#8217;s gesture from the previous round.<\/p>\n<pre><code class=\"language-java\" data-line=\"\">package games.rockpaperscissors.ai.strategies;\n\nimport games.rockpaperscissors.Move;\nimport java.util.List;\n\npublic class CounterLastPlayerMoveStrategy implements AIStrategy {\n    @Override\n    public Move nextMove(List&lt;Move&gt; playerHistory, List&lt;Move&gt; aiHistory) {\n        if(!playerHistory.isEmpty()) {\n            Move lastPlayer = playerHistory.get(playerHistory.size() - 1);\n            return Move.counterMove(lastPlayer);\n        }\n        return new RandomStrategy().nextMove(playerHistory, aiHistory);\n    }\n}<\/code><\/pre>\n<p><strong><u>Class RepeatMostFrequentPlayerMoveStrategy<br \/>\n<\/u><\/strong>Repeats the gesture that the player used most often.<\/p>\n<pre><code class=\"language-java\" data-line=\"\">package games.rockpaperscissors.ai.strategies;\n\nimport games.rockpaperscissors.Move;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class RepeatMostFrequentPlayerMoveStrategy implements AIStrategy {\n    @Override\n    public Move nextMove(List&lt;Move&gt; playerHistory, List&lt;Move&gt; aiHistory) {\n        if(!playerHistory.isEmpty()) {\n            Map&lt;Move, Integer&gt; moveFrequency = new HashMap&lt;&gt;();\n            for(Move move : playerHistory) {\n                moveFrequency.put(move, moveFrequency.getOrDefault(move, 0) + 1);\n            }\n            return Collections.max(moveFrequency.entrySet(), Map.Entry.comparingByValue()).getKey();\n        }\n        return new RandomStrategy().nextMove(playerHistory, aiHistory);\n    }\n}<\/code><\/pre>\n<p><strong><u>Class CounterMostFrequentPlayerMoveStrategy<br \/>\n<\/u><\/strong>The counter-move to the gesture that the player used most often.<\/p>\n<pre><code class=\"language-java\" data-line=\"\">package games.rockpaperscissors.ai.strategies;\n\nimport games.rockpaperscissors.Move;\nimport java.util.List;\n\npublic class CounterMostFrequentPlayerMoveStrategy implements AIStrategy {\n    @Override\n    public Move nextMove(List&lt;Move&gt; playerHistory, List&lt;Move&gt; aiHistory) {\n        if(!playerHistory.isEmpty()) {\n            Move mostFrequentMove = new RepeatMostFrequentPlayerMoveStrategy().nextMove(playerHistory, aiHistory);\n            \/\/ Counter the most frequent player&#039;s move\n            return Move.counterMove(mostFrequentMove);\n        }\n        return new RandomStrategy().nextMove(playerHistory, aiHistory);\n    }\n}<\/code><\/pre>\n<p><strong><u>RockPaperScissors class<br \/>\n<\/u><\/strong>Class <strong><em>RockPaperScissorsGame<\/em><\/strong> implements the overall game logic and manages the game flow, score recording and strategy selection.<\/p>\n<pre><code class=\"language-java\" data-line=\"\">package games.rockpaperscissors;\n\nimport games.rockpaperscissors.ai.strategies.*;\nimport java.util.*;\n\npublic class RockPaperScissors {\n    private final int totalRounds;\n    private final List&lt;Move&gt; playerHistory = new ArrayList&lt;&gt;();\n    private final List&lt;Move&gt; aiHistory = new ArrayList&lt;&gt;();\n    private int playerScore = 0;\n    private int aiScore = 0;\n\n    private final List&lt;AIStrategy&gt; aiStrategies = Arrays.asList(\n            new RandomStrategy(),\n            new RepeatLastMoveStrategy(),\n            new CounterLastPlayerMoveStrategy(),\n            new RepeatMostFrequentPlayerMoveStrategy(),\n            new CounterMostFrequentPlayerMoveStrategy()\n    );\n\n    public RockPaperScissors(int totalRounds) {\n        this.totalRounds = totalRounds;\n    }\n\n    private Move getPlayerMove(int input) {\n        switch (input) {\n            case 1:\n                return Move.ROCK;\n            case 2:\n                return Move.PAPER;\n            case 3:\n                return Move.SCISSORS;\n            default:\n                Move playerMove = new RandomStrategy().nextMove(playerHistory, aiHistory);\n                System.out.println(&quot;Chybny vstup, vyberam za hraca: &quot; + playerMove);\n                return playerMove;\n        }\n    }\n\n    public void play() {\n        Scanner scanner = new Scanner(System.in);\n        Random random = new Random();\n\n        while (playerScore &lt; totalRounds &amp;&amp; aiScore &lt; totalRounds) {\n            System.out.println(&quot;Vyber si: (1) Kamen, (2) Papier, (3) Noznice&quot;);\n            Move playerMove = getPlayerMove(scanner.nextInt());\n            Move aiMove = aiStrategies.get(random.nextInt(aiStrategies.size()))\n                    .nextMove(playerHistory, aiHistory);\n            System.out.println(&quot;HRAC vybral: &quot; + playerMove);\n            System.out.println(&quot;AI vybrala: &quot; + aiMove);\n\n            \/\/ Compare moves\n            int result = Move.compareMoves(playerMove, aiMove);\n            if (result &gt; 0) {\n                System.out.println(&quot;Vyhral si toto kolo.&quot;);\n                playerScore++;\n            } else if (result &lt; 0) {\n                System.out.println(&quot;AI vyhrala toto kolo.&quot;);\n                aiScore++;\n            }\n\n            \/\/ Record moves\n            playerHistory.add(playerMove);\n            aiHistory.add(aiMove);\n\n            System.out.println(&quot;Aktualne skore - Hrac: &quot; + playerScore + &quot; | AI: &quot; + aiScore);\n            System.out.println();\n        }\n\n        if(playerScore &gt;= totalRounds) {\n                System.out.println(&quot;Gratulujeme! Vyhral si tuto hru!&quot;);\n        }\n        else {\n            System.out.println(&quot;AI vyhrala tuto hru! Skus ju porazit.&quot;);\n        }\n    }\n}<\/code><\/pre>\n<p><strong><u>Main Class<\/u><\/strong><\/p>\n<pre><code class=\"language-java\" data-line=\"\">import games.rockpaperscissors.RockPaperScissors;\n\npublic class Main {\n    public static void main(String[] args) {\n        RockPaperScissors game = new RockPaperScissors(20);\n        game.play();\n    }\n}<\/code><\/pre>\n<h2>How the game works<\/h2>\n<ol>\n<li>The player chooses a move (rock, paper, scissors) using the input.<\/li>\n<li>The AI selects its strategy randomly and chooses a gesture based on that strategy.<\/li>\n<li>The game compares the moves and updates the score.<\/li>\n<li>The game continues until one player reaches 20 points.<\/li>\n<\/ol>\n<p>The output of a 3-round game can look like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-4762 size-full\" src=\"https:\/\/msgprogramator.sk\/wp-content\/uploads\/2024\/11\/vystup_hry_RockPaperScissors-1.webp\" alt=\"Rock Paper Scissors 3-Round Game Output\" width=\"456\" height=\"1364\" srcset=\"https:\/\/msgprogramator.sk\/wp-content\/uploads\/2024\/11\/vystup_hry_RockPaperScissors-1.webp 456w, https:\/\/msgprogramator.sk\/wp-content\/uploads\/2024\/11\/vystup_hry_RockPaperScissors-1-100x300.webp 100w, https:\/\/msgprogramator.sk\/wp-content\/uploads\/2024\/11\/vystup_hry_RockPaperScissors-1-342x1024.webp 342w\" sizes=\"auto, (max-width: 456px) 100vw, 456px\" \/><\/p>\n<p>In this Java game, the artificial intelligence plays very well and it is not so easy to win in a multi-round game.<\/p>\n<p>Here you can download the source code of <a href=\"https:\/\/msgprogramator.sk\/wp-content\/uploads\/2024\/11\/RockPaperScissors.zip\" target=\"_blank\" rel=\"noopener\">RockPaperScissors in Java.<\/a><\/p>\n<p>If you&#8217;re looking for a job and you&#8217;re a <a href=\"https:\/\/msg-life.sk\/en\/jobs\/java-programmer-senior\/\" target=\"_blank\" rel=\"noopener\">Java developer<\/a>, check out our <a href=\"https:\/\/msg-life.sk\/en\/benefits\/\" target=\"_blank\" rel=\"noopener\">employee benefits<\/a> and respond to our <a href=\"https:\/\/msg-life.sk\/en\/jobs\/\" target=\"_blank\" rel=\"noopener\">job offers<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article you will learn how to program the game Rock, Paper, Scissors in Java with artificial intelligence with different strategies.<\/p>\n","protected":false},"author":14,"featured_media":4728,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[57],"tags":[],"class_list":["post-7915","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/posts\/7915","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/users\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/comments?post=7915"}],"version-history":[{"count":3,"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/posts\/7915\/revisions"}],"predecessor-version":[{"id":42910,"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/posts\/7915\/revisions\/42910"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/media\/4728"}],"wp:attachment":[{"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/media?parent=7915"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/categories?post=7915"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/msgprogramator.sk\/en\/wp-json\/wp\/v2\/tags?post=7915"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}