## Definition
Following the examples in the original definition of the standard, as well as several existing implementations, UCI Notation encodes a move (technically a halfmove) as the coordinates of the piece before the move (in the standard file-rank form, so file a rank 1 is `a1`), then the coordinates of the piece after the move (in the same file-rank form), and, if the move is a promotion, one of the characters `q`, `r`, `b`, or `n` to indicate promoting to a `q`ueen, `r`ook, `b`ishop, or k`n`ight, respectively.
---
## Clarifications & Examples
- The opening sequence of the [Queen's Gambit](https://en.wikipedia.org/wiki/Queen%27s_Gambit) is represented as:
1. `d2d4`
2. `d7d5`
3. `c2c4`
- Castling is simply represented by moving the king 2 squares. For example, white King-side Castling is `e1g1`. It is up to an implementation to recognise that, if the king is at `e1` and moves to `g1`, the rook should be moved from `h1` to `f1`, and for white Queen-side Castling if the king moves from `e1` to `c1`, the rook should be moved from `a1` to `d1`.
- Captures are not indicated in any special way. It is up to an implementation to infer when a move is a capture.
- Ranks are 1-indexed, not 0-indexed (`a0` is invalid, `a8` is valid). This is unusual for programming (for good reasons[^2]). However, in order to keep with chess conventions, UCI uses 1-indexing instead.
- White promoting to a queen on the e file is `e7e8q`.
---
## Motivation
The original standard *states* that all moves are formatted in [Long Algebraic Notation.](https://en.wikipedia.org/wiki/Algebraic_notation_(chess)#Long_algebraic_notation) However, this is not *quite* the case. The examples of move notation given in the original document are close to Long Algebraic Notation, but they omit the piece names and omit "x" to indicate captures[^2].
Given this contradiction, I feel it is appropriate to codify the rules that the examples and existing implementations appear to be following.
---
## Original Examples
A short list of examples given in the original document is as follows:
- `e2e4`
- `e7e5`
- `e1g1` - A note indicates that this move is white short castling
- `e7e8q` - A note indicates that this move is a promotion
- `d2d4`
- `g1f3`
- `d1h5` - See below
- `g6h5` - Appears in the example for the [[refutation]] subcommand of [[UCI Docs/Commands/Engine/info|info]]. It is indicated that this move refutes the move `d1h5`, so this move is a capture.
---
[^1]: This will get semi-technical. It is not necessary for understanding UCI. Basically, to a first approximation, the actual physical RAM of your computer can be thought of as an absolutely gigantic array of bytes. A pointer is a term used in systems programming (with languages like C and Rust) to refer to whatever type is used by the hardware to index into that array, which is usually just the native integer type for your CPU. When you, as a programmer, create an array of length `X` whose elements are each `Y` bytes wide (which your language might call a list (but list could also refer to a different thing that is beyond the scope of this footnote), and your language might hide the size and handle it for you), what happens "under the hood" is that your program goes to the operating system, and in a gross oversimplification, asks "Hey operating system, I need (`X * Y`) bytes of memory for an array. Can you please find me a free block of memory at least that big?", and if all goes well, the operating system will return a pointer to the first byte in that block of memory, which your program will save in the variable that represents the array, which I will call `arr`. Then, when your program wants to access the element at index `i` in `arr`, if you're using zero indexing, that can be accomplished by doing *basically* what `physical_memory[arr + (i * X * Y)]` means. If you instead use 1-indexing, that becomes `physical_memory[arr + ((i - 1) * X * Y)]`, which doesn't seem that much worse, especially for code you never see, but it actually it does matter. While addition and subtraction of integers is fast, take note of the fact that basically every program on basically every computer in the world is doing this operation thousands of times per second or more all the time forever. Tiny improvements to performance add up fast in that context.
[^2]: And I checked, it's not just that none of the examples happened to be captures; in the original documentation for the [[refutation]] subcommand of [[UCI Docs/Commands/Engine/info|info]], the example given is `info refutation d1h5 g6h5`, which is indicating that the engine wants to play `g6h5` to capture if it's opponent plays `d1h5`.