Best way to represent game card class in C#

后端 未结 7 1909
难免孤独
难免孤独 2021-01-06 01:23

I use class Card which contains 2 enumerated properties (suite - hearts diamonds spades and clubs) and card value from 2 to A. And overrides ToString() method to returns som

7条回答
  •  无人及你
    2021-01-06 01:36

    There's an obvious numeric value for the pip-cards, and we can add J=11, Q=12, K=13.

    It may be more convenient to have A=14 than A=1 depending on the game being modelled (so one can more simply compute different relative values of hands).

    Enums gives no real advantage, especially since enums allow out-of-range values unless you explicitly check for them (e.g. there is nothing to stop someone assigning (CardValue)54 to the card-value enumeration value).

    ToString can be aided with an array of the values {null,"1","2","3","4","5","6","7","8","9","10","J","Q","K"}. Likewise {'♥','♦','♠','♣'} could give a nicer output.

    Parsing always trickier than outputting a string, even if you are very strict in what you accept, as you have to deal with the potential for invalid input. A simple approach would be:

    private Card(string input)
    {
      if(input == null)
        throw new ArgumentNullException();
      if(input.length < 2 || input.length > 3)
        throw new ArgumentException();
      switch(input[input.Length - 1])
      {
        case 'H': case 'h': case '♥':
          _suit = Suit.Hearts;
          break;
        case 'D': case 'd': case '♦':
          _suit = Suit.Diamonds;
          break;
        case 'S': case 's': case '♠':
          _suit = Suit.Spades;
          break;
        case 'C': case 'c': case '♣':
          _suit = Suit.Clubs;
          break;
        default:
          throw new ArgumentException();
      }
      switch(input[0])
      {
        case "J": case "j":
          _cardValue = 11;
          break;
        case "Q": case "q":
          _cardValue = 12;
          break;
        case "K": case "k":
          _cardValue = 13;
          break;
        case "A": case "a":
          _cardValue = 1;
          break;
        default:
          if(!int.TryParse(input.substring(0, input.Length - 1), out _cardValue) || _cardValue < 2 || _cardVaue > 10)
            throw new ArgumentException;
          break;
      }
    }
    public static Card Parse(string cardString)
    {
      return new Card(cardString);
    }
    

    You might want to add a static method that read a larger string, yield returning cards as it parsed, to allow for easier encoding of several cards.

提交回复
热议问题