c # Struct Array установлен в конструкторе - PullRequest
0 голосов
/ 22 октября 2018

У меня есть небольшая структура -

struct Card {
        public string suit;
        public string value;
}

, которую я затем использую для инициализации массива карт

Card[] deck = new Card[52];

В моем Main () я вызываю

Deck myDeck = new Deck();

Что соответствует конструктору

public Deck() {         
            int cardNum = 0;
            for (int i = 0; i < numSuits; i++) {
                for (int a = 0; a < numValues; a++) {
                    deck[cardNum].suit = suits[i];
                    deck[cardNum].value = values[a];
                    Console.WriteLine("The card at position " + (cardNum + 1) + " is the " + deck[cardNum].value + " of " + deck[cardNum].suit);
                    cardNum++;

                }
            }

        }

..., создавая таким образом колоду из 52 карт, что, как подтверждает мой Console.WriteLine (), правильно заполняет колоду.

Моя проблема в том, что у меня есть 2 других метода, public void Shuffle () и public string Deal (), которые, как показывают их названия, перетасовывают колоду и раздают верхнюю карту соответственно, однако я не знаю, какпередать значения deck.suit и deck.value в указанные методы.

Я попытался инициализировать массив Card [] внутри конструктора.Все эти функции находятся в одном и том же пространстве имен и классе.

Я также хотел бы сохранить конструктор и два метода в коде и больше ничего не использовать, хотя я уверен, что есть много других, потенциальноболее простые способы сделать это.

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 22 октября 2018

Карты немного более универсальны.Они не используются только в колодах.Они также используются в руках.А с некоторыми играми, в которых открытые карты есть даже в других структурах, чье имя я не знаю (извините, я знаю только покер из Star Trek TNG).

Из личного опыта я знаю, что довольно сложно сделатьправильный класс для "Hand" или "Deck".В конце концов, оба, похоже, оказываются чуть больше, чем контейнеры для карты [].Так что может быть лучше / проще использовать карту [].И просто имейте набор статических функций, которые инициализируют полную колоду карт, перетасовывают колоду, вытягивают из колоды и берут карту [] в качестве одного из аргументов или возвращают экземпляры карты.Имейте в виду, что массивы по своей сути разбиты по ссылкам, что действительно помогает здесь.

Что касается процесса рисования случайных карт без повторения, я лично называю это «проблемой лотереи».И я сделал этот пример кода, чтобы справиться с ним:

//Create an array. Fill it with Sequential Numbers.
int[] input = new int[20];

for(int i = 0; i < numbers.lenght; i++)
  input[i] = i;

/*Initialise the instances you will need*/
//Use the array to create a list
List<int> DrawableNumbers = new List<int>(input);
List<int> DrawnNumbers = new List<int>();

//Generate a Random Number Generator
Random rng = new Random();

/*Draw 6 from the group*/
while(DrawnNumbers.Count < 6){
  //Get a random Index to move from DrawableNumbers to DrawnNumbers
  int temp = Random.NextInt(DrawableNumbers.Count);
  DrawnNumbers.Add(DrawableNumbers[i]);
  DrawableNumbers.Remove(temp);
}

Единственная разница с перетасовкой колоды заключается в том, что вы не останавливаетесь, пока у вас не кончатся карты.

0 голосов
/ 22 октября 2018

К сожалению, я пока не могу комментировать:

Random rnd=new Random();
Card[] randomOrder = deck.OrderBy(x => rnd.Next()).ToArray();    
//TODO: you could iterate over the random order and fill your Stack 

, который должен перемешивать ваш массив случайным образом.Сделка должна быть простой, вы можете выбрать случайный индекс вашего массива и вернуть карту.Если эту карту нужно удалить после того, как она была сдана, используйте список или лучше, когда вы тасуете, вы можете заполнить, создать StackT> и заполнить ее, тогда вы можете Pop следующую карту каждый раз, когда вы звоните своему Dealфункция.

@ загадочность превзошла меня, и его решение позволяет брать сразу несколько карт.Вопрос в том, что лучше практиковать, используя стек и медленно его очищая или используя .Take и новые массивы? -

0 голосов
/ 22 октября 2018

Поиграйте с этим:

void Main()
{
    var deck = new Deck();
    deck.Shuffle();
    var cards = deck.Deal(1);
    foreach (var card in cards)
    {
        Console.WriteLine($"{card.Value} of {card.Suit}");
    }
}

public struct Card
{
    public Card(string suit, string value)
    {
        this.Suit = suit;
        this.Value = value;
    }
    public readonly string Suit;
    public readonly string Value;
}

public class Deck
{
    private const int _numSuits = 4;
    private const int _numValues = 13;

    private string[] _suits = new [] { "Clubs", "Diamonds", "Hearts", "Spades", };
    private string[] _values = new []
    {
        "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King",
    };

    private Card[] _deck = new Card[52];

    public Deck()
    {
        _deck =
            _suits
                .SelectMany(s => _values, (s, v) => new Card(s, v))
                .ToArray();
    }

    private Random _random = new Random();
    public void Shuffle()
    {
        _deck = _deck.OrderBy(_ => _random.Next()).ToArray();
    }

    public Card[] Deal(int take)
    {
        var cards = _deck.Take(take).ToArray();
        _deck = _deck.Skip(take).ToArray();
        return cards;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...