Portable Chess Notation

A general purpose JSON-based format for recording chess variants.

Created
Updated
Version
1.0.0

Introduction

PCN (Portable Chess Notation) is a lightweight format based on JSON and PMN that gives a consistent and easy way to represent most chess-derived games.

Able to describe both multidimensional games and related moves, in progress and finished games, easy for humans to read and write, and easy for machines to import and export, it is completely laws of chess independent and compatible with the main variants, including 장기Janggi, หมากรุกMakruk, 将棋Shogi, Chess, 象棋Xiangqi. These properties make PCN an ideal data-interchange format for recording chess games.

Notational conventions

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

Notation for Games

Properties

The following table defines the properties that appear in this resource:

Property name Type Required Nullable Default Description
board a hash false false {} The board at the beginning of the game.
event a string false true null The name of the tournament or match event.
finished_at a datetime false true null The datetime when the game could end or ended.
href a string false true null The URL of a website that display the game.
indexes an array true false   The shape of the board.
location a string false true null The place or position of the game.
moves an array false false [] The moves previously played.
name a string false true null The name of the game.
round an unsigned integer false true null The playing round ordinal of the game.
sides an array true false   The list of players.
started_on a date false true null The date the game started.
state a state object false false {} The properties of the last position.

Board

The reserved “board” property is RECOMMENDED.

If the property is not present, this means that there are no pieces on the board.

The “board” property specifies a one-dimensional list of board representing the first position. It could represent a starting position, or the position of a Chess problem.

Empty board example:

{}

Chess starting position example:

{
  "0":  "♜",  "1": "♞",  "2": "♝",  "3": "♛",  "4": "♚",  "5": "♝",  "6": "♞",  "7": "♜",
  "8":  "♟",  "9": "♟", "10": "♟", "11": "♟", "12": "♟", "13": "♟", "14": "♟", "15": "♟",




  "48": "♙", "49": "♙", "50": "♙", "51": "♙", "52": "♙", "53": "♙", "54": "♙", "55": "♙",
  "56": "♖", "57": "♘", "58": "♗", "59": "♕", "60": "♔", "61": "♗", "62": "♘", "63": "♖"
}

Event

The reserved “event” property is RECOMMENDED.

The “event” property is the name of the tournament or match event.

Finished datetime

The reserved “finished_at” property is RECOMMENDED.

The “finished_at” property specifies the datetime when the game could end or ended.

The value is specified in ISO 8601 format (eg “1994-11-05T13:15:30Z”).

If the property is not present, or if the property is present and its value is null or smaller than or equal to the current datetime, the game MUST be considered finished. Otherwise, the game MUST be considered in progress because the value is greater than the current datetime.

Hyperlink

The reserved “href” property is RECOMMENDED.

The “href” property specifies a link that targets a document about the game.

Indexes of the board

The reserved “indexes” property is REQUIRED.

The “indexes” property specifies the shape of the board.

This is a tuple of integers indicating the size of the array in each dimension. For a two-dimensional board, n would be the number of rows and m the number of columns: [n, m].

Examples:

Location

The reserved “location” property is RECOMMENDED.

Indicates the place or position that the game was in or where it happened.

Example: “San Francisco, CA

Moves

The reserved “moves” property is OPTIONAL.

The “moves” property represents an ordered set of actions based on Portable Move Notation format.

If the property is not present, the list of moves MUST be considered as empty.

King’s Gambit example:

[
  [52, 36, "P", nil],
  [12, 28, "p", nil],
  [53, 37, "P", nil]
]

Name

The reserved “name” property is RECOMMENDED.

Indicates the name of the game.

Round

The reserved “round” property is RECOMMENDED.

The “round” property is the number of the game played between the players of the current described game.

If present, the value MUST be greater than or equal to 1.

Sides

The reserved “sides” property is RECOMMENDED.

The “sides” property represents the list of players.

When this list is empty, there MUST be no pieces on the board, nor pieces in hand.

The ordering of the sides MUST be the same as the order in which players traditionally play from starting position.

For example,

Started date

The reserved “started_on” property is RECOMMENDED.

The “started_on” property specifies the starting date for the game.

The value is specified in ISO 8601 format (eg “1997-07-16”).

State

The reserved “state” property is RECOMMENDED.

The “state” property represents the properties of the last position.


State object

Properties

The following table defines the properties that appear in this resource:

Property name Type Required Nullable Default Description
is_in_check a boolean false true null The King is under threat of capture on their opponent’s next turn.
is_topside_better a boolean false true null Depending on whether the game is in progress or over, may indicate whether the game is won, lost or drawn.

In check?

The reserved “is_in_check” property is RECOMMENDED.

The “is_in_check” property specifies the current player’s king (or general in Xiangqi and Janggi) is under threat of capture on their opponent’s next turn.

Top-side better?

The reserved “is_topside_better” property is RECOMMENDED.

When the game is in progress, indicates whether top-side would win, lose or if there would be a draw at the end of regulation time. Or when the game is over, indicates if top-side has won, lost or if there is a draw.

Player object

Properties

The following table defines the properties that appear in this resource:

Property name Value Required Nullable Default Description
elo an unsigned integer false true null The Elo rating of the player.
in_hand_pieces an array false false [] The list of pieces in hand of the player at the beginning of the game.
is_requesting_a_draw a boolean false false false The player is offering a draw.
name a string false true null The name of the player.

Player Elo

The reserved “elo” property is RECOMMENDED.

The “elo” property represents the relative skill level of a player at the beginning of the game, according to the Elo rating system.

If present, the value MUST be greater than or equal to 0.

Example: 1735

The list of pieces in hand

The reserved “in_hand_pieces” property is RECOMMENDED.

The “in_hand_pieces” property represents a set of pieces retained in hand at the beginning of the game, by the player.

Example of value from a tsume Shogi position, for Sente player:

["S"]

Most of the time, this list should be empty because the players have not yet captured any pieces in the starting position.

Draw request

The reserved “is_requesting_a_draw” property is RECOMMENDED.

The “is_requesting_a_draw” property represents a proposal for a draw from the player to the opponent player. If the opponent accepts, the game is a draw (by mutual agreement).

If the property is not present, or if the property is present and its value is null, there is no proposal for a draw.

Player's name

The reserved “name” property is RECOMMENDED.

The “name” property represents the name of the player.

Example: “Bob


Examples

Albin Countergambit, Lasker Trap, at Chess, in PCN format:

{
  "board": {
    "0":  "♜",  "1": "♞",  "2": "♝",  "3": "♛",  "4": "♚",  "5": "♝",  "6": "♞",  "7": "♜",
    "8":  "♟",  "9": "♟", "10": "♟", "11": "♟", "12": "♟", "13": "♟", "14": "♟", "15": "♟",




    "48": "♙", "49": "♙", "50": "♙", "51": "♙", "52": "♙", "53": "♙", "54": "♙", "55": "♙",
    "56": "♖", "57": "♘", "58": "♗", "59": "♕", "60": "♔", "61": "♗", "62": "♘", "63": "♖"
  },

  "href": "https://en.wikipedia.org/wiki/Albin_Countergambit,_Lasker_Trap",
  "indexes": [8, 8],

  "moves": [
    [ 51, 35, "♙" ],  [ 11, 27, "♟" ],
    [ 50, 34, "♙" ],  [ 12, 28, "♟" ],
    [ 35, 28, "♙" ],  [ 27, 35, "♟" ],
    [ 52, 44, "♙" ],  [  5, 33, "♝" ],
    [ 58, 51, "♗" ],  [ 35, 44, "♟" ],
    [ 51, 33, "♗" ],  [ 44, 53, "♟" ],
    [ 60, 52, "♔" ],  [ 53, 62, "♞" ],
    [ 63, 62, "♖" ],  [  3, 38, "♝" ]
  ],

  "name": "Albin Countergambit, Lasker Trap",

  "sides": [
    { "name": "Korody" },
    { "name": "Bologh" }
  ],

  "started_on": "1933-01-01",

  "state": {
    "is_in_check": true,
    "is_topside_better": true
  }
}

Immortal Chess game, in PCN format:

{
  "board": {
    "0":  "♜",  "1": "♞",  "2": "♝",  "3": "♛",  "4": "♚",  "5": "♝",  "6": "♞",  "7": "♜",
    "8":  "♟",  "9": "♟", "10": "♟", "11": "♟", "12": "♟", "13": "♟", "14": "♟", "15": "♟",




    "48": "♙", "49": "♙", "50": "♙", "51": "♙", "52": "♙", "53": "♙", "54": "♙", "55": "♙",
    "56": "♖", "57": "♘", "58": "♗", "59": "♕", "60": "♔", "61": "♗", "62": "♘", "63": "♖"
  },

  "event": "London",
  "href": "https://en.wikipedia.org/wiki/Immortal_Game",
  "indexes": [8, 8],
  "location": "London ENG",

  "moves": [
    [ 52, 36, "♙" ],  [ 12, 28, "♟" ],
    [ 53, 37, "♙" ],  [ 28, 37, "♟" ],
    [ 61, 34, "♗" ],  [  3, 39, "♛" ],
    [ 60, 61, "♔" ],  [  9, 25, "♟" ],
    [ 34, 25, "♗" ],  [  6, 21, "♞" ],
    [ 62, 45, "♘" ],  [ 39, 23, "♛" ],
    [ 51, 43, "♙" ],  [ 21, 31, "♞" ],
    [ 45, 39, "♘" ],  [ 23, 30, "♛" ],
    [ 39, 29, "♘" ],  [ 10, 18, "♟" ],
    [ 54, 38, "♙" ],  [ 31, 21, "♞" ],
    [ 63, 62, "♖" ],  [ 18, 25, "♟" ],
    [ 55, 39, "♙" ],  [ 30, 22, "♛" ],
    [ 39, 31, "♙" ],  [ 22, 30, "♛" ],
    [ 59, 45, "♕" ],  [ 21,  6, "♞" ],
    [ 58, 37, "♗" ],  [ 30, 21, "♛" ],
    [ 57, 42, "♘" ],  [  5, 26, "♝" ],
    [ 42, 27, "♘" ],  [ 21, 49, "♛" ],
    [ 37, 19, "♗" ],  [ 26, 62, "♝" ],
    [ 36, 28, "♙" ],  [ 49, 56, "♛" ],
    [ 61, 52, "♔" ],  [  1, 16, "♞" ],
    [ 29, 14, "♘" ],  [  4,  3, "♚" ],
    [ 45, 21, "♕" ],  [  6, 21, "♞" ],
    [ 19, 12, "♗" ]
  ],

  "name": "Immortal Game",

  "sides": [
    { "name": "Adolf Anderssen" },
    { "name": "Lionel Adalbert Bagration Felix Kieseritzky" }
  ],

  "started_on": "1851-06-21",

  "state": {
    "is_in_check": true,
    "is_topside_better": false
  }
}

Very short Shogi game, in PCN format:

{
  "board": {
     "0": "l",  "1": "n",  "2": "s",  "3": "g",  "4": "k",  "5": "g",  "6": "s",  "7": "n",  "8": "l",
               "10": "r",                                                        "16": "b",
    "18": "p", "19": "p", "20": "p", "21": "p", "22": "p", "23": "p", "24": "p", "25": "p", "26": "p",



    "54": "P", "55": "P", "56": "P", "57": "P", "58": "P", "59": "P", "60": "P", "61": "P", "62": "P",
               "64": "B",                                                        "70": "R",
    "72": "L", "73": "N", "74": "S", "75": "G", "76": "K", "77": "G", "78": "S", "79": "N", "80": "L"
  },

  "href": "https://userpages.monmouth.com/~colonel/shortshogi.html",
  "indexes": [9, 9],

  "moves": [
    [   56, 47,  "P"      ],  [    3, 11,  "g"      ],
    [   64, 24, "+B", "P" ],  [    5, 14,  "g"      ],
    [   24, 14, "+B", "G" ],  [    4,  3,  "k"      ],
    [ null, 13,  "G"      ]
  ],

  "name": "The Shortest Possible Game of Shogi",

  "sides": [
    { "name": "アリス" },
    { "name": "ボブ" }
  ],

  "state": {
    "is_in_check": true,
    "is_topside_better": false
  }
}

A classic Shogi problem, in PCN format:

{
  "board": {
                                      "3": "s",  "4": "k" ,  "5": "s",

                                                "22": "+P",

                                                                                 "43": "+B"




  },

  "indexes": [9, 9],

  "moves": [
    [   43, 13, "+B"      ],  [    5, 13,  "s", "b" ],
    [ null, 14,  "S"      ]
  ],

  "name": "Tsume in 2 moves",

  "sides": [
    {
      "in_hand_pieces": ["S"],
      "name": "アリス"
    },
    {
      "in_hand_pieces": ["r", "r", "b", "g", "g", "g", "g", "s", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p"],
      "name": "ボブ"
    }
  ],

  "state": {
    "is_in_check": true,
    "is_topside_better": false
  }
}

Short double cannons checkmate at Xiangqi, in PCN format:

{
  "board": {
     "0": "車",
     "1": "馬",
     "2": "象",
     "3": "士",
     "4": "將",
     "5": "士",
     "6": "象",
     "7": "馬",
     "8": "車",
    "19": "砲",
    "25": "砲",
    "27": "卒",
    "29": "卒",
    "31": "卒",
    "33": "卒",
    "35": "卒",
    "54": "兵",
    "56": "兵",
    "58": "兵",
    "60": "兵",
    "62": "兵",
    "64": "炮",
    "70": "炮",
    "81": "俥",
    "82": "傌",
    "83": "相",
    "84": "仕",
    "85": "帥",
    "86": "仕",
    "87": "相",
    "88": "傌",
    "89": "俥"
  },

  "indexes": [10, 9],

  "moves": [
    [ 64, 67, "炮" ],  [ 25, 22, "砲" ],
    [ 70, 52, "炮" ],  [ 19, 55, "砲" ],
    [ 67, 31, "炮" ],  [ 22, 58, "砲" ],
    [ 52, 49, "炮" ]
  ],

  "name": "Short Double Cannons Checkmate",

  "sides": [
    { "name": "愛麗絲" },
    { "name": "與鮑伯" }
  ],

  "state": {
    "is_in_check": true,
    "is_topside_better": false
  }
}

See also
Implementation
Informative References

This work is influenced by several documents.