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

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

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

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

Q&A

解決済

1回答

767閲覧

listの中に同じ数字があればカウントしていきたい

3o.1984

総合スコア12

Java

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

1グッド

1クリップ

投稿2019/05/21 05:52

編集2019/05/21 07:29

前提・実現したいこと

Javaを使用しています。同じ数字があればカウントしたいソースを書きたいです。

ポーカーを開発しておりランダムで配布されたカード5枚です。
ワンペア
ツーペア
スリーカード等などの判定するソースを書きたいところです。
listには残りのトランプカードが入っています。

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

エラーはありません。 ```ここに言語名を入力 Java ### 試したこと ArrayList<String>手札=new ArrayList(){ for (int i = 1; i < 10; i++) { card.add("♠" + (i + 1)); card.add("❤" + (i + 1)); card.add("????" + (i + 1)); card.add("♦" + (i + 1)); } card.add("♠" + "J"); card.add("❤" + "J"); card.add("????" + "J"); card.add("♦" + "J"); card.add("♠" + "Q"); card.add("❤" + "Q"); card.add("????" + "Q"); card.add("♦" + "Q"); card.add("❤" + "K"); card.add("????" + "K"); card.add("♦" + "K"); card.add("♠" + "K"); card.add("❤" + "A"); card.add("????" + "A"); card.add("♦" + "A"); card.add("♠" + "A"); card.add("JOKER"); for(int i = 0;i<5;i++){ 手札.add(card.get(i)) } int count = 0; for (int a = 0; a < 手札.size(); a++) { for (int b = 0; b <手札.size(); b++) { if (手札.get(b).substring(1,2).equals(手札.get(a).substring(1,2))) { count++; } } } System.out.println(count); ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。
DrqYuto👍を押しています

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

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

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

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

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

m.ts10806

2019/05/21 06:21

あと、mainメソッドとかはいいのでせめてコピペで動作するコードでご提示ください。 下記とか何のために入れられたものかわかりません。 >❤5,♠2,♦8,♦5,????9
jimbe

2019/05/21 06:38

この場合 count は幾つになってほしいのでしょうか. また, 現状は幾つになっているのでしょうか.
3o.1984

2019/05/21 07:00

最初countは0です。 countはカードの枚数の「2」になってほしいです。
m.ts10806

2019/05/21 07:02

質問は編集できますので適宜ご対応いただければと
jimbe

2019/05/21 07:19

編集ありがとうございます. 出来れば mts10806さんの言われていますように, コードのほうを動作するものにして頂けたらと思います. count ですが, ポーカーということで ワンペア→2, スリーカード→3, フォーカード→4 でしょうか. ではツーペア, フルハウスはどうしましょう.
3o.1984

2019/05/21 07:30

ツーペアとフルハウスはまだやり方が思いつかないので進まない状態です
ngsvx

2019/05/21 12:43

もしかしたら、他の方の意図を邪魔してしまうかもしれませんが、、、 現実でのカードを数える時に、このコードのような数え方はしないのではないですか? それぞれの数字が何枚あるかを集計すれば、役の判定に使えると思いますが。
guest

回答1

0

ベストアンサー

コード(あるいは設計)の問題点として3つほど指摘します。

問題1: カードのランク(数字)は1文字ではないです

1, 2, A, Kなどは1文字ですけど、10は2文字になりますよね?またJOKERはどう考えますか?質問者さんはそのことを失念あるいは棚上げしておられるようです。

対処:10の考慮については問題2の対処の方で書きます。ちなみにポーカーならJOKERは不要では?ローカルルール(?)ではワイルドカードとしての役割があるポーカーですが使わないルールの方が普通のようですし、なによりプログラムが難しくなります。

問題2: 見た目が1文字の文字列の長さが1とは限らない(Javaでは)

Javaにおいて見た目が1文字のStringの長さは多くの場合1ですが、文字によっては2となることがあります。これはJavaのchar型が65,536種類の情報しか保持できないのに対し、UNICODEで定義されている全ての文字が1,114,112種類(本当はもっと少ない)あるためです。日本語においては半角英数記号文字(いわゆるASCII文字)やほとんどの漢字・全角記号が1つのcharで表現できる範囲に収まっているのですが、特殊な漢字や記号(絵文字など)は1つのcharでは表現できず2つのcharの並び(サロゲートペアといいます)で表現されます。ご質問のコードに限ると????が長さ2の文字列として扱われています。

String#substringなどの多くのメソッドではUNICODE文字の単位ではなくJavaのcharの単位で文字の位置や長さを扱います。このため
s.substring(1, 2)
と書いてもそれは単純に「2文字目の一つの文字」を表すことにはなりません。

対処:今のままのデータ構造を変えずに先頭の文字(スート)がchar 1つの文字なのか2つの文字なのかを判定し、それによりsubstring(1)substring(2)のどちらとするか切り分けることもできます。java.lang.Stringのメソッドの一覧を詳しく調べれば方法が見つかります。しかしその方法はお勧めできません。文字コードの扱いはややこしく特に初心者の方を混乱させるものだと思うからです。もっと分かり易い設計に作り直すことをお勧めします。設計方法はピンキリですが多分最も分かり易いものの一つは「スートとランクの間に区切り文字を挿入しておくこと」と思います。"♠10"ではなく"♠ 10"などとするのです。

こうしておくと"♠ 10".split(" ")[1] => "10"のように簡単にランクが取り出せます。1文字のランク1でも2文字のランク10でも同一のコードで取り出せるので簡単です。

(多分自分ならこういうふうにはしません。単なる文字列でカードを表現するのではなくCardクラスを定義し、スートやランクを別々に扱えるようにし、そのほかスートやランクの強さなどカードが備えるべき機能を定義すると思います。クラス設計の議論は長くなるので割愛します。)

問題3: 比較すべき組み合わせの問題

手札5枚の中の「同じランク」のカードの枚数がいくつか数えようとされているわけですが、フルハウスのケースを除外したとしてももう少しきちんと考える必要があります。例えばご質問のコードで♦A, ♠A, ♦2, ♦3, ♦4のケースは2となるのが期待でしょうが実際には7になってしまいますよ?forループのa, bがどのように変化し、いつカウントが上がるかを紙に表でも書いて整理すると見えてくると思います。

a = 0, b = 0:
=> カウントアップされる。同じカードを見ているわけなのでランクが一致するのは当然

a = 0, b = 1:
a = 1, b = 0:
=> 二重にカウントアップされる。

対処:色々ありますがそれを書くためには「Java言語とは直接関係ない一般的なアルゴリズムを考える力」「Java言語でそのアルゴリズムを適用するのに必要なクラスやクラスのメソッドの使い方の知識」の2種類のスキルが必要になります。比較的分かり易いものを挙げてみますと・・・

案1: HashMapを用い5枚の手札を一重ループで調べ、ランクをキーに、枚数を値にしてHashMapへ登録していく。
♦A, ♠A, ♦2, ♦3, ♦4を一枚ずつ登録するとHashMapの中は

キー値(枚数を表す)
A2
21
31
41

となります。ここから全てのキーについて値を取り出し、1以外のものを記録していくとフルハウスのケースにも対処できます。詳細は割愛。

案2: 手札をランクに従いソートし、連続したカードを見ながらランクが一致している個数を数える
ソートは1行で書けますが、意味を把握するのが多分難しいと思います。ソートの説明は割愛します。

java

1import java.util.Comparator; 2... 3 4手札.sort(Comparator.comparing(a -> a.split(" ")[1]));

ソートした結果に対して先頭から順にランクを調べ、同じランクが続いている限りカウントアップ、直前と違っていたらカウンターをリセット・・・という感じですが言うは易しで、具体的なコードに表現するのは少し難しいかも知れません。挑戦してみてください。


本回答ではいくつかの方針案のみ述べています。ポーカーの役の判定は一見簡単に思えるかも知れませんが、コードに書いてみるとわかるように様々な「アルゴリズムやJavaのクラスの知識」が必要となる結構難しいものだと思います。多分質問者さんにとって挑戦的な問題ではないでしょうか?一挙にゴールを目指すのではなく小さな機能・処理の断片を一つ一つ攻略していくよう心がけるとよいと思います。

投稿2019/05/22 00:09

KSwordOfHaste

総合スコア18392

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問