Position()

Represent a chess position, i.e. the state of a 64-square chessboard with a few additional information (who is about to play, castling rights, en-passant rights).

new Position()

This constructor can be invoked with different types of arguments:

new kokopu.Position('regular');                  //  1 -> Usual starting position.
new kokopu.Position('regular', 'start');         //  2 -> Same as 1.
new kokopu.Position('regular', 'empty');         //  3 -> Empty board.
new kokopu.Position('no-king', 'empty');         //  4 -> Empty board, configured to be considered as legal without any king.
new kokopu.Position('white-king-only', 'empty'); //  5 -> Empty board, configured to be considered as legal with no black king.
new kokopu.Position('black-king-only', 'empty'); //  6 -> Empty board, configured to be considered as legal with no white king.
new kokopu.Position('chess960', 'empty');        //  7 -> Empty board, configured for Chess960.
new kokopu.Position('chess960', scharnaglCode);  //  8 -> One of the Chess960 starting position (`scharnaglCode` is a number between 0 and 959 inclusive).
new kokopu.Position('antichess');                //  9 -> Usual starting position, configured for antichess.
new kokopu.Position('antichess', 'start');       // 10 -> Same as 9.
new kokopu.Position('antichess', 'empty');       // 11 -> Empty board, configured for antichess.
new kokopu.Position('horde');                    // 12 -> Horde chess usual starting position.
new kokopu.Position('horde', 'start');           // 13 -> Same as 12.
new kokopu.Position('horde', 'empty');           // 14 -> Empty board, configured for horde chess.
new kokopu.Position(variant, fenString);         // 15 -> Parse the given FEN string, assuming the given game variant.
new kokopu.Position(fenStringWithVariant);       // 16 -> Parse the given FEN string, taking into account an optional game variant that may be mentioned in prefix.
new kokopu.Position(anotherPosition);            // 17 -> Make a copy of `anotherPosition`.

Please note that the argument 'regular' can be omitted in forms 1, 2, 3. In particular, the constructor can be invoked with no argument, as in new kokopu.Position(): in this case, a new Position initialized to the usual starting position is instantiated (as in forms 1 and 2).

In form 15, variant must be one of the game variant proposed in GameVariant. The variant argument can be omitted if it is set to 'regular' (i.e. if the usual chess rules are used). If variant is set to 'chess960', then the X-FEN syntax can be used for fenString'.

In form 16, fenStringWithVariant is assumed to be a string formatted as 'variant:FEN' (e.g. 'chess960:nrkbqrbn/pppppppp/8/8/8/8/PPPPPPPP/NRKBQRBN w BFbf - 0 1'). The 'variant:' prefix is optional: if omitted, the usual chess rules are used. For the Chess960 variant, the X-FEN syntax can be used for the FEN part of the string.

In form 17, anotherPosition must be another Position object.

Throws:

If the input parameter is not a valid FEN string (can be thrown only in cases 15 and 16).

Type
module:exception.InvalidFEN
See:

Methods

static isEqual(pos1, pos2) → {boolean}

Check whether both given objects represent the same chess position (i.e. the same chess variant, same board, and same turn/castling/en-passant flags).

Parameters:
Name Type Description
pos1 Position
pos2 Position
Returns:
boolean

ascii() → {string}

Return a human-readable string representing the position. This string is multi-line, and is intended to be displayed in a fixed-width font (similarly to an ASCII-art picture).

Returns:
string -

Human-readable representation of the position.

castling(castle) → {boolean}

Get a castle flag (i.e. whether or not the corresponding castle is allowed or not).

Parameters:
Name Type Description
castle Castle | Castle960

Must be Castle960 if the Position is configured for Chess960, or Castle otherwise.

Returns:
boolean

castling(castle, value)

Set a castle flag (i.e. whether or not the corresponding castle is allowed or not).

Parameters:
Name Type Description
castle Castle | Castle960

Must be Castle960 if the Position is configured for Chess960, or Castle otherwise.

value boolean

clear(variantopt)

Set the position to the empty state.

Parameters:
Name Type Attributes Default Description
variant GameVariant <optional>
'regular'

Chess game variant to use.

enPassant() → {EnPassantFlag}

Get the en-passant flag (i.e. the file on which en-passant is allowed, if any).

Returns:
EnPassantFlag

enPassant(value)

Set the en-passant flag (i.e. the file on which en-passant is allowed, if any).

Parameters:
Name Type Description
value EnPassantFlag

fen(optionsopt)

Get the FEN representation of the current Position).

Parameters:
Name Type Attributes Description
options Object <optional>

If not provided, the fiftyMoveClock and the fullMoveNumber fields of the returned FEN string are set respectively to 0 and 1. If field withVariant is true (false by default), then the current game variant is appended as a colon-separated prefix. If field regularFENIfPossible is true (false by default), then castling rights X-FEN are encoded using the regular-FEN coding format (this flag affects only Chess960 positions).

fen(fen, strictopt) → {Object}

Parse the given FEN string and set the position accordingly.

Parameters:
Name Type Attributes Default Description
fen string
strict boolean <optional>
false

If true, only perfectly formatted FEN strings are accepted.

Throws:

If the given string cannot be parsed as a valid FEN string.

Type
module:exception.InvalidFEN
Returns:
Object

figurineNotation(moveDescriptor) → {string}

Return the figurine algebraic notation corresponding to the given move descriptor (figurine algebraic notation is the same as standard algebraic notation, except that chess pieces are represented with their respective unicode character, instead of the first letter of their English name).

Parameters:
Name Type Description
moveDescriptor MoveDescriptor
Returns:
string

figurineNotation(move, strictopt) → {MoveDescriptor}

Parse the given string as figurine algebraic notation and return the corresponding move descriptor (figurine algebraic notation is the same as standard algebraic notation, except that chess pieces are represented with their respective unicode character, instead of the first letter of their English name).

Parameters:
Name Type Attributes Default Description
move string
strict boolean <optional>
false

If true, only perfectly formatted FAN moves are accepted. If false, "small errors" in the input such as a missing capture character, an unnecessary disambiguation symbol... do not interrupt the parsing.

Throws:

If the move parsing fails or if the parsed move would correspond to an illegal move.

Type
module:exception.InvalidNotation
Returns:
MoveDescriptor

getAttacks(square, byWho) → {Array.<Square>}

Return the squares from which a piece of the given color attacks a given square.

Parameters:
Name Type Description
square Square
byWho Color
Returns:
Array.<Square>

hasMove() → {boolean}

Whether at least one legal move exists in the current position or not. If the position is not legal (see Position#isLegal), the returned value is always false.

Returns:
boolean

isAttacked(square, byWho) → {boolean}

Check if any piece of the given color attacks a given square.

Parameters:
Name Type Description
square Square
byWho Color
Returns:
boolean

isCheck() → {boolean}

Return true if the player that is about to play is in check. If the position is not legal (see Position#isLegal), the returned value is always false.

For antichess, this method always returns false.

Returns:
boolean

isCheckmate() → {boolean}

Return true if the player that is about to play is checkmated. If the position is not legal (see Position#isLegal), the returned value is always false.

For antichess, this method returns true if the player about to play has no remaining piece or pawn, or if non of his/her remaining piece can move. (same behavior as Position#isStalemate for this variant).

For horde chess, this method returns true if black has been checkmated or if white has no remaining piece.

Returns:
boolean

isLegal() → {boolean}

Check whether the current position is legal or not.

A position is considered to be legal if all the following conditions are met:

  1. There is exactly one white king and one black king on the board.
  2. The player that is not about to play is not in check.
  3. There are no pawn on ranks 1 and 8.
  4. For each colored castle flag set, there is a rook and a king on the corresponding initial squares.
  5. The pawn situation is consistent with the en-passant flag if it is set. For instance, if it is set to the "e" file and black is about to play, the squares e2 and e3 must be empty, and there must be a white pawn on e4.
Returns:
boolean

isMoveLegal(from, to) → {boolean|function}

Check whether a move is legal or not, and return the corresponding MoveDescriptor if it is legal.

Depending on the situation, the method returns:

  • false if it is not possible to move from from to to (either because the move itself is not legal, or because the underlying position is not legal).
  • a function that returns a MoveDescriptor otherwise. When there is only one possible move between the given squares from and to (i.e. in most cases), this function must be invoked with no argument. When there is a "move ambiguity" (i.e. squares from and to are not sufficient to fully describe a move), an argument must be passed to the this function in order to discriminate between the possible moves. A field status is added to the function in order to indicate whether there is a move ambiguity or not.

For castling moves, to is supposed to represent:

  • for regular chess, the destination square of the king (i.e. c1, g1, c8 or g8),
  • for Chess960, the origin square of the rook ("king-take-rook" pattern).

A code interpreting the result returned by Position#isMoveLegal would typically look like this:

var result = position.isMoveLegal(from, to);
if(!result) {
  // The move "from -> to" is not legal.
}
else {
  switch(result.status) {

    case 'regular':
      // The move "from -> to" is legal, and the corresponding move descriptor is `result()`.
      break;

    case 'promotion':
      // The move "from -> to" is legal, but it corresponds to a promotion,
      // so the promoted piece must be specified. The corresponding move descriptors
      // are `result('q')`, `result('r')`, `result('b')` and `result('n')`.
      break;

    default:
      // This case is not supposed to happen.
      break;
  }
}
Parameters:
Name Type Description
from Square
to Square
Returns:
boolean | function

isNullMoveLegal() → {boolean}

Determine whether a null-move (i.e. switching the player about to play) can be play in the current position.

A null-move is possible if the position is legal and if the current player about to play is not in check.

Returns:
boolean

isStalemate() → {boolean}

Return true if the player that is about to play is stalemated. If the position is not legal (see Position#isLegal), the returned value is always false.

For antichess, this method returns true if the player about to play has no remaining piece or pawn, or if non of his/her remaining piece can move. (same behavior as Position#isCheckmate for this variant).

For horde chess, this method returns true if black has been stalemated or if white cannot move but has still at least one piece.

Returns:
boolean

kingSquare(color) → {Square|boolean}

Return the square on which is located the king of the given color.

For non-standard variants, the behavior of this method depends on whether king has "royal power" in the current variant or not (i.e. whether it can be put in check or not). For instance:

  • in antichess, the king has no royal power, thus false is always returned,
  • in chess960, the king has royal power (as in the usual chess rules), thus the method does returns the square on which the king is located.
Parameters:
Name Type Description
color Color
Returns:
Square | boolean -

Square where is located the searched king. false is returned if there is no king of the given color, if the are 2 such kings or more, or if king has no "royal power".

moves() → {Array.<MoveDescriptor>}

Return the list of all legal moves in the current position. An empty list is returned if the position itself is not legal (see Position#isLegal).

Returns:
Array.<MoveDescriptor>

notation(moveDescriptor) → {string}

Return the standard algebraic notation corresponding to the given move descriptor.

Parameters:
Name Type Description
moveDescriptor MoveDescriptor
Returns:
string

notation(move, strictopt) → {MoveDescriptor}

Parse the given string as standard algebraic notation and return the corresponding move descriptor.

Parameters:
Name Type Attributes Default Description
move string
strict boolean <optional>
false

If true, only perfectly formatted SAN moves are accepted. If false, "small errors" in the input such as a missing capture character, an unnecessary disambiguation symbol... do not interrupt the parsing.

Throws:

If the move parsing fails or if the parsed move would correspond to an illegal move.

Type
module:exception.InvalidNotation
Returns:
MoveDescriptor

play(move) → {boolean}

Play the given move if it is legal.

WARNING: when a MoveDescriptor is passed to this method, this MoveDescriptor must have been issued by one of the Position#moves / Position#isMoveLegal / Position#notation methods of the current Position. Trying to invoke Position#play with a MoveDescriptor generated by another Position object would result in an undefined behavior.

Parameters:
Name Type Description
move string | MoveDescriptor
Returns:
boolean -

true if the move has been played, false if the move is not legal or if the string passed to the method cannot be interpreted as a valid SAN move notation (see Position#notation).

playNullMove() → {boolean}

Play a null-move on the current position if it is legal.

Returns:
boolean -

true if the move has actually been played, false otherwise.

reset()

Set the position to the starting state (in the regular chess variant).

reset960(scharnaglCode)

Set the position to one of the Chess960 starting position.

Parameters:
Name Type Description
scharnaglCode number

Must be between 0 and 959 inclusive (see https://chess960.net/start-positions/ or https://www.chessprogramming.org/Reinhard_Scharnagl for more details).

resetAntichess()

Set the position to the starting state of the antichess variant.

resetHorde()

Set the position to the starting state of the horde chess variant.

square(square) → {ColoredPiece|Empty}

Get the content of a square.

Parameters:
Name Type Description
square Square
Returns:
ColoredPiece | Empty

square(square, value)

Set the content of a square.

Parameters:
Name Type Description
square Square
value ColoredPiece | Empty

turn() → {Color}

Get the turn flag (i.e. who is about to play).

Returns:
Color

turn(value)

Set the turn flag (i.e. who is about to play).

Parameters:
Name Type Description
value Color

uci(moveDescriptor, forceKxRopt) → {string}

Return the UCI notation corresponding to the given move descriptor.

Examples of UCI notation: 'e2e4', 'b8c6', 'e7e8q' (promotion)... For more details, please refer to:

Parameters:
Name Type Attributes Default Description
moveDescriptor MoveDescriptor
forceKxR boolean <optional>
false

If true, castling moves are encoded as "king-take-rook", i.e. for instance white king-side castling will be 'e1h1' (instead of 'e1g1' in UCI standard). If false, castling move encoding follows the UCI standard for normal chess games (e.g. 'e1g1'). For Chess960 games, the "king-take-rook" style is always used, whatever the value of this flag.

Returns:
string

uci(move, strictopt) → {MoveDescriptor}

Parse the given string as UCI notation and return the corresponding move descriptor.

Parameters:
Name Type Attributes Default Description
move string
strict boolean <optional>
false

If true, "king-take-rook"-encoded castling moves (i.e. for instance 'e1h1' for white king-side castling) are rejected in case of normal chess games. If false, both "king-take-rook"-encoded and UCI-standard-encoded castling moves (e.g. 'e1g1') are accepted. For Chess960 games, only the "king-take-rook" style is accepted, whatever the value of this flag.

Throws:

If the move parsing fails or if the parsed move would correspond to an illegal move.

Type
module:exception.InvalidNotation
Returns:
MoveDescriptor

variant() → {GameVariant}

Get the GameVariant in use.

Returns:
GameVariant