chess.js icon indicating copy to clipboard operation
chess.js copied to clipboard

chess960 support

Open LocutusOfPenguin opened this issue 8 years ago • 26 comments

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 :-)

LocutusOfPenguin avatar Aug 18 '16 07:08 LocutusOfPenguin

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.

jhlywa avatar Aug 20 '16 16:08 jhlywa

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

LocutusOfPenguin avatar Aug 22 '16 14:08 LocutusOfPenguin

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

djdekker avatar Aug 28 '16 17:08 djdekker

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

ghost avatar Oct 24 '17 01:10 ghost

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.

LocutusOfPenguin avatar Oct 24 '17 05:10 LocutusOfPenguin

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 ^^

ghost avatar Oct 25 '17 15:10 ghost

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

LocutusOfPenguin avatar Oct 25 '17 18:10 LocutusOfPenguin

@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 avatar Jan 06 '18 17:01 sesse

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.

sesse avatar Jan 06 '18 21:01 sesse

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...)

ghost avatar Jan 07 '18 15:01 ghost

@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.)

sesse avatar Jan 07 '18 16:01 sesse

@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 ^^)

ghost avatar Jan 07 '18 17:01 ghost

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 avatar Jan 07 '18 18:01 sesse

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.

sesse avatar Jan 10 '18 23:01 sesse

Hey, can we expect some progress here, please?

undera avatar Aug 17 '19 20:08 undera

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.

maxim-devereaux avatar Sep 17 '20 14:09 maxim-devereaux

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?

sesse avatar Sep 17 '20 14:09 sesse

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.

maxim-devereaux avatar Sep 17 '20 17:09 maxim-devereaux

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.

sesse avatar Sep 17 '20 17:09 sesse

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

trx222 avatar Oct 29 '20 19:10 trx222

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

justingolden21 avatar May 18 '21 23:05 justingolden21

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.

zamfofex avatar Jun 13 '22 16:06 zamfofex