質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

GsACADEMY

セカイを変えるエンジニア【GEEK】を養成する 授業料後払いのエンジニア養成学校です。 ①一流企業によるメンター指導 基本習得後は2ヶ月間メンターの個別指導でサービス完成を目指します。 ②480万円までの起業支援出資 起業志望者をサムライインキュベートが支援(審査あり)します。 ③初心者歓迎・授業料後払い 丸暗記ではなく、創りながら。初心者のための授業料後払い制度です。

Q&A

解決済

4回答

4093閲覧

JavaScript ランダムではない"じゃんけん"について

M_Kasahara

総合スコア13

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

GsACADEMY

セカイを変えるエンジニア【GEEK】を養成する 授業料後払いのエンジニア養成学校です。 ①一流企業によるメンター指導 基本習得後は2ヶ月間メンターの個別指導でサービス完成を目指します。 ②480万円までの起業支援出資 起業志望者をサムライインキュベートが支援(審査あり)します。 ③初心者歓迎・授業料後払い 丸暗記ではなく、創りながら。初心者のための授業料後払い制度です。

0グッド

2クリップ

投稿2015/05/06 15:49

編集2015/05/06 15:51

プログラミング入門で JavaScriptのじゃんけんゲームをつくっております。

これまでコンピュータの出す手は、ランダム関数を利用してきました。

これをコンピュータが過去の戦績を参照して、出す手を考える、とすることは可能でしょうか。

たとえば、
・全3回対戦
・1,2回戦はランダムで
・3回戦は、過去2回で人間が出さなかった手に勝てる手を出す
(過去に出さなかったので3回戦で出す可能性が高い..はず)

などです。

JavaScriptに、
sessionStorageやlocalStorageという機能があり
データをローカル環境に保存することまでは調べました。

この機能を使って、上記のような戦績分析型(?)は作れるものでしょうか。

機能の理解で初歩的なところから間違っておりましたらすみません。

よろしくお願い申し上げます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

こんにちは。

ご質問の中の

・3回戦は、過去2回で人間が出さなかった手に勝てる手を出す

の実装とは、ちょっと違うことをレスします。

コンピュータの勝率をアップさせることを、このプログラムの
性能向上と考えると、人がじゃんけんをするときに、どういう
クセがあるか?というデータを「戦績分析」するロジックに
いろいろ組み込んでいくことになると思いますが、
こんなまとめサイトがありました。

じゃんけんで勝つ確率を飛躍的にあげるコツ

上記から行けるサイトのひとつ

ジャンケンで勝つ確率を上げる簡単な方法

には、以下のような調査結果が書かれています。

2009年6月20日の日本経済新聞土曜版「日経プラスワン」に、
桜美林大学
の芳沢光雄教授による「ジャンケンに関する研究結果」が掲載されました。
芳沢教授が学生725人を集めて、のべ11567回ジャンケンさせたところ、
人間の手の出し方はグー、キョキ、パーそれぞれ1/3とはならなかったそうです。
当時の記事には、以下のように書かれています。

最も多いのはグーで4054枚(35.0%)、次はパーで3849回(33.3%)、
最も少ないのはチョキで、3664回(31.7%)と、かなりのバラツキが出た。
統計的にはグーが出やすく、チョキが出にくい。だから、パーを出せば
勝ちやすいというわけだ。


上記のようなデータもふまえつつ、とはいえ、実際に手を出してやる
じゃんけんと、WEBの画面で選ぶのとはまた違うので、たくさんの対戦
のデータを蓄積して、どういうパターンで出せば人間に勝てるのかの
戦略を、(流行り言葉でいってみれば)機械学習的に向上させていく
ようなロジックを考えるのも面白そうですね。

以上、ちょっとした思いつきでした。

投稿2015/05/06 18:34

編集2015/05/07 07:40
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

M_Kasahara

2015/05/08 11:54

ひきつづきありがとうございます。 リンク先のサイトをさっそく拝見しました。 これは面白いですね。 実際に手をだしてやるじゃんけんで、 所作の多いチョキが少なくなるのは なんとなく実感できます。 おなじように WEBの画面で左右に3つボタンが並んでいたら 無意識に一番左のボタンを多くクリックしてしまいそうです。 ひじを開かず右手のマウスを動かす距離が短くてすむからです。 「機械学習」とか「人工知能」という言葉には 字面からひとを惹きつける力があります。 わたしも昨年から今年にかけて 本を読んだり、NHKスペシャルを見たりして、かなり素直に影響を受けています。 今回、じゃんけんのプログラムをつくろうとしたとき 最初に考えたのが「コンピュータが過去の戦績を分析して手をだす」 だったのはその影響かもしれません。 考えたロジックを 実際にカタチにできる力を早く身につけたいです。 ありがとうございました
guest

0

ベストアンサー

動作するものを作成してみました。
グー、チョキ、パーを0,1,2で、_historyに格納しています。
次の勝負では一番少ない手に勝つ手をコンピュータが選びます。comChoice()の箇所です。
動作確認する際は、UTF-8で保存してお試しください。

グーチョキパーの履歴を残したのは、3回連続の場合にどうするとか、一定のパターンにマッチしたらどうするとか、そういった戦術を後から組み込むことも考慮してみました。

lang

1<!doctype html> 2<html lang="ja"> 3<head> 4<meta charset="utf-8"> 5<title>じゃんけん</title> 6<script> 7(function(w,d){ 8 var _history = []; 9 var _scoreCom = 0; 10 var _scoreMan = 0; 11 var _scoreDraw = 0; 12 var _guCyoPar = ['グー','チョキ','パー']; 13 var _judge = ['引き分け','勝ち','負け']; 14 15 w.addEventListener('load',function(){init();},false); 16 function init() { 17 for (var i = 0; i < 3; i++) { 18 (function(i){ 19 d.getElementById('hand' + i).addEventListener('click',function(){pon(i);},false); 20 })(i); 21 } 22 } 23 function comChoice() { 24 if (_history.length < 2) { 25 return Math.floor(Math.random() * 3); 26 } 27 var manHistory = countHistory(); 28 var few = (manHistory[0] < manHistory[1]) ? 0 : 1; 29 few = (Math.min(manHistory[0],manHistory[1]) < manHistory[2]) ? few : 2; 30 var com = (few == 0) ? 2 : few - 1; 31 return com; 32 } 33 function countHistory() { 34 var manHistory = []; 35 manHistory[0] = 0; 36 manHistory[1] = 0; 37 manHistory[2] = 0; 38 for (var i = 0; i < _history.length; i++) { 39 manHistory[_history[i]]++; 40 } 41 return manHistory; 42 } 43 function pon(man) { 44 var com = comChoice(); 45 _history.push(man); 46 var manHistory = countHistory(); 47 var result = []; 48 result.push('コンピュータ:' + _guCyoPar[com]); 49 result.push('自分の手:' + _guCyoPar[man]); 50 result.push('勝敗:' + _judge[judge(com,man)]); 51 result.push('コンピュータの勝ち数:' + _scoreCom); 52 result.push('自分の勝ち数:' + _scoreMan); 53 result.push('引き分け数:' + _scoreDraw); 54 result.push('自分のグーの数:' + manHistory[0]); 55 result.push('自分のチョキの数:' + manHistory[1]); 56 result.push('自分のパーの数:' + manHistory[2]); 57 output(result); 58 } 59 function output(result) { 60 d.getElementById('output').innerHTML = ''; 61 for (var i = 0; i < result.length; i++) { 62 var div = d.createElement('div'); 63 div.innerHTML = result[i]; 64 d.getElementById('output').appendChild(div); 65 } 66 } 67 function judge(com,man) { 68 if (com == man) { 69 _scoreDraw++; 70 return 0; 71 } 72 if (com == 0 && man == 2 || com == 1 && man == 0 || com == 2 && man == 1) { 73 _scoreMan++; 74 return 1; 75 } else { 76 _scoreCom++; 77 return 2; 78 } 79 } 80})(window,document); 81</script> 82</head> 83<body> 84<h1>じゃんけん</h1> 85<button type="button" id="hand0">グー</button> 86<button type="button" id="hand1">チョキ</button> 87<button type="button" id="hand2">パー</button> 88<div id="output"></div> 89</body> 90</html>

投稿2015/05/06 18:01

編集2015/05/06 18:19
rik

総合スコア1151

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

M_Kasahara

2015/05/08 11:14

ありがとうございました。 自分でもうまく動かすことができました。 昨日、今日とリファレンス本を片手に 読み解いていました。 正直申しあげて、 まだ理解しきれていないところもありますが、 引き続き取り組んでいきます。 いずれはグーチョキパーの履歴を使って、 さらに新しい戦術パターンを組み込めるところまで できるようなりたいです。 漠然とこんなことが出来たら良いなと思って投げかけたところ わずか数時間で、実際にカタチにできる方がいるのに驚きました。 プログラミングの威力をあらためて実感しています。 夜分にも関わらず こんなに長いコードを書いて下さり 本当にありがとうございました。
guest

0

作れるか作れないかで言えば、作れるでしょう。

・3回戦は、過去2回で人間が出さなかった手に勝てる手を出す

これを素直にコード化すればよいだけです。

例えば、ユーザーの出した手が一度目はグー、二度目がパーだとして

lang

1var selected = []; 2selected.push("グー"); 3selected.push("パー");

などと書けます。

3回目のコンピュータの手は

lang

1// それぞれの出した回数を求める 2var gu_count = selected.filter(function(e){ return e === "グー" }).length; 3var ck_count = selected.filter(function(e){ return e === "チョキ" }).length; 4var pa_count = selected.filter(function(e){ return e === "パー" }).length; 5 6// 選ばれた回数が一番少ないものを求める 7// name に手を、count に選ばれた回数を持ったオブジェクトの配列を作る 8var min = [ 9 { name: "グー", count: gu_count }, 10 { name: "チョキ", count: ck_count }, 11 { name: "パー", count: pa_count } 12] 13// count の少ない順にソート 14.sort(function(a, b){ 15 return a.count - b.count; 16})[0]; // 0番目、つまり一番少なかった手のオブジェクトを選択する 17 18// 一番少なかったもの(min.name) が 19// 「グー」なら「パー」 20// 「チョキ」なら「グー」 21// 「パー」なら「チョキ」 22// を選択する 23var computersNext; 24switch (min.name) { 25 case "グー": 26 computersNext = "パー"; break; 27 case "チョキ": 28 computersNext = "グー"; break; 29 case "パー": 30 computersNext = "チョキ"; break; 31}

こんな感じですか。上記はあくまで例なので、方法なら他にもいくらでもあるはずです。
たぶん私なら「グーを0」「チョキを1」「パーを2」のように数値化して計算すると思います。

投稿2015/05/06 17:08

htsign

総合スコア870

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

M_Kasahara

2015/05/08 10:59

丁寧にコードを教えてくださり ありがとうございます。 '//'で各コードの意味するところを 書いていただいたのがとても助かりました。 昨日、今日とリファレンス本を片手に 一行づつ読み解いていきました。 手と回数を持ったオブジェクトの配列を作り count の少ない順にソートし 一番少なかった手のオブジェクトを選択する というのは全く思いつきませんでした。 まだ教えていただいたコードを読み解くので精一杯ですが とても勉強になりました。 心より御礼申し上げます。
guest

0

じゃんけんの手を出すパターンは、個人によって違うでしょう。
また、あまり単純な思考だとすぐにはめられかねません。
こういった時に有効なのは、どのように考えるか自体を、過去のデータからコンピュータに学習させる方法です。
パーセプトロンやニューラルネットワークと呼ばれ、対戦相手に応じて学習する能力も授けることができます。

投稿2015/05/07 14:04

jser

総合スコア100

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問