President

In President, players play sets of cards from their hand that are higher in precedence than what was played previously. Players can pass and then rejoin the game at any time, however if all players pass in sequence, then the last player to play cards starts with a new set. The goal is to eliminate all cards from your hand before other players.

Rules of Play

These rules are summarized from https://www.pagat.com/climbing/president.html.

President is a climbing game. Other games in this genre include Dou Dizhu (斗地主) and Big Two, along with the commercial game Tichu.

Information Flow

Card Movement Graph

The diagram above visualizes information flow in President using a single random rollout in CardStock. Visibility is attached to card locations, so all cards in a location share the same visibility; information is revealed or concealed as cards move between locations and ownership changes.

Public locations are shown in green, hidden locations in yellow, private locations in blue, and memory locations in light gray. Locations containing cards with distinct backs are indicated with bold borders. Rectangles denote ownership (players or table), and directed edges show card movement between locations and resulting visibility changes. Taken information is shown with red dotted edges (public to private/hidden), and shared information with blue dashed edges (private cards transferred to another player).

Branching Factor

Branching Factor Graph

The figure above illustrates the branching factor (y-axis) for each decision point (x-axis) of President, summarized over 100 random games. We define a decision point as a specific moment at which a player must choose from a set of possible actions. Following this definition, a player can be part of multiple distinct decision points during one of their turns, resulting in successive actions.

Decision Spread

Decision Spread Graph

The figure above illustrates the normalized spread (y-axis) for each decision point (x-axis) of President, summarized over 100 games with all MCTS players. At each decision point, a player evaluates the potential moves in terms of their potential final score. The spread is the difference between the best estimated move and the worst estimated move. This value is then divided by the highest spread found during the game to calculate the normalized spread.

Lead History

Lead History Graph

The figure above illustrates the normalized average lead history (y-axis) for each decision point (x-axis) of President, summarized over 100 games with all MCTS players. At each decision point, a player evaluates the potential moves in terms of their potential final score. For the best estimated move, they record the estimated score for all players, assigning them normalized rank estimates, where 1 is first place, and 0 is last place. Across 100 games, these histories are grouped according to final game rank, and then averaged.

RECYCLE Code

The rules for President are coded in RECYCLE, a card game description language, to encourage standardized implementations across different systems.

You can also Download the code.

;; President
;; https://www.pagat.com/climbing/president.html

(game
 (declare 5 'NUMP)
 (setup 
  (create players 'NUMP)
  
  ;; Create the deck source
  (create deck (game iloc STOCK) (deck 
   (RANK (ACE, TWO, THREE, FOUR, FIVE, SIX, 
          SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING))
   (COLOR (RED   (SUIT (HEARTS, DIAMONDS)))
          (BLACK (SUIT (SPADES, CLUBS)))))))         
 
 ;; Shuffle and deal each player 18 cards
 (do (
  (shuffle (game iloc STOCK))
  (set (game sto POINTS) 2)
  (set (game points PRECEDENCE) 
   (((RANK : TWO)  15) ((RANK : ACE) 14) ((RANK : KING) 13) ((RANK : QUEEN) 12)
    ((RANK : JACK) 11) ((RANK : TEN) 10) ((RANK : NINE)  9) ((RANK : EIGHT)  8)
    ((RANK : SEVEN) 7) ((RANK : SIX)  6) ((RANK : FIVE)  5) ((RANK : FOUR)   4)
    ((RANK : THREE) 3)))))

 (stage player 
  (end (== (size (game iloc STOCK)) 0))
  (do (
   (move (top (game iloc STOCK))
         (top ((current player) iloc HAND))))))  
 
 ;; players play until all players are out of cards
 (stage player
  (end (all player 'P (== (size ('P iloc HAND)) 0)))
  (choice (

   ;; First, play anything
   ((== (size (game vloc PLAY)) 0)
    (any (partition RANK ((current player) iloc HAND)) 'PAR
     (any (subsets 'PAR) 'S 
      (do (
       (set (game sto SIZE) (size 'S))
       (repeat all
        (move (top 'S) 
              (top (game vloc PLAY)))))))))

   ;; play anything that beats the current PLAY and is the same size
   ((> (size (game vloc PLAY)) 0)
    (any (partition RANK ((current player) iloc HAND)) 'PAR
     (any (subsets 'PAR) 'S 
      ((and (== (size 'S) (game sto SIZE))
            (> (score (top 'S) using (game points PRECEDENCE))
               (score (top (game vloc PLAY)) using (game points PRECEDENCE))))
       (repeat all 
        (move (top 'S) 
              (top (game vloc PLAY))))))))

   ;; you can always pass if you are not the first player
   ((or (> (size (game vloc PLAY)) 0)
        (== (size ((current player) iloc HAND)) 0))
    (inc (game sto PASSING)))))

  (do (
   ;; if everyone passed, then discard the PLAY
   ((== (game sto PASSING) (- 'NUMP 1))
    (do (
     (set (game sto PASSING) 0)
     (repeat all 
      (move (top (game vloc PLAY))
            (top (game vloc DISCARD)))))))

   ;; determine your score if you go out
   ((and (== (size ((current player) iloc HAND)) 0)
         (== ((current player) sto SCORE) 0))
    (do (
     (set ((current player) sto SCORE) (game sto POINTS))
     ((> (game sto POINTS) 0)
      (dec (game sto POINTS)))))))))

 (scoring max ((current player) sto SCORE)))