Skip to content


Repository files navigation

Carballo Chess Engine


Carballo (the galician word for Oak, it's all about search trees) is an Open Source Java chess engine with three interfaces:

It is organized into modules:

  • Core: the chess engine
  • Jse: the Java Standard Edition version with the UCI interface and JUnit tests
  • Gwt: components needed for the GWT GUI
  • GwtGui: an HTML5 interface developed by Lukas Laag, it depends on Core and Gwt
  • Swing: the swing application code, it depends on Core and Jse

It is licensed under GPLv3 and the source code is hosted at You are free to use, distribute or modify the code, we ask for a mention to the original authors and/or a link to our pages.


  • UCI interface for chess GUIs like Arena or SCID
  • It includes a great GWT interface by Lukas Laag and a Java Swing GUI
  • Based on bitboards with a magic bitboard move generator, it also includes code for magic number generation
  • Move iterator sorting moves with four killer move slots, Static Exchange Evaluation (SEE), Most Valuable Victim/Least Valuable Aggressor (MVV/LVA) and history heuristic
  • PVS searcher
  • Aspiration window, moves only one border of the window if it falls out
  • Transposition Table (TT) with zobrist keys (it uses two zobrist keys per board to avoid collisions) and multiprobe
  • Quiescent Search (QS) with only good or equal captures (according to SEE) and limited check generation
  • Internal Iterative Deepening to improve sorting
  • Extensions: Check (only with positive SEE), pawn push, mate threat and singular move
  • Reductions: Late Move Reductions (LMR)
  • Pruning: Null move pruning, static null move pruning, futility pruning and history pruning
  • Pluggable evaluator function, distinct functions provided: the Simplified Evaluator Function, other Complete and other Experimental
  • Selectable ELO level with an UCI parameter
  • Supports Chess960
  • Polyglot opening book support; in the code it includes Fruit's Small Book
  • FEN notation import/export support, also EPD support for testing
  • JUnit used for testing, multiple test suites provided (Perft, BS2830, BT2630, LCTII, WinAtChess, etc.)

Test results in a Intel Xeon CPU limited to 2.0GHz for consistency:

Test suite Time per position Version 1.8 Version 1.7
WinAtChess (New) 1 second 293/300 293/300
SilentButDeadly 1 second 125/134 125/134
ECMGCP 1 second 113/183 112/183
ECMGCP 5 seconds 156/183 154/183
Arasan 19a 60 seconds 52/200 52/200

His real strength is about 2400 ELO points, you can check his tournament rankings at



Carballo uses the Gradle build system and the gradle wrapper.

Build all the jars and install them to your local Maven repository:

./gradlew publishToMavenLocal

UCI Interface

Build the UCI interface (creates a carballo-${version}.jar in jse/):

cd jse
../gradlew proguard

Running the UCI interface:

cd jse
java -jar carballo-1.8.jar

HTML5 Interface

Build the GWT interface:

cd gwtgui
../gradlew compileGwt

Running the GWT interface:

cd gwtgui
../gradlew appRun

and access with your web browser to http://localhost:8080/chess/

Desktop Interface

Building the Swing interface (creates a carballo-swing-${version}.jar in swing/):

cd swing
../gradlew proguard

Running the Swing interface:

cd swing
java -jar carballo-swing-1.8.jar


Run tests:

./gradlew test

Run the "Win at Chess" test suite:

cd jse
../gradlew slowTest --tests=WinAtChessTest

Run the "Silent but Deadly" suite:

cd jse
../gradlew slowTest --tests=SilentButDeadlyTest


Version 1.8: Java 11, new desktop application and source code improvements

  • Change the source code level to Java 11
  • Use JitPack for publishing the artifacts
  • Changed artifact group to com.github.albertoruibal.carballo
  • Use the gradle wrapper 7.5.1
  • Update the tests to JUnit 5.9.1
  • HTML5 app updated to GWT 2.10
  • Converted the old Applet to a Swing application
  • Implemented the standard "UCI_LimitStrength" and "UCI_Elo" UCI options instead of the old "Elo" option
  • Implemented "searchmoves" and "go depth" in the UCI interface
  • UCI Interface: Now "isready" may be called after "position"
  • Add pawn blockade also to the CompleteEvaluator
  • More small bug fixes

Version 1.7: A new Late Move Reductions (LMR) formula

  • New LMR formula with a progressive reduction based on the node eval diff and the move history
  • Reduce the LMR tables size saving memory
  • Do history pruning before LMR
  • Prune moves with negative SSEs taking reductions into account
  • Penalty for pawns in [D,E] in the initial square blocked by our own pieces
  • Remove the pawn push extension
  • A new PGN parser supporting variations, comments, NAGs, etc.

Version 1.6: Refactoring, bug fixes, endgames, etc.

  • Set the CompleteEvaluator as the new default evaluator
  • Add history pruning
  • Make the singular move margin depth dependent
  • Don't do razoring in positions with known wins
  • Add pawn push extension
  • Fixes in the Opening-Endgame values to two-shorts-in-one-int logic that allows to separate the piece values from the square tables
  • Add logic to detect draws in KQKQ, KRKR, KRPKR, KQKP, KBPKB, KBPKN and KRPPKP endgames
  • Reduce the pawn value in the opening
  • Add space evaluation
  • Add rook trapped logic and improve bishop trapped evaluating pawn guard
  • Change passer pawn logic adding a king distance bonus, remove unstoppable passer logic
  • Improve the king shield and pawn storm logic
  • Do not eval only forward mobility in bishops and knights
  • Scale the contempt factor to 0 in the endgame
  • Fix a bug returning from the excluded search for the singular move extension
  • Add KBKB draw recognition (with same color bishops)
  • Start to scale from midgame to endgame with 6 minor pieces (previously it was with 4 pieces)
  • Fix some concurrence problems adding thread locks in the SearchEngine and SearchEngineThreaded class
  • Fix seldepth reporting in the UCI interface (sometimes seldepth was lower than depth): if a TT move is returned, add the depth analyzed in the TT

Version 1.5: More search and evaluation tuning

  • Prune non capture moves with SEE < 0 when depthRemaining < 3
  • Change the outside passer detection, now only if the pawn is in the files a, b, c or f, g, h and there are opposite pawns
  • Increase the passer pawn bonuses to match the "Two connected passers on 6th are better than a rook"
  • Increase the attack bonuses
  • Revise the absolute/relative pin logic, adding the bonus one time by each pinned piece
  • Increase the bishop trapped penalty
  • Increase the pawn center bonuses in the opening
  • Fix a bug in the pawnCanAttack bitboards
  • Added GNU's Octave scripts to generate the mobility/attack/passer bonuses and the Piece-Square tables under scripts/octave
  • Added a GCJ compilation script to generate native binaries for Linux

Version 1.4: Another step in the engine strength

  • Better understanding of pinned pieces, generating attacks only from legal moves
  • New logarithmic piece mobility bonuses
  • New set of pawn bonuses and changes in passer pawn evaluation adding an unstoppable passer bonus
  • Remove evaluator section Config & UCI parameters speeding up things
  • Changes in king safety evaluation taking into account three more squares in front of the king and modifying bonuses
  • Improve pawn shield logic and add pawn storm evaluation
  • Avoid negative values in the Opening-Endgame (O-E) arithmetic
  • Make the bishop pair and the tempo bonuses O-E
  • Reduce the tempo bonus in the endgame
  • Merge piece values in the piece-square tables
  • Simplify the rook on 5th, 6th, 7th rank logic replacing it by a bonus for each pawn attacked by the rook
  • Remove the queen on 7th rank logic
  • Use the PV value in the TT as the search starting score in each depth iteration
  • Change time management to use more time
  • New futility and razoring margins by depthRemaining, extend futility to more PLYs
  • In quiescence search (QS), do futility also for PV nodes and generate checks at depth 0 also for non-PV nodes
  • As fractional extensions are no longer used, now PLY is 1
  • Use unicode figurines in the text board and in the GWT Gui SAN notation
  • Fix engine crash analyzing positions already mate

Version 1.3: A lot of work in the evaluation function for a better positional play

  • Now AttacksInfo holds the attacks information by piece type
  • This allows to improve mobility and king safety evaluation detecting squares attacked by less valuable pieces
  • Removed the king defense bonuses from the Experimental evaluator
  • New MOBILITY array holding mobility bonuses by piece type and number of destiny squares
  • Simplified the Bishop's Capablanca rule
  • Removed some rook in 7th rank logic
  • Improved the pawnCanAttack squares detection removing squares that cannot be reached due to opposite pawns
  • Fixed the unsupported pawn penalty
  • Modify the "rook attacks backward pawn logic" to detect real backward pawns
  • Evaluation refactoring using the "W" and "B" constants and the "us" and "them" variables
  • The Attacks evaluation is now done in a separated evalAttacks() method, unifying the attack bonuses in the PAWN_ATTACKS, MINOR_ATTACKS and MAJOR_ATTACKS arrays
  • Piece value constants moved to the Config class and removed the PIECE_VALUES array
  • Better midgame-to-endgame evaluation scaling with the new NON_PAWN_MATERIAL_MIDGAME_MAX and NON_PAWN_MATERIAL_ENDGAME_MIN constants
  • Remove some UCI parameters and change them by constants for a better running optimization

Version 1.2: A new MoveIterator, Chess960 and lots of UCI improvements

  • New MoveIterator that generates only legal moves with a check flag set
  • Added support for Chess960 (Fischer Random Chess)
  • Implemented UCI Ponder
  • New replace strategy for the TT, taking into account the entry depth and the generation difference
  • In the TT in QS, store the entries with checks generated with depth 1 and entries without checks with depth 0
  • Four killer move slots
  • Set default razoring margin to 400
  • Fix the futility in QS and set the default futility in QS to 80
  • Remove the null move margin and improve the null move reduction calculation
  • Remove the recapture extension
  • New time management strategy adding a "panic time" when the search in the root node fails low by a margin of 100
  • Do not penalize pinned pawns in the evaluators, multiply the hung pieces bonus by the number of hung pieces, and pawn center opening corrections
  • Fixed a bug multiplying the opening/ending values in the evaluators by negative factors
  • Generate piece-square values in different classes
  • Fixed an important bug in the SWAP algorithm for the SSE evaluation
  • Now it uses 1" for the WinAtChess tests

Version 1.1: Urgent bug fix for 1.0

  • The UCI interface was ignoring all the UCI options
  • Do not allocate memory inside ExperimentalEvaluator.evaluate()
  • Added the new pawn and endgame logic to the CompleteEvaluator (ExperimentalEvaluator continues as the default)

Version 1.0: Lots of fixes, small advances in test results: 294 in WAC (5") and 2520 in BT2630.

  • New Transposition Table with a separated slot for the eval values
  • Now uses the TT in quiescence search
  • Fix mate values before inserting them in the TT, now the mate problems are solved with the right distance to the mate
  • Fixes to futility pruning in quiescence search
  • New pawn classification in the ExperimentalEvaluator
  • Now the PV line is shown every time that a move is found in the root node
  • Implemented UCI seldepth, lowerbound, upperbound and hashfull
  • Implemented the depth and node limit for the search
  • Enabled the endgame knowledge
  • In the search, assume that pawn pushes are to the 6th, 7th or 8th rank
  • Extend only checks with positive SSE
  • Disable by default the recapture and pawn extensions, set the mate threat extension to one full PLY
  • Fix recapture extension (now disabled by default)
  • Tests migrated to the JUnit 4 format with annotations, and created a "fastTest" gradle task to run only the fast tests
  • C# code separated in another GitHub project

Version 0.9: Fixes evaluator bugs

  • Reordered some logic in the ExperimentalEvaluator
  • Fixed a bug in the detection of the 2 bishop bonus
  • Fixed another bug in the detection of candidate passer pawns
  • Bug in the detection of the adjacent columns found by Yonathan Maalo
  • Some improvements in the HTML5 interface

Version 0.8: Build system and GWT modifications

  • Project build system migrated from Maven to Gradle
  • Solved some evaluator bugs
  • New option to do not use Magic Bitboard Attacks: optimizes start time in HTML5
  • Removed specific Bitboard attacks code from GWT, can be simulated setting BitboardAttacks.USE_MAGIC = false
  • New ArrayBufferBook for GWT, it can process any opening book loaded as a JS ArrayBuffer

Version 0.7: A small leap on the engine performance and a big code clean

  • Code moved to Github
  • Integrated ROOT, PV and NULL nodes search routine
  • Activated singular movement extensions and changed default singular extension margin
  • Do null move only when the remaining depth is > 3 PLY
  • No not overwrite the value in the TT if there is no room
  • Converted code to C# using sharpen. At the moment only the core of the engine
  • Solved a big bug getting the move from the transposition table
  • Also found another bug on the search getting the last captured piece value
  • And the complete evaluator had a bug calculating the attacks value

Version 0.6: Source code reorganization, GWT and PGN improvements, no changes on the engine code

  • Code splitted in carballo-core, carballo-jse and carballo-applet
  • Carballo-core is GWT-friendly
  • Integrated SAN notation on Board class
  • Improved PGN export with SAN notation
  • Added a GWT interface based on the one by Lukas Laag ( code

Version 0.5: Improves about 150 ELO points over Carballo 0.4

  • PVS searcher: SearchEngine completely changed
  • Futility pruning now works!
  • New TT algorithm, now also uses TT to store evaluation values
  • Bug with draw detection with 3-fold repetition
  • Bug with time management on tournament, was using the opponent's time amount
  • Bug with history table overflow

Version 0.4: First version integrated with Mobialia Chess

  • Parameterizable evaluator
  • Evaluator changes


Carballo Chess Engine