For our second game, Pairs, we move away from the trick-taking of Agram to a different genre, and switch up the player goal from winning tricks to avoiding points. These new wrinkles will show themselves in the coding, statistics, and heuristics as we dive into our analysis.
Pairs is a press-your-luck card game for 2 to 6 players, described by designers James Ernest and Paul Peterson as a new classic pub game, which I interpret to mean it is meant to be a light, fun way to pass the time when you’re drinking with friends. It was released in 2014 following a very successful kickstarter, and includes many variant decks and artwork, some of which are based on the world of The Kingkiller Chronicle by Patrick Rothfuss.
First, let’s see how you play!
Rules
Pairs uses a custom deck of 55 cards, containing one card of value 1, two cards of value 2, etc., up to ten cards of value 10. Each round players are dealt one card to a face-up hand, and then players cycle in turn order to either end the round by scoring the minimum value card in play or draw another card into their hand. If the drawn card is the same value as a card currently in their hand, the player scores that many points and the round is over. The first player to score a set number of points over multiple rounds is the loser, so players strive to minimize their points.
RECYCLE Coding
To illustrate how we encode these rules computationally, we will walk through in detail the RECYCLE code for Pairs.
We start by declaring the number of players as the 'NUMP
variable, and place each player
on their own team. (Teams will matter more in later games, but for these initial games, players
are all on their own.)
Next, we create the triangular deck, giving each card a single attribute of VALUE
. The
repeat
action is put to good use here to create the multiple cards of each value.
So we can compare the cards quickly, a PointMap is created to assign
the string attributes for VALUE
to integers.
The final part of the setup is to shuffle the deck, then burn through 5 cards
to the THROWOUT
pile, to make the game a little more unpredictable.
Now we start to play the game. This first stage sets up the rounds, and will continue until one player has enough points to lose the game.
How many points does it take to lose? The rules state “Take 60, divide by the number of players, then add 1.” Thankfully 60 is evenly divisible by 2, 3, 4, 5, and 6, so we’ll always have an integer as the loss threshold.
The first action of each round is for the game to check if there are enough
cards to deal out an initial card to each player. If not, we will need to
reset the STOCK
location by adding in all of the cards that were thrown out
earlier to the THROWOUT
location, along with those in the DISCARD
location.
The STOCK
is then shuffled again, and 5 random cards are moved to THROWOUT
to
fog up the game.
We are secure that each player can get a card to start, so we deal each player
a card from STOCK
, which they place in their face-up HAND
. The player with the
smallest card will go first, since they are currently “winning” the game.
If there is a tie, then technically, we should add another stage here, which would deal new card and try again to find the minimum of those just dealt, repeating until a clear minimum card emerges.
But, for simplicity, our simulation engine will just break the tie randomly.
Players now take turns in an inner stage, pressing their luck until one has a pair or stops voluntarily.
Before each player’s turn, however, we must check the deck again, and reset if there are not enough cards for a deal.
Here is the code for the player’s choice. First, they can either stop their turn, by
moving the smallest card in anyone’s HAND
to their SCORING
location, and
set the stage to be finished after their turn. Alternately, they can
press-their-luck and deal the top card from the STOCK
to their HAND
.
The second choice above could result in a pair of cards in the player’s HAND
, two cards
with the same value. If this is found, the round is ended, and
one of those cards of the pair is moved to the player’s SCORING
location.
The cards in a pair are found with the tuples
function, which looks through the
current player’s HAND
for any groups of two cards with the same point value using the
'POINTS
PointMap we created earlier.
When the round is over, we move all cards from player’s HAND
locations to the DISCARD
pile, reset the
FINISHED
flag for the inner round, and start a new round.
To score the game, we will sort the players based on the sum of the cards in their
SCORING
pile. The player with the highest score loses, and for our purposes, the
player with the lowest score wins.
Up Next
In the next post, we’ll look at the same two questions we asked for Agram, does the player have choices, and is there opportunity for strategy? We’ll also look at the way AI players affect the length of the game for Pairs, something not possible in a trick-taking game like Agram.
Get ready to spin up some simulations with random and AI players and watch the shape of Pairs come together!
comments powered by Disqus