Hey what's up guys, I've finally reached the point of satisfaction with this project -
despite the fact that initially I wanted it to be a chess library, still it's more likely to
call it a LEGO-like chess board/movegen methods set for tinkering and it would rather
make sense for beginners to learn the initial principals of interaction between back-end
move generator and front-end board widget rather than use it somewhere in production
especially bearing in mind the fact I was sticking to pure JS the matter of things like parsing
PGN or drawing arrows on right-click drag-n-drop is the matter of stand-alone library-like
sophisticated projects. So I would rather publish this project as a:
"Experimental pure javascript chess board library-like code base for beginner's tinkering"
The code is very very simple, I've tried to comment every single line of code.
If anything is unclear you can always find the references in my extended move generator tutorials.
Anyway I've created a "crash course" video about this project's usage and inner workings -
it's 1 hour long, but I promise that by the end of this video you'll be able to start working with existing
code base as if it was your own code.
FINAL REALASE (project link):
https://github.com/maksimKorzh/chessboard
LIVE DEMO:
https://maksimkorzh.github.io/chessboard/
CRASH COURSE:
https://www.youtube.com/watch?v=QFY1Mbc ... e=youtu.be
Pure javascript chess board library
Moderators: hgm, Dann Corbit, Harvey Williamson
-
maksimKorzh
- Posts: 771
- Joined: Sat Sep 08, 2018 5:37 pm
- Location: Ukraine
- Full name: Maksim Korzh
Re: Pure javascript chess board library
Didactic chess engines:
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
-
maksimKorzh
- Posts: 771
- Joined: Sat Sep 08, 2018 5:37 pm
- Location: Ukraine
- Full name: Maksim Korzh
Re: Pure javascript chess board library
HGMhgm wrote: ↑Wed Dec 02, 2020 10:53 am Nice!
I did a similar project (the 'Interactive Diagram') aimed at doing arbitrary chess variants. So the rules for the piece movement are not hard-coded, but configurable. I also use a HTML table to represent the board. Initially I had problems with making this work well: the piece images put in the table cells tended to enlarge the height of the row they were in even when their size was so small that they should have fitted. This lead to very annoying expansion and contraction of the board ranks as you moved pieces, unless you made the pieces unaesthetically small.
I could finally solve that problem by using the piece images as background, rather than cell content. An additional advantage of that is that I could then use the cell content to display images of 'markers' used for highlighting move targets and such. Before I was using the background color visible in the transparent surroundings of the pieces to highlight. This is still possible, because even when you use a background image, the HTML background color is still visible through the transparent part of that image.
I made these Diagrams embeddable in this forum:
theme=MV firstRank=1 markerDir=http://www.chessvariants.com/membergrap ... lven-chessThis is an open-ended project. At some point I decided to equip it with a simple AI, (accessible through the 'Play it' link), so it could be used as sparring partner in web pages that explained the rules of a new chess variant. It remembers the game history, and allows you to step through it, while displaying the game in SAN below the diagram.
Pawn::::a2-h2,,a7,h7
Lance::C::a1,h1,,a8,h8
Cannon::mRcpR:Canon:c1,f1,,c8,f8
King::::e1,,e8
I am now working on making it possible to paste pre-existing games in the HTML paragraph that normally displays the game you are playing, so that it can be used as game viewer. The mechanics of the pasting is easy (through the HTML attributes contenteditable and onpaste). But unfortunately I must also write a SAN parser for that to work, which is quite a chore.
Despite the fact I've already answered regarding drag-n-drop I can try to implement described ideas within your sources.
I could've possibly cover this work on my YouTube channel if it works - that's my benefit)
Could you please kindly give me the exact source code link?
Didactic chess engines:
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
-
maksimKorzh
- Posts: 771
- Joined: Sat Sep 08, 2018 5:37 pm
- Location: Ukraine
- Full name: Maksim Korzh
Re: Pure javascript chess board library
Ok, I've just managed to grab the source)maksimKorzh wrote: ↑Thu Dec 03, 2020 5:50 pmHGMhgm wrote: ↑Wed Dec 02, 2020 10:53 am Nice!
I did a similar project (the 'Interactive Diagram') aimed at doing arbitrary chess variants. So the rules for the piece movement are not hard-coded, but configurable. I also use a HTML table to represent the board. Initially I had problems with making this work well: the piece images put in the table cells tended to enlarge the height of the row they were in even when their size was so small that they should have fitted. This lead to very annoying expansion and contraction of the board ranks as you moved pieces, unless you made the pieces unaesthetically small.
I could finally solve that problem by using the piece images as background, rather than cell content. An additional advantage of that is that I could then use the cell content to display images of 'markers' used for highlighting move targets and such. Before I was using the background color visible in the transparent surroundings of the pieces to highlight. This is still possible, because even when you use a background image, the HTML background color is still visible through the transparent part of that image.
I made these Diagrams embeddable in this forum:
theme=MV firstRank=1 markerDir=http://www.chessvariants.com/membergrap ... lven-chessThis is an open-ended project. At some point I decided to equip it with a simple AI, (accessible through the 'Play it' link), so it could be used as sparring partner in web pages that explained the rules of a new chess variant. It remembers the game history, and allows you to step through it, while displaying the game in SAN below the diagram.
Pawn::::a2-h2,,a7,h7
Lance::C::a1,h1,,a8,h8
Cannon::mRcpR:Canon:c1,f1,,c8,f8
King::::e1,,e8
I am now working on making it possible to paste pre-existing games in the HTML paragraph that normally displays the game you are playing, so that it can be used as game viewer. The mechanics of the pasting is easy (through the HTML attributes contenteditable and onpaste). But unfortunately I must also write a SAN parser for that to work, which is quite a chore.
Despite the fact I've already answered regarding drag-n-drop I can try to implement described ideas within your sources.
I could've possibly cover this work on my YouTube channel if it works - that's my benefit)
Could you please kindly give me the exact source code link?
Didactic chess engines:
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
-
hgm
- Posts: 27701
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Pure javascript chess board library
[Note] This message crossed yours.
My cells are created like this (empty):
You see I use quite a number of event handlers. Some of those were added later to get things working on a touch screen. The Hover function is an extra not needed for moving pieces, but for in the move diagrams, to make those dynamic. (E.g. open the piece overview in the example above, and click on 'Cannon' to see what I mean.) When I was still using foreground images I had the problem that the opaque part of the images would catch the mouse events, rather than the <td> they were in
I haven't tried that, but I don't want to resize the image either. If I have 50x50 images, I want them to fit in 50x50 table cells, without shrinking the image, or expanding the cells. I never managed to do that for foreground images. I had to define the height at least as 53 to fit 50x50 images without expanding the cell height. I suppose the problem is made more obvious because I did not use images in empty cells, but even if the height became 53 everywhere always, it would be annoying to me. The images were designed for 50x50 cells.maksimKorzh wrote: ↑Thu Dec 03, 2020 5:28 pmDid you try dynamic resizing of image width within style attribute to prevent cells from resizing?
My cells are created like this (empty):
Code: Select all
h = ranks - 1 - i;
var s = OwnShade(h, j);
row = row + '<td id="' + bnr + 'y' + h + 'y' + j + '" style="width:' + sqrSize + 'px;height:' + sqrSize +
'px;border:thin solid black;font-size:xx-large;background-repeat:no-repeat;background-position: center center"' +
' onmousedown="Down(' + bnr + ',' + j + ',' + h + ',event)" onmouseup="Up(' + bnr + ',' + j + ',' + h +
')" ontouch="Touch(' + bnr + ',' + j + ',' + h +
')" onmouseover="Hover(event' +
')" ondragover="PreDrop(event)" ondrop="Drop(event)" ondragend="Relay()" valign="center" align="center"></td>';
Code: Select all
var curCell;
var obstacle = 0, emulateHover = 0;
function Hover(ev) {
emulateHover = 0;
Interpose(ev.target.id);
}
function Relay() { // catches mouse-up after drag in source. (destination might be eclipsed)
var coords = curCell.split('y');
if(coords.length != 3) return;
Up(parseInt(coords[0]), parseInt(coords[2]), parseInt(coords[1]));
}
function PreDrop(ev) { // keeps track of cell we are in
ev.preventDefault();
s = ev.target.id; if(s.length > 2) curCell = s;
}
function Parent(ev) { // keeps track of cell we are in, when image hides cell
s = ev.target.parentElement.id; if(s.length > 2) curCell = s, Interpose(s);
}
function Drop(ev) { // needed to prevent browser follows link to dragged image
ev.preventDefault();
}
var downX;
var downY;
var noMouse = 0;
var down = 0;
function Down(bnr, x, y, ev) {
if(noMouse) return;
SwitchDiag(bnr);
if(ev.button == 2) {
ev.preventDefault();
RightClick(x, y);
return;
}
downX = x; downY = y; down = 1;
curCell = "";
Click(x, y);
}
function Up(bnr, x, y) { // catches up-click on empty square
if(noMouse) return;
SwitchDiag(bnr);
if(x == downX && y == downY) return; // ignore up on static click
Click(x, y); // on other square up counts as new click event
}
function Touch(bnr, x, y){
noMouse = 1;
SwitchDiag(bnr);
if(touched > 0) { Interpose(bnr + 'y' + y + 'y' + x); return; } else
if(down && x == downX && y == downY) { Display(); down = 0; return; }
downX = x; downY = y; down = 1;
curCell = "";
Click(x, y);
}
-
hgm
- Posts: 27701
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Pure javascript chess board library
Thank you for that. Unfortunately the source has grown to be quite messy, over time. My previous posting already showed the various low-level event handlers; their purpose is to eventually call the routine Click(x, y) with the coordinates of the clicked squares; a drag and drop simulates the two clicks of the corresponding click-click move, by also calling Click() on the mouseup when this happens in another square as the mousedown.maksimKorzh wrote: ↑Thu Dec 03, 2020 5:50 pmDespite the fact I've already answered regarding drag-n-drop I can try to implement described ideas within your sources.
I could've possibly cover this work on my YouTube channel if it works - that's my benefit)
Could you please kindly give me the exact source code link?
Displaying the board is done by the routine Display(), which loops over the board, finds the <td> with the corresponding id, and assigns the image URL to its style.backgroundImage. (Ignore the second part, which updates the piece table if the piece theme was changed.)
Code: Select all
function Display() {
var p;
for(i=0; i<ranks; i++) for(j=0; j<files; j++) {
if(flip) {
x = files - 1 - j;
y = ranks - 1 - i;
} else {
x = j; y = i;
}
cell = active + "y" + y + "y" + x;
board[i][j] &= 2048 - 1; // erase markers
piece = board[i][j] & ~512;
if(piece > 1024) {
piece -= 1024; color = blackPrefix;
} else {
color = whitePrefix;
}
if(piece > 0 && piece != 250) {
// image = '<img ondragover="Parent(event)" src="' + MakeImage(piece, color) + '" style="vertical-align:top">';
image = 'url("' + MakeImage(piece, color) + '")';
} else {
image = "";
}
document.getElementById(cell).style.backgroundImage = image;
document.getElementById(cell).innerHTML = "";
if(piece == 250) Highlight(j, i, "#000000"); else
if(j == hx1 && i == hy1 || j == hx2 && i == hy2) Highlight(j, i, "#80FF80"); else Highlight(j, i, 0);
}
if(document.getElementById('pieceTable' + active) != null) {
if(oldImag != graphDir + whitePrefix + blackPrefix) BetzaCompile(); // switched images, adapt table
for(i=1; i<=nType; i++) {
w = hand[i]; if(w == 0) w = "-";
b = hand[i+nType]; if(b == 0) b = "-";
p = document.getElementById(active + 'w' + i);
if(p != null) p.innerHTML = w;
p = document.getElementById(active + 'b' + i);
if(p != null) p.innerHTML = b;
}
}
if(realColor != '' && realColor != dark && !touched) { if(light == dark) light = realColor; dark = realColor; touched = -1; }
oddShade = 0;
}
A complication is that the same handlers are used also for clicks in the piece table (which all have x coordinate 100 to distinguish them from board squares), as you can also drag pieces from the table to the board, for Crazyhouse-like drops. In that case it is probably not desirable to erase the piece from the cell.
-
maksimKorzh
- Posts: 771
- Joined: Sat Sep 08, 2018 5:37 pm
- Location: Ukraine
- Full name: Maksim Korzh
Re: Pure javascript chess board library
I've just added drag-n-drop in style of my library to your code in a very easy way!hgm wrote: ↑Thu Dec 03, 2020 7:31 pmThank you for that. Unfortunately the source has grown to be quite messy, over time. My previous posting already showed the various low-level event handlers; their purpose is to eventually call the routine Click(x, y) with the coordinates of the clicked squares; a drag and drop simulates the two clicks of the corresponding click-click move, by also calling Click() on the mouseup when this happens in another square as the mousedown.maksimKorzh wrote: ↑Thu Dec 03, 2020 5:50 pmDespite the fact I've already answered regarding drag-n-drop I can try to implement described ideas within your sources.
I could've possibly cover this work on my YouTube channel if it works - that's my benefit)
Could you please kindly give me the exact source code link?
Displaying the board is done by the routine Display(), which loops over the board, finds the <td> with the corresponding id, and assigns the image URL to its style.backgroundImage. (Ignore the second part, which updates the piece table if the piece theme was changed.)
I suppose it would be a matter of temporarily clearing the style.backgroundImage of the from-square on the mousedown when it is a 'first click' (i.e. no piece selected yet), and redefining the mouse pointer as the corresponding piece image. And then undo all that on the subsequent mouseup.Code: Select all
function Display() { var p; for(i=0; i<ranks; i++) for(j=0; j<files; j++) { if(flip) { x = files - 1 - j; y = ranks - 1 - i; } else { x = j; y = i; } cell = active + "y" + y + "y" + x; board[i][j] &= 2048 - 1; // erase markers piece = board[i][j] & ~512; if(piece > 1024) { piece -= 1024; color = blackPrefix; } else { color = whitePrefix; } if(piece > 0 && piece != 250) { // image = '<img ondragover="Parent(event)" src="' + MakeImage(piece, color) + '" style="vertical-align:top">'; image = 'url("' + MakeImage(piece, color) + '")'; } else { image = ""; } document.getElementById(cell).style.backgroundImage = image; document.getElementById(cell).innerHTML = ""; if(piece == 250) Highlight(j, i, "#000000"); else if(j == hx1 && i == hy1 || j == hx2 && i == hy2) Highlight(j, i, "#80FF80"); else Highlight(j, i, 0); } if(document.getElementById('pieceTable' + active) != null) { if(oldImag != graphDir + whitePrefix + blackPrefix) BetzaCompile(); // switched images, adapt table for(i=1; i<=nType; i++) { w = hand[i]; if(w == 0) w = "-"; b = hand[i+nType]; if(b == 0) b = "-"; p = document.getElementById(active + 'w' + i); if(p != null) p.innerHTML = w; p = document.getElementById(active + 'b' + i); if(p != null) p.innerHTML = b; } } if(realColor != '' && realColor != dark && !touched) { if(light == dark) light = realColor; dark = realColor; touched = -1; } oddShade = 0; }
A complication is that the same handlers are used also for clicks in the piece table (which all have x coordinate 100 to distinguish them from board squares), as you can also drag pieces from the table to the board, for Crazyhouse-like drops. In that case it is probably not desirable to erase the piece from the cell.
I'll make a video now and post the code in separate thread!
Didactic chess engines:
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
-
maksimKorzh
- Posts: 771
- Joined: Sat Sep 08, 2018 5:37 pm
- Location: Ukraine
- Full name: Maksim Korzh
Re: Pure javascript chess board library
I've just added drag-n-drop feature to your variant.hgm wrote: ↑Thu Dec 03, 2020 7:31 pmThank you for that. Unfortunately the source has grown to be quite messy, over time. My previous posting already showed the various low-level event handlers; their purpose is to eventually call the routine Click(x, y) with the coordinates of the clicked squares; a drag and drop simulates the two clicks of the corresponding click-click move, by also calling Click() on the mouseup when this happens in another square as the mousedown.maksimKorzh wrote: ↑Thu Dec 03, 2020 5:50 pmDespite the fact I've already answered regarding drag-n-drop I can try to implement described ideas within your sources.
I could've possibly cover this work on my YouTube channel if it works - that's my benefit)
Could you please kindly give me the exact source code link?
Displaying the board is done by the routine Display(), which loops over the board, finds the <td> with the corresponding id, and assigns the image URL to its style.backgroundImage. (Ignore the second part, which updates the piece table if the piece theme was changed.)
I suppose it would be a matter of temporarily clearing the style.backgroundImage of the from-square on the mousedown when it is a 'first click' (i.e. no piece selected yet), and redefining the mouse pointer as the corresponding piece image. And then undo all that on the subsequent mouseup.Code: Select all
function Display() { var p; for(i=0; i<ranks; i++) for(j=0; j<files; j++) { if(flip) { x = files - 1 - j; y = ranks - 1 - i; } else { x = j; y = i; } cell = active + "y" + y + "y" + x; board[i][j] &= 2048 - 1; // erase markers piece = board[i][j] & ~512; if(piece > 1024) { piece -= 1024; color = blackPrefix; } else { color = whitePrefix; } if(piece > 0 && piece != 250) { // image = '<img ondragover="Parent(event)" src="' + MakeImage(piece, color) + '" style="vertical-align:top">'; image = 'url("' + MakeImage(piece, color) + '")'; } else { image = ""; } document.getElementById(cell).style.backgroundImage = image; document.getElementById(cell).innerHTML = ""; if(piece == 250) Highlight(j, i, "#000000"); else if(j == hx1 && i == hy1 || j == hx2 && i == hy2) Highlight(j, i, "#80FF80"); else Highlight(j, i, 0); } if(document.getElementById('pieceTable' + active) != null) { if(oldImag != graphDir + whitePrefix + blackPrefix) BetzaCompile(); // switched images, adapt table for(i=1; i<=nType; i++) { w = hand[i]; if(w == 0) w = "-"; b = hand[i+nType]; if(b == 0) b = "-"; p = document.getElementById(active + 'w' + i); if(p != null) p.innerHTML = w; p = document.getElementById(active + 'b' + i); if(p != null) p.innerHTML = b; } } if(realColor != '' && realColor != dark && !touched) { if(light == dark) light = realColor; dark = realColor; touched = -1; } oddShade = 0; }
A complication is that the same handlers are used also for clicks in the piece table (which all have x coordinate 100 to distinguish them from board squares), as you can also drag pieces from the table to the board, for Crazyhouse-like drops. In that case it is probably not desirable to erase the piece from the cell.
Here's the thread with details:
http://talkchess.com/forum3/viewtopic.php?f=2&t=75979
waiting for your feedback)))
Didactic chess engines:
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
-
maksimKorzh
- Posts: 771
- Joined: Sat Sep 08, 2018 5:37 pm
- Location: Ukraine
- Full name: Maksim Korzh
Re: Pure javascript chess board library
Just fixed drag-n-drop bug in firefox browser
https://maksimkorzh.github.io/chessboard/
https://maksimkorzh.github.io/chessboard/
Didactic chess engines:
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ
https://www.chessprogramming.org/Maksim_Korzh
Chess programming YouTube channel:
https://www.youtube.com/channel/UCB9-pr ... KKqDgXhsMQ