Giter Site home page Giter Site logo

uci's Introduction

Ruby UCI - A Universal Chess Interface for Ruby

The UCI gem allows for a much more ruby-like way of communicating with chess engines that support the UCI protocol.

Installation

NOTE: No Chess engines are included. You must install an appropriate UCI-compatible engine first.

Standard installation applies. Either:

gem install uci

..or, in a bundled project, add this line to your application's Gemfile:

gem 'uci'

And then execute:

$ bundle

Example

 require 'uci'

  uci = Uci.new( :engine_path => '/usr/local/bin/stockfish' )

  while !uci.ready? do
    puts "Engine isn't ready yet, sleeping..."
    sleep(1)
  end

  # this loop will make the engine play against itself.
  loop do
    puts "Move ##{uci.moves.size+1}."
    puts uci.board # print ascii layout of current board.
    uci.go!
  end

Docs

::new(options = {})

make a new connection to a UCI engine

  Uci.new(
    :engine_path => '/path/to/executable',
    :debug => false, # true or false, default false
    :name => "Name of engine", # optional
    :movetime => 100, # max amount of time engine can "think" in ms - default 100
    :options => { "Navalov Cache" => true } # optional configuration for engine
  )

#bestmove()

Ask the chess engine what the “best move” is given the current state of the internal chess board. This does not actiually execute a move, it simply queries for and returns what the engine would consider to be the best option available.

#board(empty_square_char = '.')

ASCII-art representation of the current internal board.

  > puts board
    ABCDEFGH
  8 r.bqkbnr
  7 pppppppp
  6 n.......
  5 ........
  4 .P......
  3 ........
  2 P.PPPPPP
  1 RNBQKBNR

clear_position(position)

Clear a position on the board, regardless of occupied state

engine_name()

Return the current engine name

fenstring()

Return the state of the interal board in a FEN (Forsyth–Edwards Notation) string, SHORT format (no castling info, move, etc).

get_piece(position)

Get the details of a piece at the current position raises NoPieceAtPositionError if position is unoccupied. Returns array of [:piece, :player].

  > get_piece(“a2”)
  > [:pawn, :white]

go!()

Tell the engine what the current board layout it, get its best move AND execute that move on the current board.

move_piece(move_string)

Move a piece on the current interal board. Will raise NoPieceAtPositionError if source position is unoccupied. If destination is occipied, the occupying piece will be removed from the game.

move_string is algebraic standard notation of the chess move. Shorthand is not allowed.

  move_piece("a2a3") # Simple movement
  move_piece("e1g1") # Castling (king’s rook white)
  move_piece("a7a8q" # Pawn promomition (to Queen)

Note that there is minimal rule checking here, illegal moves will be executed.

new_game!()

Send “ucinewgame” to engine, reset interal board to standard starting layout.

new_game?()

True if no moves have been recorded yet.

piece_at?(position)

returns a boolean if a position is occupied

  > piece_at?(“a2”)
  > true
  > piece_at?(“a3”)
  > false

piece_name(p)

Returns the piece name OR the piece icon, depending on that was passes.

  > piece_name(:n)
  > :knight
  > piece_name(:queen)
  > “q”

place_piece(player, piece, position)

Place a piece on the board, regardless of occupied state.

  • player - symbol: :black or :white
  • piece - symbol: :pawn, :rook, etc
  • position - a2, etc
  place_piece(:black, :rook, "h1")

ready?()

True if engine is ready, false if not yet ready.

send_position_to_engine()

Write board position information to the UCI engine, either the starting position and move log or the current FEN string, depending on how the board was set up.

This does not tell the engine to execute a move.

set_board(fen)

Set the board using Forsyth–Edwards Notation (FEN), LONG format including current player, castling, etc.

  • fen - rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1 (Please see en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation)

Supported Engines

In theory it can support any UCI-compatible engine (except for conditions outlined in the 'caveats' section). It has been tested with:

  • Stockfish (Jan 11 2013 Github source)
  • Fruit 2.3.1 (Mac)

Caveats

No move checking

This gem assumes the engine knows what it's doing. If the gem wishes to place a illegal move it will be accepted.

Unix-style Line endings are assumed.

Current version assumes unix-style ("\n") line endings. That means running this under MS-DOS or Windows may barf.

Very limited command set.

Very few commands of the total UCI command set are currently supported. they are:

  • Starting a new game
  • Setting positions
  • Getting best move
  • Setting options

It DOES NOT yet support:

  • 'uci' command
  • ponder mode / infinite mode
  • ponderhit
  • registrations

Known Issues

When connecting to more than one engine from the same code, there is a problem where their input streams get crosses. This is an issue with Open3, but for some reason turning "debug" on seems to mitigate it.

Open3 is supposed to work under in Ruby 1.9.x in Windows, but this is currently untested.

Contributing

Ruby UCI needs support for more features and to be tested with more chess engines. To contribute to this project please fork the project and add/change any new code inside of a new branch:

git checkout -b my-new-feature

Before committing and pushing code, please make sure all existing tests pass and that all new code has tests. Once that is verified, please push the changes and create a new pull request.

uci's People

Contributors

bitdeli-chef avatar xunker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

uci's Issues

ruby -w -> warning

Reported by Michael A:

ruby -w -->
/var/lib/gems/1.9.1/gems/uci-0.0.2/lib/uci.rb:174: warning: method redefined; discarding old moves
/var/lib/gems/1.9.1/gems/uci-0.0.2/lib/uci.rb:247: warning: instance variable @fen not initialized

Problems with other engines or newer versions of stockfish

Reported by Michael A:

Hi,

I tried your gem and all works fine with Ubuntu 14.04, stockfish and movetime 100ms.

Some problems occour with other engines and even with stockfish:

Problem at startup:

  • Expected return to begin with 'bestmove', but got 'readyok' (ReturnStringError)
    Engines:
  • fruit 2.1.dfsg-6
  • gnuchess 6.1.1-1
  • toga2 3.0.0.1SE1-1

Problem at the end of a game:

  • Engine returned a 'bestmove' that I don't understand: bestmove (none) (UnknownBestmoveSyntax)
    Engines:
  • glaurung 2.2-2ubuntu1

Problem before the first move if more than 100 ms - e.g. 1000 ms:

  • Expected return to begin with 'bestmove', but got 'info depth 14 seldepth 18 score cp 28 nodes 505809 nps 2634421 time 192 multipv 1 pv g1f3 g8f6 > d2d4 d7d5 e2e3 e7e6 f1d3 f8d6 e1g1 b8c6 c2c4 c6b4 c4c5 b4d3 d1d3'
    Engines:
  • stockfish 3.0.0+git20130508-2

So it is not usable :-( for me. I think my experience is not good enough to fix your gem.
I am fighting hard to use the gem's and have no knowledge in the UCI-protocoll.
Could you help me please?

I am very interested in using your gem. I develop a chess program for a blind person.

Kind regards,
Michael

Method to get position score information from engine info string

Thanks for this great library!

I'm looking to use it to automate the evaluation of a series of board positions. This means I need access to the engine's info output. According to the protocol the engine is supposed to send an info command that includes a score for the position with a series of different attributes. This is what I want. I noticed that in read_from_engine() you explicitly skip info strings. Why? Is it just to avoid their verbosity?

I also noticed that the protocol provides no way for the client to specifically request info for the current board position from the engine. Am I missing something there?

Is there a simple way to add that feature without having to add a persistent info log? What would be the best approach that you'd recommend?

Setting fenstring doesn't update internal board representation

It looks like the set_board function sets @board https://github.com/xunker/uci/blob/master/lib/uci.rb#L275 but I'm not seeing the result after having sent in a fenstring

require 'uci'
uci = Uci.new( :engine_path => '/usr/local/bin/stockfish')
uci.ready?
uci.set_board "5k2/5pb1/1pp2qp1/p1nr3p/5P2/1P2P1R1/P3NP1P/1B4QK w - - 1 20"
uci.board
 => "  ABCDEFGH\n8 rnbqkbnr\n7 pppppppp\n6 ........\n5 ........\n4 ........\n3 ........\n2 PPPPPPPP\n1 RNBQKBNR\n"

For references, that board should look like this:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.