3

ユーザーがボタンを押してカードを配ると、そのカードの値がテキスト ボックスに追加される、ブラックジャックのゲームである C# でカード ゲームを作成しています。テキスト ボックスの値が 21 を超えると、ユーザーは負けたことになります。

カードの扱いに問題があります。ランダムに生成し、5 が生成されたとします。ダイヤモンドの 5 を表示し、ダイヤモンドの 5 の値をスコア テキスト ボックスに追加し、画像ボックス (5 の 5) を表示します。ダイヤモンド トランプ)。ただし、5 が生成されると、そのカードを再度生成できないという問題が発生します。発生する必要があるロジックがダウンしています。初心者なので、実際のコード自体についてはわかりません。

これまでのところ、リストとブール値の配列の2つの異なる方法を試しましたが、まだ苦労しています。コードに関して誰かが正しい方向に私を向けることができます.

List<int> Diamonds = new List<int>();
        Random random = new Random();
        genRandom = random.Next(0, 5);


        while (Diamonds.Contains(genRandom))
        {
            genRandom = random.Next(0, 5);
            break;
        } 


        while (!Diamonds.Contains(genRandom))

        if (genRandom == 0)
        {
            Diamonds.add(0);
            score = score += 2;
            scoreTextBox.Text = score.ToString();
            diamonds2.Show();

        }

よろしくお願いします。悪い文法については申し訳ありません!

4

6 に答える 6

4

あなたが今抱えている問題は、カードプールがないことです。ドローできるカードのリストが必要です。カードが選択されると、使用可能な選択肢から削除され、再度ドローすることはできません。

List<Card> deck = new List<Card>();

deck.Add(new Card(1, CardType.Diamonds));
deck.Add(new Card(2, CardType.Diamonds));

...

Card nextCard = deck[Random.Next(0, deck.Count - 1)];
deck.Remove(nextCard);

どこ:

struct Card
{
    public int number;
    public CardType type;

    public Card(int number, CardType type)
    {
        this.number = number;
        this.type = type;
    }
}

enum CardType
{
    Diamonds,
    Spades,
    Hearts,
    Clubs
}

これは、各カードが一意のコンテナーとして明確に定義されている、非常に単純化されたオブジェクト指向のアプローチです。これは最適な方法ではないかもしれませんが、おそらくはるかに理解しやすいでしょう。

于 2013-04-16T10:09:09.300 に答える
4

考えられるすべてのカードを保持するコレクションを作成し、コレクションからそれらをランダムに引き出すという逆のアプローチをとります。

Deckカード デッキを表す というクラスがあるとします。Cardクラスでそれを埋めます。カードを引き始めたら、コレクションからランダムに数字を選び、そのカードを から取り除きDeckます。次に同じ乱数が引かれたとき、使用済みのカードを取り除くため、デッキから別のカードが引かれます。

デッキのサイズの範囲内で乱数を生成することを忘れないでください。これは、ドローごとに減少します。

于 2013-04-16T10:06:55.617 に答える
1

それを行うには多くの方法があります。私が最もよく使用するのは次のとおりです。

List<int> available = new List<int>(5000);
for(int i=1; i<=5; i++)
available.Add(i);

上記のコードは、すべての乱数を生成します。

現在、次のように選択できます。

List<int> result = new List<int>(5000);
while(available.Count > 0)
{
 int index = random.Next(availableCount);
 result.Add(available[index]);
 available.RemoveAt(index);
}
return result;

取得後に削除するため、繰り返されることはありません。

于 2013-04-16T10:08:59.500 に答える
1

次のようなことができます。

List<int> Diamonds = new List<int>();
for(int i = 1; i <= 10; i++) //10 is just an example..dk how many cards :P
{
    Diamonds.Add(i);
}

Random random = new Random();
int index = random.Next(0, Diamonds.Count - 1);
int nr = Diamonds[index];
Diamonds.Remove(index);
于 2013-04-16T10:09:42.793 に答える
0

これを概念的に行う最も簡単な方法は、カードのデッキを表す配列を用意し、そこからカードを配ることです。

これにはスタックを使用するのが理想的ですが、残念ながらスタックをシャッフルすることはできません。

したがって、最善の策は を使用することですList<Card>。'Card' はカードを表すクラスです。Cardクラスには 2 つのプロパティがあります。aとSuite、1 (エース) から 13 までのランク (11 はジャック、12 はクイーン、13 はキング) です。

デッキに 52 枚の可能なカードすべてを配置し、フィッシャー イェーツ シャッフルList<Card>の実装を使用してシャッフルすることができます。

完全なサンプルは次のとおりです。

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var deck = new List<Card>();

            for (int rank = 1; rank <= 13; ++rank)
                foreach (Suite suite in Enum.GetValues(typeof(Suite)))
                    deck.Add(new Card {Rank = rank, Suite = suite});

            var shuffler = new Shuffler();

            shuffler.Shuffle(deck);

            // Deal the top 10 cards.

            for (int i = 0; i < 10; ++i)
                Console.WriteLine(deck[i]);
        }
    }

    public enum Suite
    {
        Clubs,
        Diamonds,
        Hearts,
        Spades
    }

    public sealed class Card
    {
        public Suite Suite;
        public int Rank;

        public override string ToString()
        {
            string rank;

            switch (Rank)
            {
                case 1:  rank = "Ace";   break;
                case 11: rank = "Jack";  break;
                case 12: rank = "Queen"; break;
                case 13: rank = "King";  break;
                default: rank = Rank.ToString(); break;
            }

            return string.Format("{0} of {1}", rank, Suite);
        }
    }

    public sealed class Shuffler
    {
        public Shuffler()
        {
            _rng = new Random();
        }

        public void Shuffle<T>(IList<T> array)
        {
            for (int n = array.Count; n > 1; )
            {
                int k = _rng.Next(n);
                --n;
                T temp = array[n];
                array[n] = array[k];
                array[k] = temp;
            }
        }

        private readonly Random _rng;
    }
}

もちろん、実際のコードはランクとスイートを検証する必要があります。また、シャッフルとディールをカプセル化した Deck クラスを作成したほうがよいでしょう (ディールList<Card>時に最後からカードを削除できます)。

于 2013-04-16T10:27:45.317 に答える