Finvara
Finvara is a stack-based esolang inspired by fairy chess. Each program is made of 3 parts: defining the pieces, defining the board, and listing the moves.
Everything following a #
is a comment going to the end of the line.
Piece definitions and notation
The piece definition is a list of all pieces used in the program (and others if you want). Every definition is in the following form:
(<piece symbol> <point value>): <notation>
The point value can be excluded, making that piece royal. Royal pieces must follow check rules (like a chess king), and if any player has no royal pieces or all royal pieces in check, they lose. The value can also be x
or y
(explained in Board definition.)
Notation is made up of the following:
(a,b)
: Make an a*b jump (ex. knight =(1,2)
)(a,b|>)
means that it can only jump to the right (^ = up, < = left, v = down)
{A,B,C...}
: The piece can move like A or B or C etc.c(A)
: Only do A as a capturing movem(A)
: Only do A as a non-capturing mover(A,b)
: Only do A on rank br!(A,b)
: Only do A not on rank b- If b is
[x,y]
, all ranks from x to y (inclusive) are used - Negative numbers can be used for ranks starting from the other side (-1 = other player's 1st rank, -2 = other player's 2nd rank, etc.)
- If b is
x
: Capture current piece (used if movement occurs after capture)A*
: Repeat A any number of times (jumps must stay moving in the same direction)A`
: Same asA*
, but jumps can change directionp
: Promote (turn into any other piece)->[a,b,c...]
: Can only promote into a, b, c, etc.
"x"
: Move like x (x can be any previously defined piece)
[Square brackets] can be used to group multiple actions together.
Examples for standard chess pieces:
(p 1): {c((1,1|^)),m((1,0|^)),r((2,0|^),2),r(p,-1)} #pawn (not including en passant because the notation can't factor in other turns) (n 3): (1,2) #knight (b 3): (1,1)* #bishop (r 5): (1,0)* #rook (q 9): {"r","b"} #queen (rook+bishop) (k): {(1,0),(1,1)} #king
Some non-standard chess pieces:
(h 7): {(1,0),(2,2)}r(->[q],[9,12]) #pheonix from shogi (g 5): {(1,1|^)(1,0|^)*,(1,1|>)(1,0|>)*,(1,1|v)(1,0|v)*,(1,1|<)(1,0|<)*} #gryphon from grande acedrex
Board definition
+--+--+--+--+--+--+--+--+ |rB|nB|bB|qB|kB|bB|nB|rB| +--+--+--+--+--+--+--+--+ |pB|pB|pB|pB|pB|pB|pB|pB| +--+--+--+--+--+--+--+--+ | | | | | | | | | +--+--+--+--+--+--+--+--+ | | |##|##|##|##| | | +--+--+--+--+--+--+--+--+ | | |##|##|##|##| | | +--+--+--+--+--+--+--+--+ | | | | | | | | | +--+--+--+--+--+--+--+--+ |pW|pW|pW|pW|pW|pW|pW|pW| +--+--+--+--+--+--+--+--+ |rW|nW|bW|qW|kW|bW|nW|rW| +--+--+--+--+--+--+--+--+
The above is a definition for a standard chess board, except that the middle 2 ranks have holes in them (marked with ##
.) Each space is either empty, a hole, or a piece symbol followed by its color (B
or W
.) The board can be any size, but must stay a rectangle. The bottom-left space is labelled a1, with the letter increasing going up and the number increasing going left. If there are more than 26 ranks, double letters are used (i.e. x1, y1, z1, aa1, ab1, ac1, etc.)
Movements
Each player (Black and White) has a corresponding stack which starts empty.
There are 2 types of moves:
Turn <turn number> <color>: <piece symbol> <starting space> -> <ending space>
If the move is valid and non-capturing, just move the piece.
If the move is valid and moves into or through a hole, remove the piece, take the value mod 6, and perform the corresponding action on the same color stack as the piece that was moved.
0: Pop A and B, push A+B 1: Pop A and B, push A-B 2: Pop A and B, push A = B (boolean value) 3: Push input to stack 4: Print top of stack 5: Pop top of stack
If the move is valid and captures another piece, push the value of the captured piece to the captured piece's color stack. If the value = x or y, push the piece's x or y coordinate (ex. d3 = (3,4)).
If the move is invalid, skip the next turn if the top of both stacks aren't 0 (or empty)
Turn <turn number> <color>: <piece symbol> <space> checks turn <turn number to jump to>
If <space>
is empty, place <piece symbol>
on that space, then jump to turn <turn number to jump to>
(jump even if no piece is placed).
Every turn is made of 2 moves, alternating between colors, like:
Turn 1 W: #move Turn 1 B: #move Turn 2 W: #move Turn 2 B: #move ...
Example Program
Truth-machine:
(k): (n 0): (0,0) (q 0): (1,0) (i 3): (1,0) (p 4): (1,0) +--+--+--+--+ |kB|##|qB|nB| +--+--+--+--+ |##|##| | | +--+--+--+--+ |iW|pW| |kW| +--+--+--+--+ Turn 1 W: i a1 -> b1 Turn 1 B: k c1 -> c2 Turn 2 W: p a2 -> b2 Turn 2 B: q c3 -> b3 Turn 3 W: p a2 -> b2 Turn 3 B: n c4 -> c4 Turn 4 W: p a2 checks turn 3 Turn 4 B: n c4 -> c4