jhlywa / chess.js

A TypeScript chess library for chess move generation/validation, piece placement/movement, and check/checkmate/draw detection
BSD 2-Clause "Simplified" License
3.66k stars 889 forks source link

chess960 support #122

Open LocutusOfPenguin opened 8 years ago

LocutusOfPenguin commented 8 years ago

Hi,

is chess960 supported? When i try to go over a game (code 534 exchanged K/Q), "O-O-O" isnt recognized as kd1-c1, ra1-d1.

If not, i would ask for such feature :-)

jhlywa commented 8 years ago

There is a very outdated 960 branch here -> https://github.com/jhlywa/chess.js/tree/960. If there's demand for 960 support I may merge it with master in the future.

LocutusOfPenguin commented 8 years ago

Hi, to no surprise i have such demand (wish) see here: https://github.com/jromang/picochess/issues/197

djdekker commented 8 years ago

Hello Jeff, I'd like to second this request very much. I'm playing chess960 with PicoChess a lot and the web server cannot handle castling. It just stops updating the game display when White or Black castles. I'd be very grateful if chess.js could support chess960 castling. Cheers, DJ

ghost commented 6 years ago

Hi,

any progress here? I just tried the FRC starting position number 3, where both can castle in the first move:

var c = Chess('bqnnrkrb/pppppppp/8/8/8/8/PPPPPPPP/BQNNRKRB w KQkq - 0 1'); c.moves(); ["a3", "a4", "b3", "b4", "c3", "c4", "d3", "d4", "e3", "e4", "f3", "f4", "g3", "g4", "h3", "h4", "Nb3", "Nd3", "Nc3", "Ne3"] c.move('0-0',{sloppy:true}); null c.move('f1g1',{sloppy:true}); null c.move({from:'f1',to:'g1'}) null

If I use the 5 years old branch "960", what functionality is missing?

regards mike

LocutusOfPenguin commented 6 years ago

see my comment on https://github.com/jromang/picochess/issues/197 from 27.Jun

I fixed it myself based on this old branch, but i dont know if thats good enough for a Lib(!) - incl. some other problems -for picochess seems to work.

ghost commented 6 years ago

Hi Locutus,

thank you for the reply.

I saw you patch, but you seem to differentiate between a standard and a FRC game and I dont want that. For me the standard position is just FRC position 518 ^^

So i made my own patch: https://github.com/jhlywa/chess.js/compare/master...mroh69:960CastleSupport

So far, it seems to work well ^^

LocutusOfPenguin commented 6 years ago

Hi mroh,

thats great. I only did it cause i waited several months with no progress and i needed a solution. I never thinked its the best JS development in world, ha (this board type - frc or not - is from orig code)

Jürgen

sesse commented 6 years ago

@mroh69: I tried your branch on a sample game, but I can't get it to work:

c = new Chess("1br1brkn/pp1ppp1p/1n4p1/2p5/P2N2P1/R7/1PPPPP1P/1BRKBQ1N w Q - 6 7");
c.move("Nf3");
c.move("d5");
c.move("b3");
c.move("f6");
c.move("Ng3");
c.move("Nf7");
c.move("d3");
c.move("Bc6");
c.move("O-O-O");

The last call returns null, i.e., invalid move.

It seemingly also can't deal with disambiguated castling rights in the FEN:

-> c = new Chess("1br1brkn/pp1ppp1p/1n4p1/2p5/P2N2P1/8/1PPPPP1P/RBRKBQ1N b C - 7 7")
<- {WHITE: "w", BLACK: "b", PAWN: "p", KNIGHT: "n", BISHOP: "b", …}
-> c.fen()
<- "8/8/8/8/8/8/8/8 w - - 0 1"
sesse commented 6 years ago

Sorry, the first example is wrong; it actually works correctly in your branch. However, this one doesn't:

var c = new Chess("nbrkbqrn/pppppppp/8/8/8/8/PPPPPPPP/NBRKBQRN w KQkq - 0 1");
c.move("c4");
c.move("f5");
c.move("Nb3");
c.move("c6");
c.move("Ng3");
c.move("f4");
c.move("Ne4");
c.move("O-O-O");
c.move("d4");
c.move("g5");
c.move("Bb4");
c.move("Bg6");
c.move("O-O-O");

The last move is counted as invalid; seemingly it thinks that Nb3 is invalidating the queen-side castling rights.

ghost commented 6 years ago

Hi @sesse Thank you for testing my branch! I made some small changes, that should fix this problem, please pull.

(Im still not sure if its good enough to make a pull request to the origin...)

sesse commented 6 years ago

@mroh69: This still looks wrong to me. Now moving any rook to the left of the king will clear queenside castling. You really need to keep track of which rooks have castling rights; the logical place would be the ROOKS array. (Imagine having rooks on a1 and c1 with the king on d1; you'll need to track whether it's the a1 or c1 rook that has castling status to see whether you can do O-O-O. The FEN would look different for the two cases, too; for the outer rook at a1, it would be Q, but for c1, it would be C.)

ghost commented 6 years ago

@sesse : Yes, you are right. This is exactly the example why X-FEN (or sometimes called Shredder-FEN) is needed, because standard FEN cant handle this case... So, to fix this, we also need to change the fen parsing, otherwise you would not know if the a1 or c1 rook is the castle rook... Still, its better than before (and good enough for me ^^)

sesse commented 6 years ago

Sure, but FEN or not, your current patch still does not handle this kind of situation as far as I can see:

var c = new Chess("nbrkbqrn/pppppppp/8/8/8/8/PPPPPPPP/NBRKBQRN w KQkq - 0 1");
moves = ["g4","c5","Rg3","O-O-O","a4","g6","Nb3","Nb6","Nd4","Na8","Ra3","Nb6","Ra1","Na8","Ra3","Nb6","O-O-O"];
for (var i = 0; i < moves.length; ++i) { console.log(c.move(moves[i])); }

The last castling is again taken to be illegal; already the first Ra3 move moved a rook over to the queenside, which cleared the queenside castle flag.

sesse commented 6 years ago

I took your patch and fixed some bugs (including some that affected non-960), added the required FEN support and adjusted the code so it should be a bit closer to the coding style in the rest of chess.js. It now passes the tests, as well as a few new ones that I made for Chess960 (e.g. that it matches Stockfish' perft in a few 960 positions).

It's not very elegant, it doesn't validate FENs all that well, and it doesn't do to/from squares for Chess960 castling right, but I think it should be usable. You can find it at https://github.com/jhlywa/chess.js/compare/master...sesse:960.

undera commented 5 years ago

Hey, can we expect some progress here, please?

maxim-devereaux commented 4 years ago

The sesse-patch doesn't follow the conventions used by other programs which support Chess960 (Chessbase for one). For 960-games, the castling rights are always provided in "Shredder-form" as HAha or similar, rather than KQkq, even where it would be unambiguous.

I believe the correct approach should be that a FEN read in with HAha (or a full game header which includes PGN-tag "Variant" = "chess 960") should set a 960-flag, and subsequently both read and write castling rights based on the kings and queens rook starting files. A FEN read in with KQkq (or parts thereof) and no Variant tag should be treated as normal chess, and fail validation if the rooks are not on a/h files and the king on the e-file.

I'm also looking at writing a patch to support 960.

sesse commented 4 years ago

The sesse-patch doesn't follow the conventions used by other programs which support Chess960 (Chessbase for one). For 960-games, the castling rights are always provided in "Shredder-form" as HAha or similar, rather than KQkq, even where it would be unambiguous.

Software simply isn't consistent on this; you just have to pick one and run with it. The behavior used in the patch is X-FEN, which is the closest thing we have to a standard right now.

I'm also looking at writing a patch to support 960.

Why do you need yet more of them?

maxim-devereaux commented 4 years ago

I'm also looking at writing a patch to support 960.

Why do you need yet more of them?

Because I haven't yet seen a patch for chess.js with full support for Shredder-FEN, and Shredder-FEN makes more sense as far as I'm concerned. I have a chess database/training website: I want to upload files from Chessbase, play through and modify them online, and potentially export them again to Chessbase.

Admittedly 960 is a very very small part of this, but I have some tactical problems from the recent St.Louis tournament which I want to use.

Btw, I don't think you can really say "X-FEN, which is the closest thing we have to a standard right now", without defining who "we" are. All the commercial programs I've looked at that support 960 use Shredder-FEN for output format.

sesse commented 4 years ago

OK, so basically you want whatever Chessbase outputs, but I'm not sure whether you need a full new patch for that, versus adding options to one of the ones that already exist. I spent a fair bit of time ironing out the bugs and then running perft for a week or so to verify that all the Chess960 stuff worked properly; it's surprisingly subtle.

By “we”, I mean “the world”, or “community”, or whatever. I'm much more concerned about what UCI engines do than what Chessbase does, but people have different demands.

trx222 commented 3 years ago

I am also asking if there are plans to merge 960 functions into master?

justingolden21 commented 3 years ago

Hi, just wondering in 2021 here if chess960 will be added to chess.js anytime soon. Thank you : )

ghost commented 2 years ago

Hello. I hate to come into someone else’s repository and advertise like this, but I wanted to say that last year I have created a chess library in JavaScript that (as of a few months ago) supports chess 960!

From an example above in the thread:

import {fromFEN, toSAN} from "dummyette/notation.js"

let board = fromFEN("nbrkbqrn/pppppppp/8/8/8/8/PPPPPPPP/NBRKBQRN w KQkq - 0 1")
let moves = "g4 c5 Rg3 O-O-O a4 g6 Nb3 Nb6 Nd4 Na8 Ra3 Nb6 Ra1 Na8 Ra3 Nb6 O-O-O"
for (let name of moves.split(" "))
{
    let move = board.moves.find(move => toSAN(move) === name)
    console.log(move.name)
    board = move.play()
}
output ~~~ g2g4 c7c5 g1g3 d8c8 a2a4 g7g6 a1b3 a8b6 b3d4 b6a8 g3a3 a8b6 a3a1 b6a8 a1a3 a8b6 d1c1 ~~~

A caveat, however, is that it’s almost as slow as dirt.

chao-mu commented 4 months ago

I'm not a Chess960 player, but I am a Chess developer and it's hard to deny that traction is gaining on this format. Currently telling users "Sorry, not at this time", but would be neat if it didn't tank the complexity of the code base! It does seem like a frightening prospect though. Maybe some kind of extension interface would help break things out and support people who have interest in it implementing/contributing it themselves.

sesse commented 4 months ago

@chao-mu I don't know why you would want an extension interface; there's already a patch (see one of my previous comments), it works well and has been extensively tested both through unit tests and through practice, by multiple different organizations.

chao-mu commented 4 months ago

That's great! I just ended up here on a Google search and since I use this library so often I thought I'd shared my two sense and encouragement. This library is such a wonderful gift to the chess community.

cmgchess commented 1 month ago

this is what used on lichess https://github.com/niklasf/chessops