Cards/CardExtensions.cs

Extension methods for CardObject that provide convenience accessors for a card's resolved face using an explicit DeckDefinition. It exposes RankValue, SuitChar, IsRed and ShortLabel to avoid repeating resolve calls.

namespace CardGames;

/// <summary>
/// Convenience accessors for a card's resolved face, so games stop repeating
/// <c>card.Value.Resolve( deck ).Value</c>. The deck is passed in explicitly - no hidden global.
/// </summary>
public static class CardExtensions
{
	/// <summary>Rank ordinal, 1 (Ace) .. 13 (King).</summary>
	public static int RankValue( this CardObject card, DeckDefinition deck ) => card.Value.Resolve( deck ).Value;

	/// <summary>Suit letter from the card key, e.g. 'H' / 'D' / 'S' / 'C' (or '?' if unknown).</summary>
	public static char SuitChar( this CardObject card, DeckDefinition deck )
	{
		var key = card.Value.Resolve( deck ).Key; // e.g. "AS", "10H"
		return string.IsNullOrEmpty( key ) ? '?' : key[^1];
	}

	/// <summary>Hearts and diamonds are red.</summary>
	public static bool IsRed( this CardObject card, DeckDefinition deck ) => card.SuitChar( deck ) is 'H' or 'D';

	/// <summary>Short label like "Q♦" (corner rank + centre suit glyph).</summary>
	public static string ShortLabel( this CardObject card, DeckDefinition deck )
	{
		var face = card.Value.Resolve( deck );
		return face.Corner + face.Center;
	}
}