lila/README.md

326 lines
11 KiB
Markdown
Raw Normal View History

2013-06-08 04:40:31 -06:00
[lichess.org](http://lichess.org)
2013-06-08 05:25:27 -06:00
---------------------------------
2014-06-01 17:50:45 -06:00
It's a free online chess game focused on [realtime](http://lichess.org/games) and ease of use
2013-06-08 04:40:31 -06:00
It haz a [search engine](http://lichess.org/games/search),
2013-12-27 02:42:50 -07:00
[computer analysis](http://lichess.org/analyse/ief49lif),
[tournaments](http://lichess.org/tournament),
[forums](http://lichess.org/forum),
[teams](http://lichess.org/team),
2014-02-09 04:53:20 -07:00
[puzzles](http://lichess.org/training),
2014-06-01 17:50:45 -06:00
a weird [monitoring console](http://lichess.org/monitor),
and a [world map](http://map.lichess.org).
The UI is available in [80 languages](http://lichess.org/translation/contribute) thanks to the community.
2013-06-08 04:40:31 -06:00
2014-06-01 17:50:45 -06:00
Lichess is written in [Scala 2.11](http://www.scala-lang.org/),
and relies on [Play 2.3](http://www.playframework.com/) for the routing, templating, and JSON.
2013-07-29 02:18:05 -06:00
Pure chess logic is contained in [scalachess](http://github.com/ornicar/scalachess) submodule.
2013-06-08 04:40:31 -06:00
The codebase is fully asynchronous, making heavy use of Scala Futures and [Akka 2 actors](http://akka.io).
Lichess talks to [Stockfish 5](http://stockfishchess.org/) using a [FSM Actor](https://github.com/ornicar/lila/blob/master/modules/ai/src/main/ActorFSM.scala) to handle AI moves and analysis.
2014-06-01 17:50:45 -06:00
It uses [MongoDB 2.4](http://mongodb.org) to store more than 30 million games, which are indexed by [elasticsearch](http://elasticsearch.org).
2013-06-08 04:40:31 -06:00
HTTP requests and websocket connections are proxied by [nginx 1.4](http://nginx.org).
2014-02-09 04:53:20 -07:00
New client-side features are written in [ClojureScript](https://github.com/ornicar/lila/tree/master/cljs/puzzle/src).
2014-06-02 01:33:24 -06:00
The [blog](http://lichess.org/blog) uses a free open content plan from [prismic.io](http://prismic.io).
2012-04-25 14:15:35 -06:00
2014-01-16 01:46:01 -07:00
Join us on #lichess IRC channel on freenode for more info.
See the roadmap on https://etherpad.mozilla.org/ep/pad/view/ro.3bIwxJwTQYW/latest.
2013-06-08 05:25:27 -06:00
2012-06-18 06:36:49 -06:00
Installation
2013-06-08 05:25:27 -06:00
------------
2012-04-25 14:15:35 -06:00
2014-02-22 19:24:48 -07:00
> If you want to add a live chess section to your website, you are welcome to [embed lichess](http://lichess.org/developers). It's very easy.
> This project source code is open for other developers to have an example of non-trivial scala/play2/mongodb application. You're welcome to reuse as much code as you want for your projects, and to get inspired by the solutions I propose to many common web development problems. But please don't just create a public lichess clone. Instead, just [embed lichess using an <iframe>](http://lichess.org/developers).
> Also note that if I provide the source code, I do **not** offer support for your lichess instance. I will probably ignore any question about lichess installation and runtime issues.
2013-06-08 05:25:27 -06:00
2014-05-11 12:02:42 -06:00
## HTTP API
Feel free to use lichess API in your applications and websites.
If the resource you need is not available yet,
drop me an email at thibault.duplessis@gmail.com, and we'll discuss it.
2013-12-30 19:00:56 -07:00
2014-01-08 17:06:20 -07:00
### `GET /api/user/<username>` fetch one user
2013-12-30 19:00:56 -07:00
```
2013-12-31 03:51:27 -07:00
> curl http://en.lichess.org/api/user/thibault
2013-12-31 03:45:37 -07:00
```
```javascript
2013-12-30 19:24:24 -07:00
{
2013-12-31 03:51:27 -07:00
"username": "thibault",
2014-01-07 18:43:20 -07:00
"url": "http://lichess.org/@/thibault", // profile url
2014-01-08 17:06:20 -07:00
"rating": 1503, // global Glicko2 rating
2013-12-31 03:51:27 -07:00
"progress": 36, // rating change over the last ten games
"online": true, // is the player currently using lichess?
"playing": "http://lichess.org/abcdefgh", // game being played, if any
2014-01-08 17:06:20 -07:00
"engine": false // true if the user is known to use a chess engine
2013-12-30 19:24:24 -07:00
}
2013-12-30 19:00:56 -07:00
```
2014-01-27 15:38:00 -07:00
Example usage with JSONP:
2013-12-31 03:45:37 -07:00
```javascript
$.ajax({
2014-02-16 16:46:46 -07:00
url:'http://en.lichess.org/api/user/thibault',
2013-12-31 03:45:37 -07:00
dataType:'jsonp',
jsonp:'callback',
success: function(data) {
// data is a javascript object, do something with it!
console.debug(JSON.stringify(data));
}
});
```
2014-01-08 17:06:20 -07:00
### `GET /api/user` fetch many users
All parameters are optional.
name | type | default | description
--- | --- | --- | ---
2014-01-08 17:15:29 -07:00
**team** | string | - | filter users by team
2014-01-08 17:06:20 -07:00
**nb** | int | 10 | maximum number of users to return
```
> curl http://en.lichess.org/api/user?team=coders&nb=100
```
```javascript
{
"list": [
{
"username": "thibault",
"url": "http://lichess.org/@/thibault", // profile url
"rating": 1503, // global Glicko2 rating
"progress": 36, // rating change over the last ten games
"online": true, // is the player currently using lichess?
"engine": false // true if the user is known to use a chess engine
2014-01-08 17:15:29 -07:00
},
... // other users
2014-01-08 17:06:20 -07:00
]
}
```
2014-01-27 15:38:00 -07:00
Example usage with JSONP:
2014-01-08 17:06:20 -07:00
```javascript
$.ajax({
2014-02-16 16:46:46 -07:00
url:'http://en.lichess.org/api/user',
2014-01-08 17:06:20 -07:00
data: {
team: 'coders',
nb: 100
},
dataType:'jsonp',
jsonp:'callback',
success: function(data) {
// data is a javascript object, do something with it!
console.debug(JSON.stringify(data.list));
}
});
```
### `GET /api/game` fetch many games
2014-01-07 18:43:20 -07:00
2014-01-08 17:06:20 -07:00
Games are returned by descendant chronological order.
All parameters are optional.
2014-01-07 18:43:20 -07:00
name | type | default | description
--- | --- | --- | ---
**username** | string | - | filter games by user
**rated** | 1 or 0 | - | filter rated or casual games
**analysed** | 1 or 0 | - | filter only analysed (or not analysed) games
2014-01-08 17:06:20 -07:00
**nb** | int | 10 | maximum number of games to return
**with_analysis** | 1 or 0 | 0 | include deep analysis data in the result
2014-01-07 18:43:20 -07:00
**token** | string | - | security token (unlocks secret game data)
```
> curl http://en.lichess.org/api/game?username=thibault&rated=1&nb=10
```
```javascript
{
"list": [
{
"id": "x2kpaixn",
"rated": false,
2014-06-06 03:08:43 -06:00
"status": "mate", // (1)
2014-01-27 06:38:23 -07:00
"clock":{ // all clock values are expressed in seconds
"limit": 300,
"increment": 8,
"totalTime": 540 // evaluation of the game duration = limit + 30 * increment
},
2014-01-07 18:43:20 -07:00
"timestamp": 1389100907239,
"turns": 44,
"url": "http://lichess.org/x2kpaixn",
"winner": "black",
"players": {
"white": {
"userId": "thibault"
"rating": 1642,
"analysis": {
"blunder": 1,
"inaccuracy": 0,
"mistake": 2
2014-01-27 15:20:08 -07:00
}
2014-01-07 18:43:20 -07:00
},
"black": ... // other player
}
"analysis": [ // only if the with_analysis flag is set
{
"eval": -26, // board evaluation in centipawns
2014-06-07 02:12:40 -06:00
"move": "e4"
},
{
"eval": -8,
2014-06-07 02:12:40 -06:00
"move": "b5"
},
{
"eval": -66,
"move": "Nfe3",
"variation": "c4 bxc4 Nfe3 c5 Qf1 f6 Rxc4 Bb7 b4 Ba6"
},
// ... more moves
],
2014-01-07 18:43:20 -07:00
},
{
... // other game
}
]
}
```
(1) All game statuses: https://github.com/ornicar/scalachess/blob/master/src/main/scala/Status.scala#L16-L25
2014-06-06 03:08:43 -06:00
### `GET /api/game/{id}` fetch one game by ID
A single game is returned.
All parameters are optional.
name | type | default | description
--- | --- | --- | ---
**with_analysis** | 1 or 0 | 0 | include deep analysis data in the result
**token** | string | - | security token (unlocks secret game data)
2014-06-06 03:08:43 -06:00
```
> curl http://en.lichess.org/api/game/x2kpaixn
```
```javascript
{
"id": "x2kpaixn",
"rated": false,
"status": "mate", // (1)
"clock":{ // all clock values are expressed in seconds
"limit": 300,
"increment": 8,
"totalTime": 540 // evaluation of the game duration = limit + 30 * increment
},
"timestamp": 1389100907239,
"turns": 44,
"url": "http://lichess.org/x2kpaixn",
"winner": "black",
"players": {
"white": {
"userId": "thibault"
"rating": 1642,
"analysis": {
"blunder": 1,
"inaccuracy": 0,
"mistake": 2
}
},
"black": ... // other player
},
"analysis": [ // only if the with_analysis flag is set
{
"eval": -26, // board evaluation in centipawns
2014-06-07 02:12:40 -06:00
"move": "e4"
},
{
"eval": -8,
2014-06-07 02:12:40 -06:00
"move": "b5"
},
{
"eval": -66,
"move": "Nfe3",
"variation": "c4 bxc4 Nfe3 c5 Qf1 f6 Rxc4 Bb7 b4 Ba6"
},
// ... more moves
]
2014-06-06 03:08:43 -06:00
}
```
(1) All game statuses: https://github.com/ornicar/scalachess/blob/master/src/main/scala/Status.scala#L16-L25
2014-06-12 15:27:02 -06:00
### `GET /{id}/pgn` fetch one game PGN by ID
This returns the raw PGN for a game.
```
> curl http://en.lichess.org/Qa7FJNk2/pgn
```
```
[Event "Rated game"]
[Site "http://lichess.org/Qa7FJNk2"]
[Date "2014.06.12"]
[White "onpurplesz"]
[Black "LauraSchmidt"]
[Result "1-0"]
[WhiteElo "1516"]
[BlackElo "1698"]
[PlyCount "37"]
[Variant "Standard"]
[TimeControl "1020+0"]
[ECO "C50"]
[Opening "Italian Game, General"]
[WhiteClock ":11:9"]
[BlackClock ":14:6"]
[Annotator "lichess.org"]
1. e4 e5 2. Nf3 Nc6 3. Bc4 { Italian Game, General } Qf6?! { (0.13 → 0.98) Inaccuracy. The best move was Nf6. } (3... Nf6 4. d3 Bc5 5. O-O O-O 6. Bg5 Be7 7. a3 d6 8. h3 a6) 4. d3 h6 5. Be3 d6 6. h3?! { (0.84 → 0.31) Inaccuracy. The best move was Nc3. } (6. Nc3 Be6 7. Nd5 Qd8 8. d4 exd4 9. Nxd4 Nxd4 10. Qxd4 c6 11. Nc3 Bxc4 12. Qxc4 Nf6 13. O-O Be7) 6... a6 7. Nbd2 Be6 8. Qe2 Bxc4 9. Nxc4 Nge7 10. a3 Nd4?! { (0.29 → 0.79) Inaccuracy. The best move was O-O-O. } (10... O-O-O 11. O-O g5 12. a4 Bg7 13. Bd2 Kb8 14. Rae1 Qe6 15. b4 f5 16. b5 fxe4) 11. Bxd4 exd4 12. O-O-O Nc6 13. Rhe1 O-O-O 14. e5 dxe5 15. Nfxe5 Nxe5 16. Qxe5 Qxe5? { (0.35 → 1.78) Mistake. The best move was Qxf2. } (16... Qxf2 17. Re2 Qf6 18. Qxf6 gxf6 19. Rf1 Bg7 20. Nd2 h5 21. Ne4 Rhe8 22. Ref2 Re5 23. b3 Rdd5 24. Kb2) 17. Nxe5 Rg8?! { (1.76 → 2.32) Inaccuracy. The best move was Rd7. } (17... Rd7 18. Nxd7 Kxd7 19. Re4 c5 20. c3 dxc3 21. bxc3 Bd6 22. Kc2 b5 23. a4 Ra8 24. d4 Kc6 25. dxc5) 18. Nxf7 Rd7? { (2.35 → Mate in 2) Checkmate is now unavoidable. The best move was Rd5. } (18... Rd5 19. Re8+ Kd7 20. Rde1 Bb4 21. Rxg8 Bxe1 22. Rxg7 Bxf2 23. Nxh6+ Kc6 24. Kd1 Rb5 25. b3 Rh5 26. Nf7) 19. Re8+ { Black resigns } 1-0
```
2014-04-17 02:34:48 -06:00
### `GET /api/puzzle/<id>` fetch one puzzle
```
> curl http://en.lichess.org/api/puzzle/23045
```
```javascript
{
2014-04-20 14:40:49 -06:00
"id": 16177,
"url": "http://lichess.org/training/16177", // URL of the puzzle
"color": "black", // color of the player
"position": "6NK/5k2/2r5/2n3PP/8/8/8/8 w - - 7 39", // FEN initial position
"solution": ["c6h6", "g5h6", "c5e6", "h8h7", "e6g5",
"h7h8", "f7f8", "h6h7", "g5f7"], // solution moves
"rating": 1799 // puzzle glicko2 rating
2014-04-17 02:34:48 -06:00
}
```
### `GET /api/puzzle/daily` fetch daily puzzle
```
> curl http://en.lichess.org/api/puzzle/daily
```
```javascript
{
2014-04-20 14:40:49 -06:00
"id": 16177,
"url": "http://lichess.org/training/16177", // URL of the puzzle
"color": "black", // color of the player
"position": "6NK/5k2/2r5/2n3PP/8/8/8/8 w - - 7 39", // FEN initial position
"solution": ["c6h6", "g5h6", "c5e6", "h8h7", "e6g5",
"h7h8", "f7f8", "h6h7", "g5f7"], // solution moves
"rating": 1799 // puzzle glicko2 rating
2014-04-17 02:34:48 -06:00
}
```
2013-06-08 05:25:27 -06:00
Credits
-------
2014-02-26 17:17:11 -07:00
See the [lichess Thanks page](http://lichess.org/thanks)