Skip to content

Commit

Permalink
New thoroughly cleaned up version
Browse files Browse the repository at this point in the history
  • Loading branch information
imor committed Jun 6, 2014
1 parent 1bd2756 commit 86519ae
Show file tree
Hide file tree
Showing 21 changed files with 415 additions and 1,213 deletions.
4 changes: 2 additions & 2 deletions Gruntfile.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = function(grunt) {
options: { options: {
node: true node: true
}, },
all: ['*.js', 'lib/*.js', 'examples/*.js', 'test/*.js'] all: ['*.js', 'src/*.js', 'examples/*.js', 'test/*.js']
}, },
cafemocha: { cafemocha: {
testThis: { testThis: {
Expand All @@ -19,7 +19,7 @@ module.exports = function(grunt) {
}, },
groc: { groc: {
javascript: [ javascript: [
"lib/*.js" "src/*.js"
], ],
options: { options: {
"out": "docs/", "out": "docs/",
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Original file line Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)


Copyright (c) 2013 Raminder Singh Copyright (c) 2014 Raminder Singh


Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
Expand Down
183 changes: 34 additions & 149 deletions README.md
Original file line number Original file line Diff line number Diff line change
@@ -1,16 +1,11 @@
UCI UCI
=== ===


NOTE:This version is not backwards compatible with 0.1.x series of releases. This was kind of expected as this module is still very young. NOTE:This version is not backwards compatible with 0.2.x series of releases.


UCI is a thin wrapper on a [uci UCI is a thin wrapper on a [uci
interface](http://en.wikipedia.org/wiki/Universal_Chess_Interface) chess engine. interface](http://en.wikipedia.org/wiki/Universal_Chess_Interface) chess engine.
It also runs a chess clock and a [chess.js](https://github.com/jhlywa/chess.js)
instance internally so that the user can quickly play a game of chess with time
controls. Currently only [stockfish](http://stockfishchess.org/) is bundled with
UCI but other engines can be used as well. See installing engines section below
for how to do that. UCI also supports polyglot books. See installing books
section for that.


## Installation ## Installation
Make sure you have [node.js](http://nodejs.org/) installed. Then do: Make sure you have [node.js](http://nodejs.org/) installed. Then do:
Expand All @@ -19,157 +14,47 @@ Make sure you have [node.js](http://nodejs.org/) installed. Then do:


## Example ## Example
```js ```js
'use strict'; var Engine = require('uci');

var engine = new Engine('<path to engine executable>');
var UciEngine = require('uci'); engine.runProcess().then(function () {
var uci = new UciEngine(); console.log('Started');
var os = require('os'); return engine.uciCommand();
var Chess = require('chess.js').Chess; }).then(function (idAndOptions) {
var game = new Chess(); console.log('Engine name - ' + idAndOptions.id.name);

return engine.isReadyCommand();
console.log('Type exit or quit to exit.'); }).then(function () {
uci.on('Ready', function () { console.log('Ready');
var availableEngines = uci.getAvailableEngines(); return engine.uciNewGameCommand();
for (var i = 0;i < availableEngines.length;i++) { }).then(function () {
var currentEngine = availableEngines[i]; console.log('New game started');
currentEngine.setOption('Skill Level', 1); return engine.positionCommand('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1');
uci.startNewGame(currentEngine, 'black', 10, uci.getAvailableBooks()[0]); }).then(function () {
break; console.log('Starting position set');
} return engine.goInfiniteCommand(function infoHandler(info) {
}).on('NewGameStarted', function () { console.log(info);
console.log("A new 10 minute game has started.");
console.log("Enter your moves in algebraic notation. E.g. e2e4<Enter>");
console.log(game.ascii());
var stdin = process.openStdin();
stdin.on('data', function (move) {
if (move == 'exit' + os.EOL || move == 'quit' + os.EOL) {
process.exit();
return;
}
move = convertToMoveObject(move.toString().replace(os.EOL, ''));
game.move(move);
console.log(game.ascii());
console.log("Engine thinking...");
uci.move(move);
}); });
}).on('EngineMoved', function (move, bookMove) { console.log('Starting analysis');
game.move(move); }).delay(2000).then(function () {
console.log('Engine moved ' + move.from + move.to + (move.promotion ? move.promotion : '') + '. BookMove:' + bookMove); console.log('Stopping analysis');
console.log(game.ascii()); return engine.stopCommand();
}).on('GameEnded', function (result, reason) { }).then(function (bestmove) {
console.log('Game ended. Result: ' + result + '. Reason: ' + reason + '.'); console.log('Bestmove: ');
console.log(bestmove);
return engine.quitCommand();
}).then(function () {
console.log('Stopped');
}).fail(function (error) {
console.log(error);
process.exit(); process.exit();
}).on('Error', function (error) { }).done();
console.log('Error:' + error);
});

function convertToMoveObject(move) {
if (typeof move == 'object') {
return move;
}
var result = {};
result.from = move.substring(0, 2);
result.to = move.substring(2, 4);
if (move.length > 4) {
result.promotion = move.substring(4);
}
return result;
}
``` ```
## API ## API


### Events See [here]() for API reference.
UCI is an [EventEmitter](http://nodejs.org/api/events.html) and it raises
following events -

#### Ready
This event is raised once UCI has enumerated all the engines and books.

#### NewGameStarted
This event is raised once UCI has started a new game.

#### EngineMoved
This event is raised when the engine has made a move. The first argument _move_
is an object with properties _from_, _to_ and _promotion_. _from_ and _to_ are
the algebraic notation square names for the from square and to square
respectively. _promotion_ property contains the piece to which the pawn is being
promoted otherwise it is null. E.g. following is a valid move object
```js
{from:'h7', to:'h8', promotion:'q'}
```
The second argument is a boolean which is true if it is a book move and false
otherwise.

#### Error
This event is raised when UCI detects an error. E.g. if the move function is
passed an invalid move object. The argument _message_ contains a string with
details about the error.

#### GameEnded
This event is raised when the game ends either in a draw or with one of the
players (engine or the other player) winning. The two arguments are _result_
which contains the result in a string (e.g. '1-0', '1/2-1/2' or '0-1') and
_reason_ which describes the reason for the result.

### Functions
UCI exposes following functions -

#### move(move)
This function takes an argument _move_ and tries to move this on the internal
board. See the format of the _move_ object above. If the move object is invalid
in any way the _error_ event is raised.
```js
var move = {from:'h7', to:'h8', promotion:'q'};
uci.move(move);
```

#### getAvailableEngines()
When a new uci instance is created it detects all the uci engines placed inside
the *uci/engines* directory. This function returns an array of these engine objects. See _Engine Object_ section below.

#### getAvailableBooks()
When a new uci instance is created it enumerates all the files in the
*uci/books* directory. This function returns a list of these books.

#### startNewGame(engine, engineSide, gameLength, [bookFile])
This function starts a new game. _engine_ is the path of the engine executable,
_engineSide_ is the side which the engine will play. It should be either 'white'
or 'black'. _gameLength_ is the game length in minutes. The optional bookFile is
the path to the polyglot book which the engine will use to lookup moves.
```js
uci.startNewGame('path/to/engine-executable', 'white', 10,
'path/to/polyglot-book');
```

### Engine Object
Each object in the array of engine objects returned in getAvailableEngines() function is described here.

#### setOption function
This function takes a string optionName and a primitive optionValue. Options set using this function will be set on the UCI chess engine. For boolean options the optionValue should not be passed.

#### availableOptions property
This property contains an array of strings of the options available on the UCI engine.

## Installing engines
Place your own uci engines inside the *uci/engines* directory. UCI will detect
all the uci engines inside the engines directory by visiting all the files
recursively and trying to run them. The detected engines can be retrieved by calling the
*getAvailableEngines* function.

## Installing books
Place any polyglot format books under the *uci/books* directory. You can also
create sub directories within the books directory for better organization of
your books. UCI will treat all files found recursively under the *uci/books*
directory as polyglot books so only put valid books files there.


## Contributing ## Contributing
Fork, pick an issue to fix from [issues](https://github.com/imor/uci/issues) or Fork, pick an issue to fix from [issues](https://github.com/imor/uci/issues) or
add a missing feature and send a pull request. add a missing feature and send a pull request.


## Credits
The excellent [chess.js](https://github.com/jhlywa/chess.js) library by [Jeff
Hlywa](https://github.com/jhlywa) and [Stockfish](http://stockfishchess.org/)
the chess engine bundled with UCI.

## License ## License
UCI is released under the MIT License. See the bundled LICENSE file for details. UCI is released under the MIT License. See the bundled LICENSE file for details.
Binary file removed books/book.bin
Binary file not shown.
Binary file removed engines/stockfish/stockfish-3-32-ja.exe
Binary file not shown.
Binary file removed engines/stockfish/stockfish-4-32
Binary file not shown.
Binary file removed engines/stockfish/stockfish-4-64
Binary file not shown.
Binary file removed engines/stockfish/stockfish-linux
Binary file not shown.
33 changes: 33 additions & 0 deletions examples/analyzeStartPosition.js
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,33 @@
var Engine = require('uci');
var engine = new Engine('<path to engine executable>');
engine.runProcess().then(function () {
console.log('Started');
return engine.uciCommand();
}).then(function (idAndOptions) {
console.log('Engine name - ' + idAndOptions.id.name);
return engine.isReadyCommand();
}).then(function () {
console.log('Ready');
return engine.uciNewGameCommand();
}).then(function () {
console.log('New game started');
return engine.positionCommand('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1');
}).then(function () {
console.log('Starting position set');
return engine.goInfiniteCommand(function infoHandler(info) {
console.log(info);
});
console.log('Starting analysis');
}).delay(2000).then(function () {
console.log('Stopping analysis');
return engine.stopCommand();
}).then(function (bestmove) {
console.log('Bestmove: ');
console.log(bestmove);
return engine.quitCommand();
}).then(function () {
console.log('Stopped');
}).fail(function (error) {
console.log(error);
process.exit();
}).done();
14 changes: 0 additions & 14 deletions examples/package.json

This file was deleted.

57 changes: 0 additions & 57 deletions examples/ucidriver.js

This file was deleted.

Loading

0 comments on commit 86519ae

Please sign in to comment.