アプリでジャンケンに強くなれるのか?試してみた!
2024-12-23 勉強会
皆さん、こんにちは!
突然ですが、皆さんには何かしらのトラウマがありませんか?
私の場合、それは「ジャンケン」です。
思い返せば、席替えや景品争奪戦でのジャンケンにことごとく敗北…。どうもジャンケンとは相性が悪いようです。「どうせジャンケンなんて運でしょ?」と思いながらも、勝つ人はなぜか勝ち続けます。例えば、社内イベントで連覇を成し遂げた某営業のS氏…。あれは偶然なのか、それとも実力なのか?
そんな疑問から、今回は「ジャンケン」をテーマに、自分の弱さを克服するためのアプリを試作してみました!
突然ですが、皆さんには何かしらのトラウマがありませんか?
私の場合、それは「ジャンケン」です。
思い返せば、席替えや景品争奪戦でのジャンケンにことごとく敗北…。どうもジャンケンとは相性が悪いようです。「どうせジャンケンなんて運でしょ?」と思いながらも、勝つ人はなぜか勝ち続けます。例えば、社内イベントで連覇を成し遂げた某営業のS氏…。あれは偶然なのか、それとも実力なのか?
そんな疑問から、今回は「ジャンケン」をテーマに、自分の弱さを克服するためのアプリを試作してみました!
ジャンケンの歴史と攻略法
ジャンケンの歴史
ジャンケンの起源は中国にあると言われています。「手拳(シューチュワン)」と呼ばれる遊びが、日本に伝わって江戸時代頃に現在の形へ進化しました。
その後、「野球拳」や「あっち向いてホイ」などの派生遊びが生まれ、ジャンケンは日本の文化として定着しました。
面白いことに、現在では世界中でジャンケンが意思決定手段として使わているようです。
その後、「野球拳」や「あっち向いてホイ」などの派生遊びが生まれ、ジャンケンは日本の文化として定着しました。
面白いことに、現在では世界中でジャンケンが意思決定手段として使わているようです。
ジャンケンの攻略法
ジャンケンには意外にも心理的なパターンが存在します。
【初手の選択傾向】 初心者は「グー」を選びやすい。対策として「パー」を出すと有利に!
【勝ち続ける心理】 勝者は次も同じ手を出す傾向が強い
【負けた後の行動】 敗者は手を変えやすいので、そのパターンを予測することが鍵
このように、ジャンケンは単なる運だけでなく、心理戦でもあるようです。
【初手の選択傾向】 初心者は「グー」を選びやすい。対策として「パー」を出すと有利に!
【勝ち続ける心理】 勝者は次も同じ手を出す傾向が強い
【負けた後の行動】 敗者は手を変えやすいので、そのパターンを予測することが鍵
このように、ジャンケンは単なる運だけでなく、心理戦でもあるようです。
まずは一人で研究できるアプリを!
試作:ジャンケン基本系
前回作成したランダム生成の仕組みを活用し、ジャンケンの基本型を構築しました。
さらに、以下の3画面をJSで作成し、アプリの体裁を整えました。
【言語】HTML5 CSS3 JS
さらに、以下の3画面をJSで作成し、アプリの体裁を整えました。
【言語】HTML5 CSS3 JS
ジャンケン基本系0号
1人じゃん拳プロトタイプ1号
JSで、スタート、プレイ、結果の3画面を用意して体裁を整えました。
シンプルにただジャンケンをするだけのアプりです。
【画面構成】
スタート画面
プレイ画面
結果画面
ここまでは前回の勉強会と被るので割愛します。
1人じゃん拳プロトタイプ2号
1人じゃん拳プロトタイプ3号
そして2号をさらに改良して、5回勝負にしました。
ジャンケンの思考パターンを分析するスクリプトを追加しパターンを読みます。
攻略の糸口になればと思い、ブラウザのコンソールをみながらCPUのパターンが
学べます。
これで、1人でもかなり戦略的に練習できるアプリが完成したかもしれません!
心理戦のロジックのポイント
★ジャンケンの攻略ロジックを組み込みました。
1.初手の傾向を活用。
2.勝敗に応じて: 前回の結果(勝者・敗者)を考慮して選択。
3.履歴分析: プレイヤー履歴を参考に最も有効な手を選択。
4.ランダム選択: パターンがない場合はランダムで決定。
1.初手の傾向を活用。
2.勝敗に応じて: 前回の結果(勝者・敗者)を考慮して選択。
3.履歴分析: プレイヤー履歴を参考に最も有効な手を選択。
4.ランダム選択: パターンがない場合はランダムで決定。
//1. 初手の傾向を活用
if (round === 1) { chosenHand = "パー";}
//初心者が初手で「グー」を選びやすい心理
//2. 勝者が同じ手を出しやすい心理を活用
else if (lastRoundWinner === "player") {
chosenHand = getWinningHand(playerChoice);
}
//3. 敗者が手を変える心理を利用
else if (lastRoundWinner === "cpu") {
chosenHand = getWinningHand(getMostPlayedHand());
}
//4. ランダムな選択の導入
else {
chosenHand = getCpuChoiceRandom();
}
ジャンケンに心理的な駆け引きを追加し、ランダム要素も加えて、プレイヤーに緊張感と予測不可能なゲーム体験をさせるのが狙いです。
対人と対戦できるジャンケン
ここまでで少し自信がついてきたので、次のステップとして「実践」で鍛えることに挑戦しました。
考えた結果、「オンラインでジャンケンができればいいんじゃない?」というアイデアに行きつき、2人で対戦できるミニアプリを試作することにしました。
しかし、技術的な課題が発生しました。
・WebSocketが利用できない一般的なレンタルサーバー環境
・Node.jsが必要なリアルタイム通信サーバーの構築が難しい
・ローカル環境での開発だけでは意味がない
これらを踏まえて実現可能な方法を比較し、以下の選択肢を検討しました。
考えた結果、「オンラインでジャンケンができればいいんじゃない?」というアイデアに行きつき、2人で対戦できるミニアプリを試作することにしました。
しかし、技術的な課題が発生しました。
・WebSocketが利用できない一般的なレンタルサーバー環境
・Node.jsが必要なリアルタイム通信サーバーの構築が難しい
・ローカル環境での開発だけでは意味がない
これらを踏まえて実現可能な方法を比較し、以下の選択肢を検討しました。
実現方法の比較
上記を踏まえ、以下の2つの方法で試作を進めました。
ポーリング方式
PHPを使用してJSONに出力・書き込みを行い、2人で対戦できる仕組みを実装しました。ただし、サーバー負荷やレスポンスの遅さが課題。
まずは動作テスト
サーバーとクライアント間の非同期通信を確認し、ポーリング処理や完了フラグによる動作制御を検証します。
要は、PHPからJSON形式でサーバーがレスポンスを出力し、クライアントがそれを読み取る仕組みの動作確認です。
PHPでポーリングを実行する際、クライアントが一定間隔でサーバーにリクエストを送り、サーバーがその都度状態を確認してレスポンスを返します。
「PHPポーリング動作テストのリンクはこちら」
このサーバーで利用できそうですね。動作確認OK!
要は、PHPからJSON形式でサーバーがレスポンスを出力し、クライアントがそれを読み取る仕組みの動作確認です。
PHPでポーリングを実行する際、クライアントが一定間隔でサーバーにリクエストを送り、サーバーがその都度状態を確認してレスポンスを返します。
「PHPポーリング動作テストのリンクはこちら」
このサーバーで利用できそうですね。動作確認OK!
2人で対戦するジャンケン試作1号
まずは、2人で同時にできるのかの検証テストを兼ねた試作1号です。
「PHP版2人プレイ検証テストはこちら」
このテストで、じゃんけんゲームの進行を管理するサーバー・クライアント構成です。
プレイヤー登録、手の送信、状態確認を行い、非同期通信とポーリングでリアルタイム性を実現。
エラーハンドリングやレスポンスの統一で安定性を確認します。
「PHP版2人プレイ検証テストはこちら」
このテストで、じゃんけんゲームの進行を管理するサーバー・クライアント構成です。
プレイヤー登録、手の送信、状態確認を行い、非同期通信とポーリングでリアルタイム性を実現。
エラーハンドリングやレスポンスの統一で安定性を確認します。
PHP版ポーリングのポイント
1. サーバー状態の取得 (ポーリング対応) PHP側
・サーバー側で現在のゲーム状態をクライアントに返す。
・ポーリングを可能にし、リアルタイム性を実現。
2. クライアントでのポーリング処理 JS側
・一定間隔でサーバーの状態をリクエスト。
・ポーリングを停止する条件も柔軟に設定可能。
・サーバー側で現在のゲーム状態をクライアントに返す。
・ポーリングを可能にし、リアルタイム性を実現。
2. クライアントでのポーリング処理 JS側
・一定間隔でサーバーの状態をリクエスト。
・ポーリングを停止する条件も柔軟に設定可能。
//1. サーバー状態の取得 (ポーリング対応) PHP
case "get_state": // ポーリング用アクション
sendResponse("success", "Current game state", $state);
break;
//2. クライアントでのポーリング処理 JS
function startPolling() {
if (pollingInterval) return; // 重複防止
pollingInterval = setInterval(() => {
fetchGameState();
}, 30000); // 00秒ごと
}
1.リアルタイム性: ポーリングで状態確認を実現。
2.簡潔なエラーハンドリング: 不正なリクエストを確実にキャッチ。
3.柔軟な設計: プレイヤー追加、リセット、状態確認をシンプルに実装。
2.簡潔なエラーハンドリング: 不正なリクエストを確実にキャッチ。
3.柔軟な設計: プレイヤー追加、リセット、状態確認をシンプルに実装。
2人で対戦するジャンケン試作2号
ページを開くとだれかを識別するために番号をつけ、振り分けてから
ログインする手法にしました。
↓↓↓↓↓
「PHP版2人プレイ検証テスト2号はこちら」
さらに識別番号を名前に入力に変更し、ジャンケンボタンを設置した改良版。
↓↓↓↓↓
「PHP版2人プレイ検証テスト2号改はこちら」
何度も繰り返すとレスポンスがどうも反応がわるい気がする。サーバー側に負荷が大きいかもしれない。
ログインする手法にしました。
↓↓↓↓↓
「PHP版2人プレイ検証テスト2号はこちら」
さらに識別番号を名前に入力に変更し、ジャンケンボタンを設置した改良版。
↓↓↓↓↓
「PHP版2人プレイ検証テスト2号改はこちら」
何度も繰り返すとレスポンスがどうも反応がわるい気がする。サーバー側に負荷が大きいかもしれない。
Firebaseを活用
Googleのリアルタイムデータベース「Firebase」を採用。無料枠を利用して試作を進め、動作テストにも成功しました。さらに、セキュリティ面にも配慮が必要で、Google Cloud consoleでAPIとサービスから認証情報を設定も簡易的に試してみました。
Firebaseは、Googleが提供するクラウドプラットフォームで、アプリの開発・運用を効率化します。リアルタイムデータベース、認証、ホスティング、プッシュ通知などを提供し、バックエンド開発を簡素化。Webやモバイルアプリ開発で広く利用されています。
公式サイト:https://firebase.google.com/
公式サイト:https://firebase.google.com/
FirebaseのRealtime Databaseを利用してまずは動作テストしました。成功!
レスポンスはポーリングよりも反応が良いと感じました。
レスポンスはポーリングよりも反応が良いと感じました。
Firebase版2人対戦型ジャンケン テスト2号
Firebase版2人対戦型ジャンケンの試作です。対戦ですので、1人でテストする場合は2画面でお試しください。
リンクを外しました。
現在は、テストできませんので、ご了承ください。
かわりに簡素ですが動画をUPしました。
クライアント側とFirebaseの動きが分かります。
1人でジャンケンするのは、非常につならないことがよく分かりました。
【画面構成】
・エントリー画面
・プレイ画面
【動作環境】Firebase、Webサーバ(html,CSS,JS)2人用
まとめ
今回のチャレンジは、心理戦や技術的課題に何度も挫折を繰り返し、気が付けばデバックしかしていない気がしますが、ジャンケンをテーマにしたアプリ試作を通じて、単純ながらも奥深いジャンケンの世界を体験しました。
次回は、「みんなでジャンケン」に挑戦します!複数人がリアルタイムで対戦できる仕組みや、ランキング機能の実装に取り組む予定です。
これからも「ジャンケン王」への道を進んでいきますので、ぜひお楽しみに!
最後までお読みいただき、ありがとうございました。
次回は、「みんなでジャンケン」に挑戦します!複数人がリアルタイムで対戦できる仕組みや、ランキング機能の実装に取り組む予定です。
これからも「ジャンケン王」への道を進んでいきますので、ぜひお楽しみに!
最後までお読みいただき、ありがとうございました。