...

Source file src/code.rocketnine.space/tslocum/joker/card.go

Documentation: code.rocketnine.space/tslocum/joker

     1  package joker
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  )
     8  
     9  // Invalid is the text shown when a valid face or suit is not found.
    10  const Invalid = "?"
    11  
    12  // Card defines a playing card with a face and suit.
    13  type Card struct {
    14  	Face CardFace
    15  	Suit CardSuit
    16  }
    17  
    18  // Parse parses a card identifier to construct a card.
    19  func Parse(identifier string) (Card, bool) {
    20  	identifier = strings.TrimSpace(strings.ToUpper(identifier))
    21  
    22  	l := len(identifier)
    23  	if l != 2 && l != 3 {
    24  		return Card{}, false
    25  	}
    26  
    27  	var cardFace CardFace
    28  	switch identifier[:l-1] {
    29  	case "A":
    30  		cardFace = FaceAce
    31  	case "2":
    32  		cardFace = Face2
    33  	case "3":
    34  		cardFace = Face3
    35  	case "4":
    36  		cardFace = Face4
    37  	case "5":
    38  		cardFace = Face5
    39  	case "6":
    40  		cardFace = Face6
    41  	case "7":
    42  		cardFace = Face7
    43  	case "8":
    44  		cardFace = Face8
    45  	case "9":
    46  		cardFace = Face9
    47  	case "10":
    48  		cardFace = Face10
    49  	case "J":
    50  		cardFace = FaceJack
    51  	case "Q":
    52  		cardFace = FaceQueen
    53  	case "K":
    54  		cardFace = FaceKing
    55  	case "!":
    56  		cardFace = FaceJoker
    57  	default:
    58  		return Card{}, false
    59  	}
    60  
    61  	var cardSuit CardSuit
    62  	switch identifier[l-1:] {
    63  	case "H":
    64  		cardSuit = SuitHearts
    65  	case "D":
    66  		cardSuit = SuitDiamonds
    67  	case "C":
    68  		cardSuit = SuitClubs
    69  	case "S":
    70  		cardSuit = SuitSpades
    71  	case "!":
    72  		cardSuit = SuitJoker
    73  	default:
    74  		return Card{}, false
    75  	}
    76  
    77  	return Card{cardFace, cardSuit}, true
    78  }
    79  
    80  // Value returns the numeric value of a card.
    81  func (c Card) Value() int {
    82  	return (int(c.Face) * 100) + int(c.Suit)
    83  }
    84  
    85  // Equal returns whether both cards have the same face and suit.
    86  func (c Card) Equal(b Card) bool {
    87  	return b.Face == c.Face && b.Suit == c.Suit
    88  }
    89  
    90  // Identifier returns a machine-readable representation of a card.
    91  func (c Card) Identifier() string {
    92  	if c.Suit.Name() == Invalid || c.Suit.Name() == Invalid {
    93  		return "??"
    94  	}
    95  
    96  	var faceidentifier string
    97  	if c.Face == FaceJoker {
    98  		faceidentifier = "!"
    99  	} else if c.Face == Face10 {
   100  		faceidentifier = c.Face.Name()
   101  	} else {
   102  		faceidentifier = string(c.Face.Name()[0])
   103  	}
   104  
   105  	var suitidentifier string
   106  	if c.Suit == SuitJoker {
   107  		suitidentifier = "!"
   108  	} else {
   109  		suitidentifier = c.Suit.Name()[0:1]
   110  	}
   111  
   112  	return strings.ToUpper(faceidentifier + suitidentifier)
   113  }
   114  
   115  // String returns a human-readable representation of a Card.
   116  func (c Card) String() string {
   117  	var cardFace string
   118  	if c.Face == 14 {
   119  		cardFace = "! "
   120  	} else {
   121  		cardFace = c.Face.Name()[0:1]
   122  		if c.Face == 10 {
   123  			cardFace += "0"
   124  		} else {
   125  			cardFace += " "
   126  		}
   127  	}
   128  
   129  	return fmt.Sprintf("[%s %s  %c]", cardFace, c.Suit.Symbol(), c.Suit.Name()[0])
   130  }
   131  
   132  // MarshalJSON marshals a Card.
   133  func (c Card) MarshalJSON() ([]byte, error) {
   134  	return json.Marshal(c.Identifier())
   135  }
   136  
   137  // UnmarshalJSON unmarshals a Card.
   138  func (c *Card) UnmarshalJSON(b []byte) error {
   139  	var identifier string
   140  	if err := json.Unmarshal(b, &identifier); err != nil {
   141  		return err
   142  	}
   143  
   144  	card, _ := Parse(identifier) // Ignore ok
   145  	*c = card
   146  	return nil
   147  }
   148  

View as plain text