Skip to content

New Variant Cheat Sheet

RainRat edited this page Apr 28, 2024 · 1 revision
  1. For most variants, you will only have to add a new entry to variants.ini
  2. Check to see if the options to create your variant already exist.
    • For rule variants, see variants.ini -> "Rule definition options"
    • For custom pieces, see variants.ini -> "Custom pieces"
  3. Most variants are added to variants.ini, but some are added to variant.cpp
  4. If your game rules aren't supported:
    1. Break it down into what changes will be required. For instance, "Connect 4" can be broken down into settings such as:

       enclosingDrop = top
       connectN = 4
      

      rather than

       playConnect4 = true
      
    2. In variant.h -> "struct Variant", add a variable for each new setting

    3. In parser.cpp -> "parse(Variant* v)", add "parse_attribute" to read from variants.ini into the variable.

    4. In position.h, most settings have a getter with a snake_case name which reads the camelCase variable. Remember to declare the getter under "class Position".

    5. If your rule changes how moves occur, see:

      1. movegen.cpp->“make_move_and_gating(const Position& pos, ExtMove* moveList, Color us, Square from, Square to, PieceType pt = NO_PIECE_TYPE)”
      2. position.cpp -> "do_move(Move m, StateInfo& newSt, bool givesCheck)"
      3. position.cpp->”legal(Move m)”
      4. position.cpp->”pseudo_legal(const Move m)”
      5. position.cpp->”undo_move(Move m)”
    6. If your rule includes a new Betza modifier, piece.cpp->”from_betza(const std::string& betza, const std::string& name)”

    7. If your rule adjudicates win, loss, or draw, see position.cpp -> "is_immediate_game_end(Value& result, int ply)" or "is_optional_game_end(Value& result, int ply, int countStarted)"

    8. See https://github.com/fairy-stockfish/Fairy-Stockfish/wiki/Understanding-the-code for more descriptions.

  5. Other functions:
    1. “movegen.cpp->generate_all” calls “movegen.cpp->generate_drops”, “movegen.cpp->generate_moves”, and “movegen.cpp->generate_pawn_moves”.
    2. “movegen.cpp->make_move_and_gating” is called by the above to encode and store the moves they generate in moveList
    3. “position.cpp->pseudo_legal” checks basic validity “position.cpp->legal” does a more extensive check, like making sure you aren’t hanging your king.
    4. “position.cpp->do_move” performs the actual change of board state, while “position.cpp->undo_move” reverses it.
  6. Testing your variant
    1. Compile using “make”. Type “make help” to see important options.

      1. “largeboards=yes” if your board is greater than 8x8. Boards greater than 10x12 are not supported.
      2. “all=yes” if your variant has a large branching factor such as “Duck Chess” or “Game of the Amazons”
      3. “debug=yes” and “optimize=no” if you’re troubleshooting
    2. You can use a GUI (see docs for your GUI if so), or run the executable directly. Useful options:

      1. “setoption name VariantPath value variants.ini”
      2. “setoption name UCI_Variant value [your_variant]”
    3. To play moves, start with “position”, either “startpos” or “fen” then use coordinates to play your moves. ie.

      1. “position startpos moves e2e4 e7e5”
      2. “position fen 4k3/8/8/8/8/8/p7/4K2R w K - 0 1 moves e1g1 a2a1q”
      3. Castling is encoded as “king moves two spaces”
      4. Promotion piece is indicated with just letter (no “=”)
      5. Drops are encoded with “@”. For instance, tictactoe looks like: position startpos moves P@b2 P@a1 P@c1
      6. “d” (prints current board using text characters)
      7. “go movetime [milliseconds]”
      8. “go depth [ply]”
      9. “quit”
    4. If you want to automate your testing, you can use redirection from the command line: Create test.txt:

       position startpos moves e2e4 d7d5
       go movetime 100
       d
       quit
      

      Run stockfish:

       stockfish < test.txt > output.txt