Decks of Cards

These examples are meant to demonstrate the type of output you can expect to create with protograf. They are not meant to be exhaustive or fully comprehensive!

Bear in mind that the images shown in these examples are lower-resolution screenshots; the original PDFs that can be generated from the source scripts will demonstrate full scalability.

Simple

Title

Simple set of Cards

Script

cards_design.py

Discussion

This example shows how to construct a deck of cards using these commands (only an extract of the code is shown here):

l1 = line(
    x=0.8, x1=5.6, y=7.1, y1=8.4,
    stroke="gold", stroke_width=2)
r1 = rectangle(
    x=0.7, y=7.0, width=5, height=1.5,
    stroke_width=1, rounding=0.2)
low = group(r1, l1)

Card([1,2,3], low)
Card("4-6", r1)
Card("7,8,9", l1)

This is a simple design of lines and rectangles. These are assigned names which can be used directly; or indirectly as part of a group.

The assignment as to which card (Card) can either be done via a string e.g. "4-6" or a list of numbers e.g. [1,2,3].

To set changes for cards at intervals; for example, a set of even cards — as defined by their sequence number — or a set odd cards:

# element added to every odd card in the range
Card(steps(1,9,2), rectangle())
# element added to every even card in the range
Card(steps(2,10,2), circle())

An alternate way to set changes for cards, specifically for odd and even cards:

# element added to every odd card in the deck
Card("odd", rectangle())
# element added to every even card in the deck
Card("even", circle())

Screenshot

../_images/cards_simple.png

Matrix Generated

Title

Cards generated from a Matrix

Script

cards_matrix_one.py

Discussion

This example shows how to construct a deck of cards using these commands (only an extract of the code is shown here):

combos = Matrix(
    labels=['SUIT', 'VALUE', 'IMAGE'],
    data=[
        # tomato, lime, aqua, gold, hotpink
        ['#FF6347', '#00FF00','#00FFFF', '#FFD700', '#FF69B4'],
        ['5', '3', '1'],
        # tapedrive, heart, snowflake
        ['\U+2707', '\U+2766', '\U+2745']
    ])
Data(matrix=combos)

The use of the Matrix command is helpful for a design that is a combination/permutation scenario.

In this example each card will display a unique combination of a SUIT - these are hexadecimal colors in the first list that appears in data — plus a VALUE — these are the numbers in the second list appearing in data — and also an IMAGE — these are the Unicode symbols shown in the third list of data.

Hint

As can be seen, a Unicode symbol is shown by 4-characters prefixed by the \U+ (For more, see Unicode character resources.)

The Unicode symbols available are specific to the font being used.

Once defined in the Matrix, the results will be generated and stored via the Data command’s matrix property.

Screenshot

../_images/cards_matrix.png

Standard Playing Cards

Title

Standard Playing Cards generated from a Matrix & Images

Script

cards_standard.py

Discussion

This example shows how to construct a deck of cards using these commands (only an extract of the code is shown here).

The bulk of the cards are generated via a Matrix (see the Matrix example above), also using Unicode symbols for the SUIT and a list of the standard card VALUE letters and numbers:

combos = Matrix(
    labels=['SUIT', 'VALUE'],
    data=[
        # spade, club, heart, diamond
        ['\u2660', '\u2663', '\u2665', '\u2666'],
        ['K','Q','J','10','9','8','7','6','5','4','3','2','A'],
    ])
Data(matrix=combos, extra=2)

The extra property for the Data command allows the deck to consist of more more cards than those generated by the Matrix; so, in this case, 4 suits multiplied by 13 values is 52 cards. The two Jokers are the 2 “extras” (card numbers 53 and 54).

The Number cards consist of text and a colored suit - because the suit is created from a Unicode symbol it is also text; the locations of these are set via common properties; and the color is set via a stroke property.

The Royalty cards require an image, whose settings are created via a Common command:

royals = Common(x=1.5, y=1.8, width=3.5, height=5)
Card("14", image("images/king_c.png", common=royals))
Card("15", image("images/queen_c.png", common=royals))

The Ace of Spades is often specially demarcated in a deck via a more elaborate design. In this case, the design is simply two large spades symbols, of different colors, superimposed:

Card("13",
     text(x=3.15, y=2.6, font_size=180, stroke="black",
          text='\u2660'),
     text(x=3.15, y=3.8, font_size=60, stroke="white",
          text='\u2660'))

The Jokers (not shown in the screenshot) are the extra 2 cards needed for a standard deck. In this case they also require an image, as well as text whose properties are created via the same Common command used for number cards:

jok_pic = Common(x=0.8, y=1.9, width=5, height=5)
Card("53",
     text(common=value_top, stroke="black", text='J'),
     text(common=value_low, stroke="black", text='J'),
     image("images/joker_black.png", common=jok_pic))

Screenshot

../_images/cards_standard.png

Image-Only Cards

Title

Cards generated from a directory of images

Script

cards_images.py

Discussion

This example shows how to construct a deck of cards using these commands (only an extract of the code is shown here):

Data(images="pictures", images_filter=".png,.jpg")
# add an image from Data to each card
Card("*", image("*", x=0, y=0, width=6.3, height=8.8))

The commands for generating cards that just consist of an image are simple. the Data command’s images property points to a directory containing all the images.

It can be helpful to ensure that any non-image files stored in that images directory are ignored; for this purpose the images_filter property can be set to contain a comma-delimited list of allowable file extensions.

The Card command sets all cards in the deck (via *) to each use an image; but in thise case no Image name is set as this will be “filled in” with the names from the Data.

Credits: the original image that was “chopped up” to form the set of images used for these example cards was sourced from: https://picjumbo.com/mysterious-fantasy-forest-with-old-bridges/

Screenshot

../_images/cards_images.png

Hexagonal Cards

Title

Hexagonal-shaped Cards

Script

cards_hexagonal.py

Discussion

This example shows how to construct a deck of cards/tiles using these commands (only an extract of the code is shown here):

Data(filename="lotr.csv")
Deck(
    cards=6,
    shape='hexagon',
    height=6.3,
    copy='Copies',
    stroke='darkgray',
    grid_marks=True)

It can be seen that each alternate row is offset from the ones on either side of it; this is to make cutting such cards/tiles much easier.

In addition, the use of the grid_marks property will cause short lines to be drawn along each edge of the page in order to support easier cutting of such cards/tiles.

Screenshot

../_images/cards_hexagonal.png

Circular Cards

Title

Circular-shaped Cards

Script

cards_circular.py

Discussion

This example shows how to construct a deck of cards using these commands (only an extract of the code is shown here):

Data(filename="lotr.csv")
Deck(
    cards=1,
    shape='circle',
    radius=3.15,
    copy='Copies')

Screenshot

../_images/cards_circular.png

Play Money

Title

Play Money (using Cards)

Script

supreme.py

Discussion

This example shows how to construct a set of play money using Deck() and Card() commands. This example was inspired by the money found in the game “Supremacy” (Supremacy Games, 1984).

Of interest is the use of PolyLine() command to create the logo at the centre, with the Repeat() command used to create the set of lines that forms the background to the logo.

The data used to set the various denomination values and their colors is “baked into” the script using the list-of-lists approach.

Screenshot

../_images/supreme.png

Access to an API

Title

Data Accessed from an API

Script

cards_api.py

Discussion

This example shows how to construct a deck of cards using data obtained from an API (only an extract of the code is shown here):

import requests

  def get_api_data():
      result = requests.get(
          'https://restcountries.com/v3.1/all?'
          'fields=name,area,population,fifa,continents')
      data = result.json()
      countries = []
      for d in data:
          countries.append(
              {'name': d['name']['common'],
               'area': d['area'],
               'pop': d['population'],
               'fifa': d['fifa'],
               'continent': d['continents'][0]}
          )
      return countries

  Data(
      source=get_api_data(),
      filters=[('fifa', '', 'ne')])

This example makes use of the following Python features:

  • def to create a new function

  • import to load another library

  • for to create a loop

  • append to add items to a list

In this example, an API is called. This is a web site that is able to provide a data set in a structured format. The Python requests library makes this very straightforward to do.

A loop allows each item of data in the data set to be accessed. Columns from each item can then be accessed using the [] notation. This allows the chosen columns to be added as a set of key/value of pairs using the {} notation to a list.

The Data() command allows the new function, which creates the dataset in format usuable by protograf, to be accessed via the source property.

Use of the filters property allows a subset of the data to be chosen for the Cards.

Screenshot

../_images/countries_cards.png