-1

既に同じような質問がありましたら申し訳ありません。得点ハンドについていくつか質問がありますが、私はそれを必要としません。

私が取り組んでいるプロジェクトは 10 枚のカードを取り、見つかった最高の 5 枚のカードの手 (「ストレート」、「ハイ カード」、「フラッシュ」など) を報告する必要があります。幸いなことに、カードの実際のハンドが何であるかは関係ありません。名前が必要なだけです。

私はすでにすべてのカードを解析して分類し、可能なすべてのハンドのテストをレイアウトしました。今必要なのは、手を収納する便利な方法だけです。私の狂った方法は、擬似コードの用語で次のとおりです。

カードの NUMBER 値を最高から最低の順に入力できる動的リストを水平方向に作成したいと考えています。たとえば、「QJT 7 4 2 1」です。T は 10 です。値の重複は無視されます。次に、これらの値のそれぞれの下に、デッキに存在する各値のスーツのリストが必要です。たとえば、J には「D H」という値を持つサブリストがあり、私がダイヤのジャックとハートのジャックを持っていることを表します。

ほとんどのポーカー ハンドは値のみを扱うので、これがこれらのカードを処理する最もエレガントな方法であると信じています。次に、スーツを扱う 2 つのテストは、キーの下の値を参照することで簡単にテストできます

深呼吸をしてください。

したがって、Lookup のインスタンスは完璧に見えます! 私が望む正確な「複数の値への1つのキー」構造を持っています。ただし、スーツに着いたときにスーツを追加することはできません。リストは入力後に不変であるため、一度にすべて追加するか、まったく追加しない必要があります。

だから私はどちらか

  1. ルックアップを行う前に、すべてのスーツを一度に見つける必要があります
  2. 何らかの方法でルックアップ リストに値を追加するか、
  3. 他のものを使用してください。

これらのいずれかに関するアイデアはありますか?

アップデート

TL;DR SPARKNOTES バージョン: ルックアップ内のキーに値を追加するにはどうすればよいですか?

*重要な注意: * このプログラムの出力は、「フォーカード」、「ツーペア」、「ハイカード」など、可能な限り最高のハンドの名前を含む文字列である必要があります。

私は、新しいリストでルックアップ全体を再作成することを提案した解決策を 1 つ見つけました (残念ながらリンクを失い、再び見つけることはできません)。それは私だけかもしれませんが、その解決策は非常に...醜い... とにかく、私が調査またはテストした他のいくつかの解決策は次のとおりです。


方法 1

ロールスルーして、各値に関連付けられたスーツを別の配列に入力します。基本的に (今回は実際の疑似コードで >_>):

  1. ArrayLists の配列を作成します (配列 1)
  2. 「カード」の並べ替えられた文字列配列を反復処理します (配列 2)
  3. 各カードについて:
  4. 文字列インデックス [1] (スーツを表す) の char を取得し、文字列インデックス [0] から抽出されたインデックス番号で配列 1 の ArrayList に追加します。

このようにして、必要なスーツが関連付けられた値のリストを取得できます。また、スーツのリストは起動する最小サイズであるため、後で簡単に反復できます。いくつかの追加の手順を使用して、アンブレラ配列を ArrayList にして、カードの値を順番に入力することもできるので、ギャップや重複した番号はありません。これにより、必要なもののギザギザの配列が残ります。明確にするために、これは宿題ではありません。ただし、それは私のルームメイトが過去に完了したコーディングクラスのプロジェクトからのものであるため、私には制約と要件があります。私が尋ねた他の誰かは、SEがこの時期にこの種の宿題の質問に悩まされると私に言ったので、あなたの懐疑論は理解できます. 私は C# を学びたいので、これは個人的なプロジェクトです (私が今知っているのは Java だけです。

もしそれがグレードだったら、うまくいくのでそこで終わります。しかし、私は配列リストの配列リストがあまり好きではありません。なので、他に方法があれば知りたいです。


方法 2

また、必然的に発生する重複を単純に処理することも検討しました。たとえば、ストレートのテストは次のとおりです。

 for (int i = 0; i < 5; i++)
        {
            int counter = 0;
            for (int j = i; j < i + 4; j++)
            {
                int secondCard = getValue(cardsArray[j + 1]);
                int firstCard = getValue(cardsArray[j]);
                if (secondCard == firstCard)
                {
                    break;
                }
                if (secondCard == (firstCard + 1))
                {
                    counter++;
                    if (counter == 4)
                    {
                        isStraight = true;
                        return "straight";
                    }
                }
            }
        }

このコードは機能しません。完全に機能するには、どこかで微調整が必​​要ですが、修正する前に、それが価値があるかどうかを分析したいと思います。ただし、ストレートを正確にテストします。また、いくつかの注意事項: firstCard と secondCard は読みやすさとデバッグの目的であり、 isStraight は後でストレート フラッシュをテストするときに車輪を再発明しないようにするためです。

この入れ子になったループは、5 枚目のカードまですべてのカードを反復処理し (並べ替えられた 10 枚のカードのうち 5 枚未満のカードをそのまま使用することはできないため)、期待どおりに次の 5 枚のカードをチェックします。この反復中に重複したエントリに遭遇した場合、それは別のスーツの同じカードであることを意味し、単純に「ブレーク」します。この 1 つのステートメントの結果として起こるべきことは、現在のカードではなく次のカードをチェックするために、2 番目の反復を 1 ずつインクリメントしたことです。「1D 2D 3S 3H 4D 5C」のようなリストは、ストレートを見つけるときに 2 番目の 3 をスキップします。休憩にもかかわらず、私は、私がそうする権利があるかどうかにかかわらず、このソリューションの優雅さに実際には非常に満足していました.

それはすべて、文字列の単純な配列 (「カード」) を使用することの欠点にまでさかのぼります。これは、私のコードが現在調整されているものです。そして、私は問題を修正するのが嫌いで、むしろ避けたいと思っています。たぶん私は不必要にうるさいですが、途中で学んでいます.


方法 3

文字列の配列の弱点を考察した結果、魅力的に見えた辞書にたどり着きました。自分の値を順番に保持するように簡単に作成でき、キー (TryGet) に特定のスーツがあるかどうかを簡単に見つけることができます。複数の配列リストを作成し、「(私の値のインデックスを見つける); array1[index].Add(value)」のようなことを行うと、「Dictionary.Add(value, suit)」に置き換えられます。ただし、キーにスーツを追加できるのは、作成時に限られます。「2」キーを作成して「S」を追加し、次のカードが「2D」であることがわかったときに「2」キーの下に D を追加することはできませんでした。辞書はそれをサポートしていないか、複数の値をまったく追加していません。リストの辞書を作ることはできますが、それでもできません。辞書はほとんどがクエリ データ構造であるため、リストを編集しないでください。ルックアップはキーごとに複数の値をサポートしますが、最初の「Add()」の後は変更できません。ここでも、ルックアップまたは辞書全体を「再作成」してスーツを追加し、すべてを整理することができました。しかし、この 1 本のケーブルは長すぎて、産業用の有能なカッターを持っていないため、ブリッジ全体を再構築するように思えます。これは、より簡単な解決策が必要な問題です。たとえば、いくつかのカッターを取得して取得する必要があります (クラスをインポートしますか?)。しかし、この 1 本のケーブルは長すぎて、産業用の有能なカッターを持っていないため、ブリッジ全体を再構築するように思えます。これは、より簡単な解決策が必要な問題です。たとえば、いくつかのカッターを取得して取得する必要があります (クラスをインポートしますか?)。しかし、この 1 本のケーブルは長すぎて、産業用の有能なカッターを持っていないため、ブリッジ全体を再構築するように思えます。これは、より簡単な解決策が必要な問題です。たとえば、いくつかのカッターを取得して取得する必要があります (クラスをインポートしますか?)。


結論

私のニーズはハンドスコアリングシステムが提供できるものと何ら変わらないとおっしゃっているので、別の質問につながります。

ハンド スコアは特定のハンドに直接関連付けられていますか? 先に述べたように、私が望む結果は、「このプレイヤーが最高のハンドを持っている」ではなく、「あなたが作ることができる最高のハンドはフルハウスです」です。最高得点のハンドを計算し、そのスコアから「フルハウス」を推定できますか? もしそうなら、これはすべて不要なコードだと思いますが、その場合はとにかくこれを解決したいと思います。

私がこの編集を書いているとき、これは基本的に虚栄心の問題であることに気づきました。私が持っている解決策が「好き」ではありません。また、受け入れられたソリューション (テーブル ルックアップ) は使用したくありません。これは、コピーペースト プロジェクトであるコーディング プロジェクトではないためです。ご意見をいただければ幸いです。

4

2 に答える 2

1

これを可能な限り簡単な方法で行いましょう。まず、それぞれがカードの名前である 10 個の文字列の配列があるとします。「フォー・オブ・ハート」や「クイーン・オブ・スペード」のように。それは一緒に仕事をするのに本当に不便です。そのため、最初にこれらの文字列を数値に変換して、各カードを表します。これを行う非常に便利な方法は、ハートには 0 ~ 12 の数字、ダイヤモンドには 13 ~ 25 などの数字を使用することです。これで、名前を数字に変換するコード (おそらくルックアップ テーブル) ができました。

Ace of Hearts = 0
Two of Hearts = 1
Three of Hearts = 2
...
Queen of Hearts = 11
King of Hearts = 12
Ace of Diamonds = 13
...
...
Ace of Clubs = 26
...
...
Kind of Spades = 51

これで、10 枚のカードを表す数字の配列ができました。それを呼んでcardsArrayください:

int[] cardsArray = new int[10];
// here, fill the cards array from the input

スーツとバリューで並べ替えると、フラッシュを簡単に確認できます。カードは 10 枚しかないので、並べ替えにそれほど時間はかかりません。並べ替えは非常に簡単です。

int[] sortedBySuit = 
    cardsArray
    .OrderBy(x => x/13)  // sorts by suit
    .ThenByDescending(x => x % 13) // then by value, descending
    .ToArray();

次に、配列を順番に調べて、フラッシュ、ストレート フラッシュがあるかどうか、およびフラッシュのハイ カード (ある場合) を判断できます。

たとえば、フォーカードはフラッシュに勝つため、その情報を保存する必要があります。ですから、それも確認する必要があります。

次に、値で並べ替えます。

int[] sortedByValue =
    cardsArray
    .OrderByDescending(x => x % 13)
    .ToArray();

そのリストを順番に調べて、ハイカード、ペア、スリーカード、フォーカード、またはストレートを決定できます。ハンドの各タイプを見つけたら、そのハンド情報 (「キング ハイ ストレート」または「スリー テン」) をハンドの値 (ハイ カードの場合は 1、ペアの場合は 2、ストレート、フラッシュ、フルハウスなど) とともに保存します。適切な順序]) をリストに追加します。

次に、見つけたものから最高の値を持つ手を選ぶだけです。

これは間違いなく最速の方法ではありませんが、単純で、メモリをほとんど使用せず、プロトタイプとしては十分高速です。辞書や配列の配列などを使用するよりも確かに簡単です。

于 2013-09-11T23:06:58.127 に答える