Image source: By Bermicourt - Own work, CC BY-SA 4.0
Skitgubbe is a two-phase game. The cards are shuffled and each player is dealt 3 cards. In the first phase, players play two-card tricks with the player to their left. Players do not have to follow suit, and draw a card from the deck after playing. The winner of the trick is the player with the highest-ranked card, and saves the won cards for phase two, with ties forcing a repeat of the trick with the same two players. The winner of the trick starts the new trick with the player to their left.
Once all cards have been played in phase one, players show all of their cards, and the trump suit for phase two is recorded as the suit of the last card drawn from the deck.
In the second phase, players repeatedly play cards to a central trick as long as they have cards that follow suit and are higher in rank than the last card played, or they have trump. If the player has no higher cards, they must take the top card from the trick. When the number of cards played equals the number of players, then the cards in the trick are discarded. If a player has no more cards, they exit the game, and the last player to exit loses.
These rules are summarized from https://www.pagat.com/beating/skitgubbe.html.
Skitgubbe is a beating game. Other games in this genre include Dudak, Cheat and Idiot.
The diagram above visualizes information flow in Skitgubbe 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).
The rules for Skitgubbe are coded in RECYCLE, a card game description language, to encourage standardized implementations across different systems.
You can also Download the code.
;; Skitgubbe
;; https://www.pagat.com/beating/skitgubbe.html
(game
(setup
(create players 3)
;; Create the deck source
(create deck (game iloc STOCK)
(deck (RANK (ACE, TWO, THREE, FOUR, FIVE, SIX,
SEVEN, EIGHT, NINE, TEN, J, Q, K))
(COLOR (RED (SUIT (HEARTS, DIAMONDS)))
(BLACK (SUIT (SPADES, CLUBS)))))))
;; Shuffle and deal each player 3 cards
(do (
(shuffle (game iloc STOCK))
;; card precedence
(set (game points PHASEONE)
(((RANK : ACE) 14) ((RANK : K) 13) ((RANK : Q) 12)
((RANK : J) 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)
((RANK : TWO) 2)))
(all player 'P
(repeat 3 (move (top (game iloc STOCK))
(top ('P iloc HAND)))))))
;; PHASE 1: players play two-card tricks until one person out of cards
(stage player
(end (== (size ((next player) iloc HAND)) 0))
;; players play a hand once
(stage player
(end (or (== (size ((next player) iloc HAND)) 0)
(== (size (union (all player 'P ('P vloc TRICK)))) 2)))
(choice (
;; if cards are left in the stock
;; players can use that as their play to trick
((> (size (game iloc STOCK)) 0)
(move (top (game iloc STOCK))
(top ((current player) vloc TRICK))))
;; or play a card from your hand. No need to follow suit
(any ((current player) iloc HAND) 'AC
(move 'AC (top ((current player) vloc TRICK))))))
;; then draw a card back into your hand
(do (
((and (== (size (game iloc STOCK)) 1)
(> (size (game iloc STOCK)) 0)
(< (size ((current player) iloc HAND)) 3))
(move (top (game iloc STOCK))
(top ((current player) iloc TRUMP))))
((and (!= (size (game iloc STOCK)) 1)
(> (size (game iloc STOCK)) 0)
(< (size ((current player) iloc HAND)) 3))
(move (top (game iloc STOCK))
(top ((current player) iloc HAND)))))))
;; after players play hand, wrap up trick
(do (
;; if there is a tie, then replay with those two players
((== (cardatt RANK (top ((current player) vloc TRICK)))
(cardatt RANK (top ((next player) vloc TRICK))))
(do (
((!= (size ((next player) iloc HAND)) 0)
(cycle next (current player)))
(all player 'P
((> (size ('P vloc TRICK)) 0)
(move (top ('P vloc TRICK))
(top ('P vloc HOLDING))))))))
;; otherwise determine who won the hand, set them first next time
((!= (cardatt RANK (top ((current player) vloc TRICK)))
(cardatt RANK (top ((next player) vloc TRICK))))
(do (
(cycle next (owner (max (union (all player 'P ('P vloc TRICK)))
using (game points PHASEONE))))
;; winner gets the cards to save for phase 2
(all player 'P
(do (
((> (size ('P vloc TRICK)) 0)
(move (top ('P vloc TRICK))
(top ((next player) vloc TRICKSWON))))
(repeat all (move (top ('P vloc HOLDING))
(top ((next player) vloc TRICKSWON)))))))))))))
;; IN BETWEEN
(do (
(all player 'P
(do (
;; show your cards
(repeat all
(move (top ('P iloc HAND))
(top ('P vloc TRICKSWON))))
(repeat all
(move (top ('P vloc HOLDING))
(top ('P vloc TRICKSWON))))
;; show trump
((== (size ('P iloc TRUMP)) 1)
(do (
(set (game str TRUMPSUIT)
(cardatt SUIT (top ('P iloc TRUMP))))
(move (top ('P iloc TRUMP))
(top ('P vloc TRICKSWON)))
(cycle current 'P)))))))
(set (game sto NUMP)
(size (filter player 'P (> (size ('P vloc TRICKSWON)) 0))))))
;; PHASE 2: Play the tricks, last out of cards loses
(stage player
(end (== (size (filter player 'P (> (size ('P vloc TRICKSWON)) 0))) 1))
;; BEFORE YOU PLAY
(do (
;; When the trick is over or starting
((or (== (size (game vloc TRICK)) (game sto NUMP))
(== (size (game vloc TRICK)) 0))
(do (
;; discard previous trick, and reset the NUMP for scoring
(repeat all (move (top (game vloc TRICK))
(top (game vloc DISCARD))))
(set (game sto NUMP)
(size (filter player 'P (> (size ('P vloc TRICKSWON)) 0)))))))))
(choice (
;; no card, you pass
((== (size ((current player) vloc TRICKSWON)) 0)
(turn pass))
;; empty trick, you can play anything
((and (!= (size ((current player) vloc TRICKSWON)) 0)
(== (size (game vloc TRICK)) 0))
(any ((current player) vloc TRICKSWON) 'C
(move 'C (top (game vloc TRICK)))))
;; cards played, you need to beat it if you can
((and (!= (size ((current player) vloc TRICKSWON)) 0)
(> (size (game vloc TRICK)) 0))
(any (filter ((current player) vloc TRICKSWON) 'FC
(> (score 'FC using (game points PHASETWO))
(score (top (game vloc TRICK)) using (game points PHASETWO)))) 'C
(move 'C (top (game vloc TRICK)))))
;; or, you can pick up the top card from the trick
((and (!= (size ((current player) vloc TRICKSWON)) 0)
(> (size (game vloc TRICK)) 0))
(move (top (game vloc TRICK))
(top ((current player) vloc TRICKSWON))))))
;; AFTER YOU PLAY
(do (
;; if you are out of cards, you get points
((and (== (size ((current player) vloc TRICKSWON)) 0)
(== ((current player) sto SCORE) 0))
(set ((current player) sto SCORE) (game sto NUMP)))
;; after lead, solifify precedence
((> (size (game vloc TRICK)) 0)
(set (game points PHASETWO)
(((SUIT : (game str TRUMPSUIT)) 200)
((SUIT : (cardatt SUIT (top (game vloc TRICK)))) 100)
((RANK : ACE) 14) ((RANK : K) 13) ((RANK : Q) 12)
((RANK : J) 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)
((RANK : TWO) 2)))))))
;; Player with least number of cards wins
(scoring max ((current player) sto SCORE)))