Skip to content

Commit

Permalink
Initial GIT conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
albertoruibal committed Jun 1, 2012
0 parents commit a77b658
Show file tree
Hide file tree
Showing 274 changed files with 127,911 additions and 0 deletions.
94 changes: 94 additions & 0 deletions README
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,94 @@

Description
===========

Carballo (the galician word for Oak, well it's all about search trees) is an Open Source Java and C# chess engine hosted at <a href="http://sourceforge.net/projects/carballo/">http://sourceforge.net/projects/carballo/</a>, where you can download a UCI binary to play in interfaces like <a href="http://www.playwitharena.com">Arena</a>. Has the following features:

* Simple and clear code
* Cute drag and drop Java Applet GUI, to fit in web sites
* Includes also a great GWT interface by Lukas Laag
* Maven source code organization
* JUnit used for testing, multiple test suites provided (Perft, BT2630, LCTII, WAC, etc.)
* Based on Bitboards (not so complicated as other people say)
* State-of-the-art magic bitboard move generator (doubles the basic move generator speed!), also code for magic number generation
* PVS searcher
* Iterative deepening
* Aspiration window, moves only one border of the window if falls out
* Transposition Table (TT) with Zobrist Keys (two zobrist keys per board, to avoid collisions) and multiprobe/two tier
* Quiescent search with only good captures (according to SEE) and limited check generation
* Move sorting: two killer move slots, SEE, MVV/LVA and history heuristic
* Also Internal Iterative Deepening to improve sorting
* Fractional Extensions: check, pawn push and passed pawns, mate threat, recapture (2 = 1PLY)
* Reductions: Late Move Reductions (LMR)
* Pruning: Null Move Pruning, Static Null Move Pruning, Futility Pruning and Aggressive Futility Pruning
* Polyglot Opening Book support; in the code I include Fruit's Small Book
* FEN notation import/export support, also EPD support for testing
* Pluggable evaluator function, distinct functions provided: the Simplified Evaluator Function, other Complete and other Experimental
* Parametrizable evaluator (only for the complete &amp; experimental evaluators)
* Contempt factor
* UCI interface with lots of UCI options
* The core of the chess engine was converted to C# using Sharpen

It scores 2415 ELO points at BT2630 tests in my Core2 Duo@2.2GHz. Also solves 280 positions of the 300 WinAtChess test (5 seconds for each). His real strength is about 2100 ELO points.

It is licensed under GPLv3, and you are free to use, distribute or modify the code but I ask for a mention to the original author and/or a link to my blog.

Test Results
============

I made a Java Engines Tournament to compare Carballo against other chess engines at tournament time 5 minutes. Here are the results:

<pre> Engine Score Ol Fr Me Al Ca Cu Br Ar Ch Fr JC S-B
Engine Score Cu Ca Ol Me Ca Fr Br Ar S-B
1: Cuckoo-1.12 34,5/35 ····· 1=111 11111 11111 11111 11111 11111 11111 515,75
2: Carballo-0.7.11 23,5/35 0=000 ····· 110=0 11111 10101 1111= 01101 11111 318,00
3: OliThink-5.3.2 22,5/35 00000 001=1 ····· 00110 11101 11011 11111 11111 274,75
4: Mediocre-0.3.4 17,5/35 00000 00000 11001 ····· 11001 01011 11=11 11101 210,50
5: Carballo-0.5 15,0/35 00000 01010 00010 00110 ····· =1100 010=1 11111 184,50
6: FrankWalter-1.0.8 14,0/35 00000 0000= 00100 10100 =0011 ····· 11011 10111 158,75
7: Bremboce-0.6.2 8,0/35 00000 10010 00000 00=00 101=0 00100 ····· 00011 117,25
8: ArabianKnight-1.0.9 5,0/35 00000 00000 00000 00010 00000 01000 11100 ····· 55,50

140 games played / Tournament is finished
Name of the tournament: JavaEnginesTournament
Site/ Country: JDEDEVELOPER5, España
Level: Tournament Game in 5 Minutes
Hardware: Intel(R) Core(TM)2 Duo CPU T7500 @ 2.20GHz 2200 MHz with 752 MB Memory
Operating system: Microsoft Windows XP Professional Service Pack 2 (Build 2600)
</pre>

History
=======

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

* 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 (http://vectomatic.org) 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

* Parametrizable evaluator
* Evaluator changes
176 changes: 176 additions & 0 deletions applet/src/main/java/com/alonsoruibal/chess/applet/BoardJPanel.java
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,176 @@
package com.alonsoruibal.chess.applet;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JLayeredPane;
import javax.swing.JPanel;


public class BoardJPanel extends JPanel implements MouseListener, MouseMotionListener
{
private static final long serialVersionUID = 1L;

JLayeredPane layeredPane;
JPanel chessBoard;
PieceJLabel chessPiece;
int xAdjustment;
int yAdjustment;
final int height = 75*8;
final int width = 75*8;
SquareJPanel originComponent;
ChessApplet chess;
String lastFen;
boolean flip;

private boolean acceptInput;

public void setAcceptInput(boolean acceptInput) {
this.acceptInput = acceptInput;
}

public BoardJPanel(ChessApplet chess)
{
Dimension d = new Dimension(width, height);

layeredPane = new JLayeredPane();
add(layeredPane);
layeredPane.setPreferredSize( d );
layeredPane.addMouseListener( this );
layeredPane.addMouseMotionListener( this );

chessBoard = new JPanel();
layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER);
chessBoard.setLayout( new GridLayout(8, 8) );
chessBoard.setPreferredSize(d);

for (int i = 0; i < 64; i++) chessBoard.add(new SquareJPanel(i));

chessBoard.setBounds(0, 0, width, height);
layeredPane.setBounds(0, 0, width, height);
setBounds(0, 0, width, height);

acceptInput = true;
this.chess = chess;
}

/**
* Add the selected chess piece to the drag and drop layer
*/
public void mousePressed(MouseEvent e)
{
if (!acceptInput) return;
chessPiece = null;
Component c = chessBoard.findComponentAt(e.getX(), e.getY());

if (c instanceof SquareJPanel) return;
originComponent = (SquareJPanel) c.getParent();

// TODO set legal moves

Point parentLocation = c.getParent().getLocation();
xAdjustment = parentLocation.x - e.getX();
yAdjustment = parentLocation.y - e.getY();
chessPiece = (PieceJLabel) c;
chessPiece.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment);
chessPiece.setSize(chessPiece.getWidth(), chessPiece.getHeight());
layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER);
}

/**
* Move the piece
*/
public void mouseDragged(MouseEvent me)
{
if (!acceptInput) return;
if (chessPiece == null) return;
chessPiece.setLocation(me.getX() + xAdjustment, me.getY() + yAdjustment);
}

/*
** Drop the piece back
*/
public void mouseReleased(MouseEvent e)
{
if (!acceptInput) return;
// Only if inside board
if (chessPiece == null) return;

chessPiece.setVisible(false);
Component c = chessBoard.findComponentAt(e.getX(), e.getY());
if (c == null) c = originComponent;

SquareJPanel parent;
if (c instanceof PieceJLabel) {
parent = (SquareJPanel) c.getParent();
parent.remove(0);
parent.add( chessPiece );
} else {
parent = (SquareJPanel) c;
parent.add( chessPiece );
}
chessPiece.setVisible(true);

// notifies move
chess.userMove(flip ? originComponent.getIndex() : 63-originComponent.getIndex(), flip ? parent.getIndex() : 63-parent.getIndex());
}

public void mouseClicked(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}

public void setFen(String fen, boolean flip, boolean redraw) {
if (fen == null) return;
this.flip = flip;
lastFen = fen;
int i = 0;
int j = 0;
while (i < fen.length()) {
char p = fen.charAt(i++);
if (p != '/') {
int number = 0;
try {
number = Integer.parseInt(String.valueOf(p));
} catch (Exception e) {}

for (int k = 0; k < (number == 0 ? 1 : number); k++) {
SquareJPanel panel = (SquareJPanel) chessBoard.getComponent(flip ? 63 - j++ : j++);
try {
PieceJLabel label = (PieceJLabel) panel.getComponent(0);
if (label.getPiece() != p || redraw) {
label.setVisible(false);
panel.remove(0);
throw new Exception();
}
} catch (Exception e) {
if (number == 0) panel.add(new PieceJLabel(p));
}
if (j>=64) {
return; // security
}
}
}
}
}

public void unhighlight() {
for (int i = 0; i< 64; i++) ((SquareJPanel) chessBoard.getComponent(i)).setHighlighted(false);
}

public void highlight(int from, int to) {
SquareJPanel squareFrom = (SquareJPanel) chessBoard.getComponent(flip ? from : 63 - from);
SquareJPanel squareTo = (SquareJPanel) chessBoard.getComponent(flip ? to : 63 - to);
squareFrom.setHighlighted(true);
squareTo.setHighlighted(true);
}

public String getLastFen() {
return lastFen;
}
}
Loading

0 comments on commit a77b658

Please sign in to comment.