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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

4回答

4802閲覧

ジャンケン:相手の手のパターンを判別する方法

JankenMan

総合スコア13

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

3クリップ

投稿2017/06/01 05:24

編集2017/06/01 06:58

###前提・実現したいこと
JAVAでジャンケンのプログラムを作っています。
相手は様々なパターンで手を繰り出してきます。
こちらが入力してジャンケンをするプログラムではなく、こちらも自動で手を返すプログラムを組んで戦わせる形です。

その際、グーで勝つと3ポイント、チョキは4ポイント、パーは5ポイント入ります。
一万回繰り返し、最後にポイントの高かったほうが勝ち。

出来ないのは、こちらの出した手に勝てる手を次のターンに出す(例えばこちらがグーのとき、相手は次のジャンケンのときにパーを出す)相手(A)等の判別方法です。
こちらは一つのプログラムの中で、先述したAのような相手、こちらの出した手と全く同じものを次のターンに出す相手B、完全ランダムに手を出す相手Cとジャンケンをしなくてはいけません。

戦う相手はランダムなため、しっかりと判別できないと負けてしまう事も考えられます。
どうすればA,B,Cの相手を判別できるでしょうか?

###発生している問題・エラーメッセージ

エラーメッセージ

###該当のソースコード

改変不可能 import java.util.*; class J1Practice { static int Win1 = 0, Win2 = 0; static int Score1 = 0, Score2 = 0; static final int GUU = 1; static final int TYOKI = 2; static final int PAA = 3; public static void main(String args[]){ int k, p1, p2, tmp; // プレイヤー1のオブジェクトを生成 J1Fighter f1 = new Parrot(); // プレイヤー2のオブジェクトを生成 J1Fighter f2 = new Smart(); p1 = p2 = tmp = 0; // 1万回じゃんけんを実行 for (k = 0; k < 10000; k++ ) { p1 = f1.Janken(k, p2); // プレイヤー1の手 p2 = f2.Janken(k, tmp); // プレイヤー2の手 tmp = p1; if ((p1 < GUU) || (p1 > PAA)) { // プレイヤー1の反則負け Score2 = 99999; } if ((p2 < GUU) || (p2 > PAA)) { // プレイヤー2の反則負け Score1 = 99999; } if ((Score1 == 99999) || (Score2 == 99999)) break; // じゃんけんの判定 if (p1 == GUU) { if (p2 == TYOKI) { ++Win1; Score1 += 3; } else if (p2 == PAA) { ++Win2; Score2 += 5; } } else if (p1 == TYOKI) { if (p2 == PAA) { ++Win1; Score1 += 4; } else if (p2 == GUU) { ++Win2; Score2 += 3; } } else if (p1 == PAA) { if (p2 == GUU) { ++Win1; Score1 += 5; } else if (p2 == TYOKI) { ++Win2; Score2 += 4; } } } if (Score1 > Score2) System.out.println(f1.getName() + "の勝ちです"); else if (Score1 < Score2) System.out.println(f2.getName() + "の勝ちです"); else System.out.println("引き分けです"); System.out.println(" " + f1.getName() + " vs " + f2.getName()); System.out.println("Score [ " + Score1 + " : " + Score2 + " ]"); System.out.println("W i n [ " + Win1 + " : " + Win2 + " ]" ); } } こちらが改変できるプログラム class Player1 extends J1Fighter { int op[] = new int[10000]; int g,c,p; int i,r; Player1() { setName("Player1"); g = c = p = 0; for(i=0; i<10000; i++)op[i]=0; } int Janken(int no, int last) { } } こちらは改変できませんが一応 class J1Fighter { static final int GUU = 1; static final int TYOKI = 2; static final int PAA = 3; private String name = null; private String pict = null; int Janken(int no, int last) { return(0); // 反則負け } void setName(String n) { name = n; } String getName() { return name; } void setPict(String f) { pict = f; } String getPict() { return pict; } }

###試したこと
課題に対してアプローチしたことを記載してください

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

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

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

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

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

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

guest

回答4

0

ベストアンサー

基本はずっとパーで勝ち続けられれば高い点数になります。
最も高い点数が出せるのは相手がCのランダムで全てグーを出し、こちらがずっとパーを出した場合になります。
しかしながらそれは現実的ではありませんので、できるだけ早く相手を確定し勝ち続けられれば最も良いことになります。
つまりできるだけ高い点数を出そうと思うと、相手がAかBだとできるだけ早く確定させ、相手の手に対応した手を出し続ける。もし相手がCだと確定したら、そのタイミングでパーを出し続ける。という戦略が最も良いことになります。

それを前提に考えてみますが、ちなみにA,Bは初手に何を出すのでしょうか?

■1戦目
1-1.最初にパーを出す

■2戦目
2-1.次もパーを出す。相手は1戦目の自分の手によって手を決めてくる。
※1戦目の相手の手は、Cはランダムだとしても、A,Bが何を出すかが分からないので情報不足。ここでは、A,Bも1戦目はランダムで手を出してくるものとし、相手が自分の手によって出す手を決定するのは2戦目終了以降である3戦目以降に判別できるとしています。1戦目に相手が出す手にルールがあるのであればそれにしたがって2戦目の処理は変化します。

■3戦目
3-1.手を出す前に相手の手が分かる。受け取った相手の手で相手を判定する。
3-2.相手がグーを出した場合 :C確定。Cが確定したので以後ずっとパーを出し続ける。
3-3.相手がパーを出した場合 :BかC。Bだと仮定し次はチョキを出す。
3-4.相手がチョキを出した場合:AかC。Aだと仮定し次はグーを出す。

■4戦目以降
3戦目同様のロジックを用いて、前に自分と相手が出した手を判定しながら相手を確定させ、次の手を決定する。

という流れになると思います。
自分が3戦目に勝てたらC確定、そのあたりの判定条件を掴めるかがポイントかと思います。

Player17のJankenメソッドは第2引数に相手の1つ前の手を受け取ります。
そこで上記の判定を入れて自分の手を決めていくことになりますね。

投稿2017/06/01 06:41

編集2017/06/01 07:14
akabee

総合スコア1947

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

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

0

10秒ほど考えました。
質問内のコードは読んでいません。

1.1回目に適当な手を出し判別。
2.ABに該当した場合は、2回目以降はそれぞれに勝てる手を出す。
3.ABに該当しなかった場合(C確定)は、2回目以降はずっとパーを出す。

【追記】
4.2の途中でC確定した場合は3に切り替える。

投稿2017/06/01 06:09

編集2017/06/01 06:15
fuzzball

総合スコア16731

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

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

0

適当な手を出して

  • AかC
  • BかC
  • C

のどれに該当するか判定

XかCパターンの場合はXに勝てる手を出す。
途中でCに該当した場合パーに切り替え

投稿2017/06/01 06:17

編集2017/06/01 06:19
ozwk

総合スコア13512

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

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

0

相手のアルゴリズムの判定方法自体は、自分自身の次の手をAのアルゴリズムでやることで
勝ちがつづけば相手はBと判定
アイコがつづけば相手はAと判定
上記以外だったらC判定です。

A、Bなら勝ち確定です。

で、相手がCだったらパーを出し続けるのがセオリーですが、
確立に偏りがない前提なので、あまりに負けがつづくようなら、
こちらもグーを出すように別のアルゴリズムにしないとですね。

投稿2017/06/01 09:20

momon-ga

総合スコア4820

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問