JavaScriptでジャンケンゲームのWEBアプリを作る

# はじめに
このアプリはJavaの学習を目的として作ったためJavaのフレームワークであるSpringBootをもとに制作されています。しかし、ジャンケンの判定を行うギミックとHTMLに出力するコードは全てJavaScriptで記述されているため、Javaに依存する箇所はコントローラーとルーティングのみになっています

## 見本

![スクリーンショット 2023-10-18 18.00.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2765288/643c6a9a-64e9-76e1-2e54-8d57cd97e0cc.png)


## HTML

```index.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">

	<!-- Bootstrap CSS -->
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
	
	<!-- Optional JavaScript -->
	<!-- jQuery, Popper.js (Bootstrap's dependency), and Bootstrap JS -->
	<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
	<script src="https://cdn.jsdelivr.net/npm/popper.js@2.9.2/dist/umd/popper.min.js"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
    <title>じゃんけんアプリ</title>
</head>
<body>
    <h1>じゃんけんアプリへようこそ！</h1>

    <p>
    <!-- クリックした場合に、play関数を実行してrock,scissors,paperの引数を渡す -->
	    <button onclick="play(`rock`)" class="btn btn-primary">グー</button>
	    <button onclick="play('scissors')" class="btn btn-success">チョキ</button>
	    <button onclick="play('paper')" class="btn btn-warning">パー</button>
	</p>

	<h2>ボタンを押してください</h2>
	
	<p>コンピューターの手</p>
    <!-- コンピュータの選択を表示するための画像 -->
	<img id="computerChoiceImg" width="150" src="">

	<p>あなたの手</p>
    <!-- ユーザーの選択を表示するための画像 -->
	<img id="yourChoiceImg" width="150" src="">
	
	<div id="history"></div>

	<!-- ジャンケンに関するギミックを記述 -->
	<script th:src="@{/js/janken.js}"></script>
</body>
</html>

```

## JavaSqript（じゃんけんの動作部分）

```js:src/main/resources/tstatic/js/janken.js
function play(userChoice) {
    // 利用可能な選択肢を配列として定義
    const choices = [`rock`, `scissors`, `paper`];

    // コンピュータの選択をランダムに決定
    const computerChoice = choices[Math.floor(Math.random() * 3)];

    let result = ``;

    // ユーザとコンピュータの選択を比較して結果を判定
    if (userChoice === computerChoice) {
        result = `引き分け！`;
    } else if (
        (userChoice === `rock` && computerChoice === `scissors`) ||
        (userChoice === `scissors` && computerChoice === `paper`) ||
        (userChoice === `paper` && computerChoice === `rock`)
    ) {
        result = `あなたの勝ち！`;
    } else {
        result = `あなたの負け…`;
    }

    // 
    
    // 英語の選択を日本語に変換するためのマッピングオブジェクト
    const choiceMapping = {
        'rock' : 'グー',
        'scissors' : 'チョキ',
        'paper' : 'パー'
    };

    // マッピングオブジェクトとは、
    //ある値と別の値を対応させるためのオブジェクトです。
    // 例えば、英語と日本語を対応させたい場合、
    // マッピングオブジェクトを使って
    // {'apple': 'りんご', 'banana': 'バナナ'} のように記述します。
    // これで、「apple」を入れると「りんご」が返ってくるようになります。
    // これは、異なる２つの情報を簡単に対応させるのに非常に便利な方法です。

    // 選択に対応する画像のURLを保持するオブジェクト
    const choiceImage = {
        'rock':`/img/rock.png`,
        'scissors':'/img/scissors.png',
        'paper':'/img/paper.png'
    };

    // コンピュータの選択を日本語に変換
    const computerChoicejapanese = choiceMapping[computerChoice];
    // choiceMapping[computerChoice] は、
    // computerChoice で指定されたキーに対応する値を 
    // choiceMapping オブジェクトから取得します。
    // つまり、コンピュータの選んだ手が英語で rock ならば、
    // choiceMapping[rock] として グー を取得することになります。

    // 結果テキストの作成
    const resultText = `コンピューターの選択： ${computerChoicejapanese}.　結果: ${result}`;
    // バッククォート（``）で囲まれた文字列内で、
    // ドル記号と波括弧（${}）を使うことで変数の値を埋め込むことができます。

    // ユーザの選択を画像で表示
    const yourChoiceImg = document.getElementById(`yourChoiceImg`);
    // yourChoiceImgというID属性を持ったタグを使用できるように代入する
    yourChoiceImg.src = choiceImage[userChoice];

    // コンピュータの選択を画像で表示
    const computerChoiceImg = document.getElementById(`computerChoiceImg`);
    computerChoiceImg.src = choiceImage[computerChoice];

    // 結果を履歴として追加
    const historyElement = document.createElement('p');
    historyElement.innerText = resultText;

    // 履歴をDOMに追加
    const addHistory = document.getElementById('history');
    addHistory.appendChild(historyElement); 
}

```

## コントローラー（ルーティング）
```java:src/main/java/Janken/JankenController.java
package Janken;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class JankenController {

	 @GetMapping("/")
	    public String index() {
	        
	        return "index";
	    }

   
}


```

## JavaSqriptを用いてHTMLを書き換える方法

JavaScriptを使ってHTMLを書き換える一般的な手順は、まず`HTML要素をJavaScriptで取得して任意の変数に代入します。`次に、その変数を通じて要素のプロパティ（例：imgタグのsrc属性)やメソッド(例：appendChildで要素を追加）を操作することで、要素のテキストや画像などを変更できます。

この手順を踏むことで、ユーザーが行った操作に応じてページの内容を変更したり、外部から取得したデータをページに表示したりといった、使いやすくて便利なウェブページを作ることができます。


### 要素の取得例

```javascript

// constは「constant（定数）」の略で、
// 変数に代入された値を変更できないようにするキーワードです。
// もし変数の値を途中で変更する必要がある場合は
// letキーワードを使用して変数を宣言します。

// すべてのp要素を取得
const pElements = document.querySelectorAll("p");

// idが"myP"のp要素を取得
const myPElement = document.getElementById("myP");

// すべてのh1要素を取得
const h1Elements = document.querySelectorAll("h1");

// classが"myH1"のh1要素を取得
const myH1Element = document.querySelector(".myH1");
```

```html:見本のHTML
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>HTMLとJavaScriptの例</title>
</head>

<body>
    <!-- 画像要素 -->
    <img id="exampleImg" src="path/to/old_image.jpg" alt="サンプル画像" width="200">

    <!-- テキストを変更するための段落要素 -->
    <p id="exampleP">元のテキスト</p>

    <!-- 新しい要素を追加するためのdiv要素 -->
    <div id="exampleDiv"></div>

    <script>

    <!-- ここにJavaSqriptのコードを記述するか、外部から呼び出す -->

    </script>
```





### 要素のプロパティとメソッドの例


```javascript

// imgタグの src 属性はプロパティの一つで、画像のURLを設定できます

// 以下のコードでHTMLから"exampleImg"というIDの要素を取得し
// srcプロパティを変更することでHTMLの画像を書き換えできます

const imgElement = document.getElementById('exampleImg');
imgElement.src = 'path/to/image.jpg';  // src属性を変更

// ==========================================================

// textContent や innerHTML などのプロパティを使うことで
// 要素のテキスト内容を変更することができます。
const pElement = document.getElementById('exampleP');
pElement.textContent = '新しいテキスト';  // テキスト内容を変更

// ===============================================================


// 新しい子要素を追加する場合はこれから追加する子要素を代入した変数と
// 対象となる親要素を代入した変数、それぞれが必要になります

//　子要素（p要素）を代入する変数
const newElement = document.createElement('p');
newElement.textContent = 'これは新しい子要素のp要素です';
// 親要素（対象）を代入する変数
const parentDiv = document.getElementById('exampleDiv');
parentDiv.appendChild(newElement);

```


## SpringBootアプリを実行する

お使いのIDEで`SpringBootアプリを実行`することでブラウザのローカルURLにWEBアプリを出力することができます

eclipseでSpringBootを実行した場合は次のURLになりました

http://localhost:8080/


# github

https://github.com/AlecTrippier/janken/tree/master/JankenApp