mersenneforum.org  

Go Back   mersenneforum.org > Extra Stuff > Programming

Reply
 
Thread Tools
Old 2019-06-29, 05:14   #1
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

3·29·113 Posts
Default A Simple JavaScript Chess GUI

This past week I've been taking a break from Mlucas coding work to pick up work on a little side project I took up over 10 years ago and have worked on occasionally since, a Javascript-based Chess GUI. Started it in order to teach myself the rudiments of JS coding, so experienced JS hands, please try not to laugh too hard at the code. :) There's no underlying algorithmic move-generating engine, perhaps eventually it could be hooked up to a freeware chess program. For now I find it useful to use when playing against my Mac's built-in Chess app, with its (to me) fugly UI, screenshotted below. It also has red-highlighting for unprotected pieces subject to next-move capture (that will eventually be made togglable), a very useful simple tool for a godawful Patzer like myself. It's a kind of visual-baed programming which makes for a nice break from computational number theory.

'tar xjf Mchess.tar.bz2' the tarball attachment, then open the html file therein in your favorite browser - I've only recently-tested under FF, but the JS is simple enough that I hope it's decently portable. To move a piece, click on the piece to highlight, then click on the destination square.

The current round of coding has been centered on adding algebraic-move-notation screen output - I've so far only managed to ugly-hack this as you will see, would really like a nicer 2-column (one for white, one for black) format but have not found a way to put such output to the right of the board display - help here would be appreciated.

Other future adds include ability to read a 'canned' game in algebraic notation from a text file, a move timer, etc.

Bug reports and add suggestions welcome! Hopefully those will be at least similar in number to video clips of users pointing at their browser display and laughing their butts off.
Attached Thumbnails
Click image for larger version

Name:	Screen shot 2019-06-28 at 9.53.25 PM.png
Views:	90
Size:	380.9 KB
ID:	20698  
Attached Files
File Type: bz2 Mchess.tar.bz2 (32.4 KB, 67 views)

Last fiddled with by ewmayer on 2019-07-25 at 22:53 Reason: Updated code as described in post #9; md5 = b53ba0c7423858906b72d4216ffad4bb
ewmayer is online now   Reply With Quote
Old 2019-07-05, 09:53   #2
lavalamp
 
lavalamp's Avatar
 
Oct 2007
London, UK

5×263 Posts
Default

Quote:
Originally Posted by ewmayer View Post
The current round of coding has been centered on adding algebraic-move-notation screen output - I've so far only managed to ugly-hack this as you will see, would really like a nicer 2-column (one for white, one for black) format but have not found a way to put such output to the right of the board display - help here would be appreciated.
The way you currently have it, couldn't you just add another <td> for each line of the output? That would be an instant 2 column table for white/black moves.

The more modern CSS way would be to use a grid layout structure, where you could specify a two column layout of boxes, you could then add a box to the log after each move with JavaScript and it would be automagically fixed to the grid.

You can add HTML code to the page with JavaScript by doing something like the following:
Code:
document.getElementById("gamelog").innerHTML += "<p>1.c4</p>"
Edit: An simple example of a 3 column grid layout is here:
https://gridbyexample.com/examples/example1/

Many more examples here: https://gridbyexample.com/examples/ and a fairly decent guide to grid layouts here: https://css-tricks.com/snippets/css/...te-guide-grid/

Similarly, I would use a grid layout for the chess board, it would be easy to specify an 8x8 grid, populate it with 64 <div> elements, then walk along it with the DOM in JavaScript to alter them as needed. With some nice CSS rules, you could then set the background pictures of the cells according to the pieces and states of the game.

The CSS selectors :nth-child(even) and :nth-child(odd) would let you colour the board appropriately. If you then had a class for each piece, you could set the appropriate background picture for that and modify the div class property with JavaScript as needed, then further if you had classes for "selected" and "attacked" you could change the background position to reveal the appropriate image for those. That last trick is known as CSS image sprites, and requires you stitch the images together into one, like this:
https://www.tutorialrepublic.com/css...ss-sprites.php

Last fiddled with by lavalamp on 2019-07-05 at 10:01
lavalamp is offline   Reply With Quote
Old 2019-07-06, 20:56   #3
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

3·29·113 Posts
Default

Lavalamp, many thanks for the layout tips and references ... it's clear there's gonna be a major round of layout-code changes coming up.

In the meantime, however, I been fixing bugs and adding more stuff to the game-play JS code:

o Refined unprotected-piece highlighting: if player A gives check, only A's pieces which are eligible for unprotected-highlighting are those giving check. (Non-checking pieces protected by virtue of opponent needing to get out of check before doing anything else.)

o Fixed several bugs in algebraic notation related to move disambiguation and pawn promotion.

o Pawn promotion now must be to R,B,N, or Q. (Previously, 'promotion' to pawn was allowed.)

o Several incorrect uses of Number() cast removed, in cases where string type is desired.

The above source-tarball has been updated to reflect those fixes and also has some code I'm currently trying to debug, related to the new algebraic-notation support: One thing it's clear is desirable from both a regular-user and debug perspective is the ability for the user to enter a partial or complete stored game in algebraic-notation form. Past couple days I added basic support for that, but in my simple tests & debug have hit a weird issue that currently has me stumped. Specifically, after putting in place the basic new enter_game() functio, testing it one some simple pawn-only openings and preparing to add the code needed to move the other pieces in accordance with such a replay log, I realized that before parsing such a user-entered game log, I should first call the board_reset() function. As soon as I added a call to that function to the enter_game() function, the latter stopped working. Here's how to see the problem:

E.g. in Firefox, Tools -> Web developer -> Debugger, click on the Mchess.js source file name, scroll down and set breakpoints at lines 265 and 1298, the call to board_reset() from enter_game() and the return statement at the end of board_reset(), respectively (The latter explicit return is unneeded and not present in the original version of the code I posted here, I added it as a handy place to set a breakpoint). Then over in the gameboard click "Enter Game" and load a simple 2-move opening, say "1.d4 d5". (No quotes in what you actually enter.) Entering <return>, what you'll see happen in the debugger is this: You hit the bp at the call to board_reset() at line 265. F7, "step over" (you may have to hit this several times, not sure why), should cause that call to get made and return execution to line 266, at which point resume-execution (F6) should cause the entered 2-pawn-moves game to be reflected in the game board, but nothing happens - for some reason the call to board_reset() from enter_game() causes the latter function to immediately exit.

Now open Mchess.js in an editor and comment out the 3 lines preceding the line 1298 return statement:

// document.info_top.disp.value = "";
// document.info_bot.disp.value = "White to move";
// document.game_log.disp.value = "";

Save the file, reload the game, and again enter the same simple 2-pawn-move game. Now everything works as intended, except for the commented-out parts of the board display code. Why the difference?
ewmayer is online now   Reply With Quote
Old 2019-07-07, 16:32   #4
WraithX
 
WraithX's Avatar
 
Mar 2006

23×59 Posts
Default

Quote:
Originally Posted by ewmayer View Post
Now open Mchess.js in an editor and comment out the 3 lines preceding the line 1298 return statement:
Code:
//	document.info_top.disp.value = "";
//	document.info_bot.disp.value = "White to move";
//	document.game_log.disp.value = "";
Save the file, reload the game, and again enter the same simple 2-pawn-move game. Now everything works as intended, except for the commented-out parts of the board display code. Why the difference?
The problem is you do not have a "game_log" variable in your web page, so Javascript is crashing when it reaches that line and does no further processing.
WraithX is offline   Reply With Quote
Old 2019-07-07, 19:25   #5
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

266716 Posts
Default

Quote:
Originally Posted by WraithX View Post
The problem is you do not have a "game_log" variable in your web page, so Javascript is crashing when it reaches that line and does no further processing.
Ah, thanks - fresh eyes, always helpful! I must've put that in there a few years ago during my last fiddling-binge as a placeholder for a future game-log display, but in my crude current-round attempts to emulate a 2-column game-log display, I replaced it on the html side with a set of numbered sub-logs.

Is there some way to get the FF debugger to help indicate "your JS script has crashed" and backtrace it, gdb-style? In my debug session, the unexplained execution jumps so far have been my only indicators, and that is a very crude tool.

I was still able to put in place the remaining missing replay-saved-game functionality yesterday despite the above issue, just left the 3 lines I had localized the crash to commented out.
ewmayer is online now   Reply With Quote
Old 2019-07-07, 21:02   #6
WraithX
 
WraithX's Avatar
 
Mar 2006

23·59 Posts
Cool

Quote:
Originally Posted by ewmayer View Post
Is there some way to get the FF debugger to help indicate "your JS script has crashed" and backtrace it, gdb-style? In my debug session, the unexplained execution jumps so far have been my only indicators, and that is a very crude tool.
A good place to look for problems is in the "console". In FF you can right-click on a web page and select the "Inspect Element" option. In there you should see things like "Inspector", "Console", "Debugger", etc. I saw the following error in the FF console (my FF is old, error may be different now):
Code:
TypeError: document.game_log is undefined[Learn More]		mchess.js:1297:2
And I saw the following error in Chrome:
Code:
Uncaught TypeError: Cannot read property 'disp' of undefined	Mchess.js:1297 
    at board_reset (Mchess.js:1297)
    at enter_game (Mchess.js:265)
    at HTMLInputElement.onclick (Mchess.html:188)
The following may not be what you are looking for, but it has helped me many times. You can write information to the console with console.log("Helpful info! Variable x = " + x);. I will often use that to binary search my way to problem sections of code.

Actually, looking more online, I see that there are more functions available to the console. You may be interested in console.trace(); which should print out the list of function calls that got you to that location in the code. You can see more console options at these two links:
https://developers.google.com/web/to...ls/console/api
https://developer.mozilla.org/en-US/...eb/API/Console

Last fiddled with by WraithX on 2019-07-07 at 21:03
WraithX is offline   Reply With Quote
Old 2019-07-13, 22:56   #7
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

3·29·113 Posts
Default

Latest version uploaded in OP-attachment ... toggling between JS console and debugger window very handy for ferreting out bugs, especially of the variable-undefined-or-null and dynamic-type-mismatch variety. Highlights:

o Fixed a move-history-corruption bug which was causing undo/redo to go off the rails with a fair amount of regularity;

o Decided to kibosh the in-screen game-log display stuff, too hard to get formatting right, and I figure most folks don't want the log in their face while playing anyway. It's now brought up in an alert popup via button-click. The text inside the alert appears unformatted, but that's simply the alert-window display single-lining everything; in fact there are line breaks between move pairs in the display text, copying it from the alert window into a text file reveals the formatting. JS appears to have no file I/O support for security reasons, but a user could save a game by simply bringing up the log, copying its contents and pasting into a text file. I like the re-simplified layout that results from hiding the log, it lends itself to e.g. mobile devices. Although absent an underlying move-engine it's all academic anyway - like i said I like to use the GUI to help me do slightly less egregiously-stupid sh*t when I'm getting thrashed by Mac Chess;

o Enhanced the "learning mode" threatened-piece highlighting - previously only unprotected-and-under-threat pieces got that, now higher-value pieces under threat by lower-value pieces of opponent are also highlighted, even if they are guarded by another piece. E.g. Queen threatened by P|B|N|R gets flagged even if the attacking piece is subject to subsequent capture. Basically a crude, shallow form of "bad trade" highlighting. The valuations there are P < B = N < R < Q.

o With a view for supporting Ctrl+[letter key] alternative to button-click for the various functions, I played with intercept-keypress a bit, but that is fraught with issues, including:
- How to implement click-delay, e.g. user hits Ctrl, want to wait a fraction of second for secondary keypress;
- The (experimental, commented-out in the attachment tarball) code uses event.preventDefault() and event.stopPropagation() to intercept keystroke events. If not one of the handled key sequences, how to resume default event propagation? (E.g. we check for Ctrl+[supported letter] and failing to find that we return the keypress handling to the default event-handler. With the experimental code I added to Mchess.html to test this re-enabled by removing the comment tags bracketing it, e.g. normal browser-recognized keystroke combs like Ctrl+[tab number] no longer work.

AFAICT the only remaining appreciable missing piece of game-play functionality is automated stalemate detection.

Any thoughts re. undergirding the GUI with the most awesomest algorithmic game-play engine evah are welcome. :) Alas I don't think GIMPS-style highly optimized multithreaded FFT-mul code is gonna be of use here.
ewmayer is online now   Reply With Quote
Old 2019-07-13, 23:46   #8
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

231478 Posts
Default

p.s.: I've added a simple assert() function which allows me to set a single breakpoint inside it in the debugger and replaced a bunch of what were alert([some error message]) with calls to that, but that is only useful where cases where I explicitly check for the error condition in question. What I really need is a general way to break on unexpected-error, thus combining the console's error-messaging with the capability to backtrace such occurrences; will probably have to wrap all the major JS functions in try/catch to effect that.
ewmayer is online now   Reply With Quote
Old 2019-07-25, 23:18   #9
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

983110 Posts
Default

OK, latest version uploaded:

o Info bars at top/bottom enhanced, so player who just moved has last-move shown in their infobar;

o Wrapped all function bodies in try/catch with catch-errors triggering an assert() call - so for debugging, just set a BP inside the latter function, at line 174 of Mchess.js;

o Added support for input-game castling notation using either 0s or Os, and allowing for a space before White's move on each round. That effectively supports PNG, I used Fischer-Portisch (Havana, 1966) (go to PGN line, click 'view') to debug these changes;

o More fixes/changes to unprotected-piece highlighting, to account for pieces which are pinned, as well as ones protected by the King. Also, only pieces capturable on the very next move (i.e. of just the color opposite that of the player whose turn it is) are highlighted.

In an attempt to also slightly desuckify my own game play I've been playing against MacChess, with slider set around 30% of the way from 'faster' (weakest) to 'stronger' ... even on that modest setting, the only way I've found to not get crushed inside of 20 moves is as follows:

1. Try various move possibilities using Mchess to highlight unprotected and give me a better visual of the board than MacChess does;

2. Let the computer give me frequent hints as to my best move, *but* discard the obviously bad ones, e.g. which result in me losing material with no apparent compensation.

The game I'm currrently slow-playing is listed below - I am White, evil PC is Black - things start with a Ruy Lopez a la Fischer-Portisch above, but on move 5 Portisch plays ...f6 whereas evil PC as Black plays Bd6:

Mayer vs Evil PC, Novato 2019:
1.e4 e5
2.Nf3 Nc6
3.Bb5 a6
4.Bxc6 dxc6
5.O-O Bd6
6.d4 exd4
7.Nxd4 Nf6
8.Nc3 O-O
9.Qd3 Be5
10.Be3 Ng4
11.Nf3 Qxd3
12.cxd3 Rd8
13.d4 Nxe3
14.fxe3 Bf6
15.e5 Be7

The current state of the board through 15 rounds is pictured in the attachment - you can download the latest version of the Mchess tarball from the OP and enter the moves to replay and take it from the current state, if you like. In the last few rounds of the above game the PC repeatedly hinted that White should move pieces, but I found that steadily advancing White's pawns in the middle of the board seemed to work well in terms of putting Black on the defensive. The "fun question for the chess players amongst the readership" is: what is White's best move? (Evil PC hints 16.Rac1, which if taken leads it to respond ...Bg4).
Attached Thumbnails
Click image for larger version

Name:	Screen shot 2019-07-25 at 3.47.57 PM.png
Views:	72
Size:	38.8 KB
ID:	20807  

Last fiddled with by ewmayer on 2019-07-25 at 23:27
ewmayer is online now   Reply With Quote
Old 2019-07-25, 23:30   #10
paulunderwood
 
paulunderwood's Avatar
 
Sep 2002
Database er0rr

3,499 Posts
Default

I would play b3 in order to protect from the Black's white square bishop from coming down the queen's side.

Last fiddled with by paulunderwood on 2019-07-25 at 23:41
paulunderwood is online now   Reply With Quote
Old 2019-07-26, 03:10   #11
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
República de California

231478 Posts
Default

Quote:
Originally Posted by paulunderwood View Post
I would play b3 in order to protect from the Black's white square bishop from coming down the queen's side.
16.b3 leads to same Evil-PC move as 16.Rac1: ...Bg4.

As I noted, Evil PC recommends 16.Rac1, which if taken leads it to respond Bg4 ... but I think I'm seeing a clear bias in the algorithm, against pawn moves, at least once it gets outside whatever opening book it's using. In the above case Bg4 seems a fairly aggressive move by computer, and asking it for White's recommended move, it suggests another piece move, Nc4, to which is responds by continuing on the offensive, via Rd5.

But the alternative simple pawn-move reply 17.h3 immediately sends Black's bishop scurrying back from g4 to e6.

Last fiddled with by ewmayer on 2019-07-26 at 03:16
ewmayer is online now   Reply With Quote
Reply

Thread Tools


Similar Threads
Thread Thread Starter Forum Replies Last Post
Converting applets to Javascript alpertron Programming 61 2019-04-21 00:15
Vote chess game 4: To be decided? Some chess variant will be interesting to consider with! Raman Chess 6 2016-12-06 06:50
Chess henryzz Chess 27 2014-04-20 16:52
Sun Tries to Get Hip to JavaScript ewmayer Programming 1 2006-10-07 21:23
JavaScript for 2-player interactive game-playing? ewmayer Programming 2 2006-02-04 19:22

All times are UTC. The time now is 22:37.

Thu Nov 26 22:37:38 UTC 2020 up 77 days, 19:48, 4 users, load averages: 1.75, 1.56, 1.59

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.

This forum has received and complied with 0 (zero) government requests for information.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation.
A copy of the license is included in the FAQ.