Cards

A card is represented by a value, A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, followed by a suit, C, D, H, S. Letters must be uppercase.
Colors are represented by B for black and R for Red.
There are three special variables:
current — the card being tested
previous — the most recent successfully played card
previous2 — the next most recent successfully played card.

Tree structure

To limit (somewhat) the complexity of rules, rules may be constructed only from a finite number of functions. The complete list, which might be expanded somewhat in the future, is

	•	suit(card) — returns the suit of a card, as a single letter: C, D, H, or S for Clubs, Diamonds, Hearts, or Spades
	•	color(card) — returns the color of a card, as a single letter: B for black, R for red
	•	value(card) — returns the integer value of a card, from 1 (Ace) to 13 (King)
	•	is_royal(card) — returns True if the card is a Jack, Queen, or King
	•	equal(a, b) — tests if two cards, suits, colors, or values are equal
	•	less(a, b) — tests if a < b; cards are compared first by suit, C < D < H < S, then if suits are equal, by value; for colors, B < R
	•	greater(a, b) — same as less(b, a)
	•	plus1(x) — returns the next higher value, suit, or card in a suit; error if there is none higher
	•	minus(x) — returns the next lower value, suit, or card in a suit; error if there is none lower
	•	even(card) — tests if the cards numeric value is even
	•	odd(card) — tests if the cards numeric value is odd
	•	andf(a, b) — True if both a and b are true
	•	orf(a, b) — True if either or both a and b are true
	•	notf(a) — True if a is False
	•	iff(test, a, b) — if the test is True, evaluate and return a, else evaluate and return b

The root of a Tree, and every internal (non-leaf) node, must contain one of the above functions. Leaves may contain cards, colors, integers, or Booleans. Example:
	rule = Tree(orf, Tree(equal, Tree(color, 'previous'), 'R'), Tree(equal, Tree(color, 'current'), 'R'))

Trees have one important method:
	rule.evaluate((previous2, previous, card)) — evaluate the rule with this tuple of values

A parse method is provided as an easier and somewhat less error-prone way of constructing a Tree. As an example, the above rule can be written as
	rule = parse("if(equal(color(previous), B), equal(color(current), R), True)")

The parser allows the following simplifications:
	•	Strings representing cards or colors should not be quoted
	•	The following alternate representations for functions are supported: and=andf, or=orf, not=notf, if=iff, and equals-equal. All but the last of these were given names ending in ‘f’ to avoid Python’s reserved words.

No methods have been provided for manipulating Trees, for example, for changing one rule into a slightly different rule. Any such operations must be developed by the user.