Comments/Ratings for a Single Item
Using the same variables I created for knowing when to include the Pass or Skip buttons, it will now include "pass" or "skip" in the legal moves datalist when one is legal.
I have not actually tested the use of $extralegal yet
I have now tested it by adding the fission moves in Fusion Chess. It is working.
It seems that continuemove does not terminate program execution, which is sort of what I expected from the description ("returns to the form for making a move"). But any code that is after it will still be executed, if you don't take care to disable it in an else-clause, or in my case by putting a return; behind the continuemove. So it has a delayed effect rather than an instant one. Perhaps this should be made clearer in the manual.
P.S.: It would still be nice if you could put this in the JavaScript for the continuemove page:
function F() { if(document.getElementsByName('pastmoves').length == 0) return; if(legalMoves) { var ori = legalMoves[0][0]; for(var i=legalMoves.length-1; i>0; i--) if(legalMoves[i][0] != ori) break; if(!i) movePiece(ori); } } setTimeout("F()", 200);
This will automatically highlight the continuation moves if there is only one piece that can make them. But only on a page that contains a 'Past moves' field. I tested this code on a local copy I made of such a page.
[Edit] BTW, how about expanding this code to allow a GAME-code-specified text to appear in the move entry field, in the case it 'auto-selects'? In some variants, entering a locust capture as two normal moves, first to make the capture, and then to move on to the final destination is quite unnatural. E.g. in Odin's Rune Chess the Forest Ox moves like a Knight, but can optionally make one of the enemies adjacent to its destination disappear. The Natural way to enter that is through move + suicide, e.g. N g1-f3; @-e4. The alternative, N g1-e4; N e4-f3 is somewhat counter-intuitive, because of the strange first leap. There doesn't seem a way to enter the suicide notation with the mouse, though.
This problem could be solved by having (after entering N g1-f3, which would be recognized as ambiguous because the optional suicide might follow, and would thus do a continuemove) the form for the follow-up move appear with " @-" in the move-entry field, and all pieces that could be optionally captured highlighted. Clicking on one of the pieces would then provide the destination square (e4, say), and send the move as @-e4. If the user doesn't want to make the capture, he could hit the Pass button.
One way to achieve this would be to allow the GAME code to do setlegal 0 " @-"; to append a fake move to the $legalmoves array, which would be passed to the JavaScript as [0, " @-"]. The JavaScript could recognize that from legalMoves[i][0], and remove it from the array, writing legalMoves[i][1] into the move entry field, before calling movePiece to highlight the destinations given in the remaining legalMoves.
The GAME code could then also use this for facilitating entry of a freedrop, e.g. for a non-standard castling where the Rook does not have to end up next to the King, but could go on any square the King moved through. After entering the King move the continuemove screen could then be made to pop up with " R-" (or " r-") in the move entry, and the possible Rook destinations highlighted, by using setlegal 0 " R-"; before the continuemove. It would also facilitate the entry of moves for the Valkyrie in Odin's Rune Chess: when this 'captures' a friend, the latter can be relocated to any square the Valkerie passed through (or came from). The GAME code knows what the first leg captured, so it could prepare the entry of the freedrop of it.
Some cosmetic issues:
when I use the Play function in the preset's menu, I get to see this:
This looks a bit disproportional. The move entries look excessively large, while the message I am trying to show to the user (arguably by far the most important item in this screen...) is printed in a miniscule font above those, hardly noticeable at all. Also, there is a strange repetition of the 'past moves' in a much smaller size left of the 'Turn' field, the purpose of which is not clear.
When I use the 'Move' mode of the preset, the layout looks a bit more balanced, but the message to the user is still very inconspicuous:
It seems more logical to me if the specific message to the user would be appended to the header, like "Move as White: enter second leg or pass". Or in the second case "White to play: enter second leg or pass" in a much larger font.
This code would actually do it:
function F() { if(document.getElementsByName('pastmoves').length == 0) return; if(legalMoves) { var ori = legalMoves[0][0], n = legalMoves.length - 1, t = ''; if(legalMoves[n][0] == 'movetext') t = legalMoves[n--][1], legalMoves.pop(); for(var i=n; i>0; i--) if(legalMoves[i][0] != ori) break; if(!i) { movePiece(ori); if(t != '') document.getElementById('movesfield').value = t; } } } setTimeout("F()", 100);
This would allow the GAME code to abuse the $legalmoves array to pass an arbitrary text xxx for the movefield in the continuemove form, by adding a 'move' ("movetext" "xxx") as the last element. The JavaScript would then clip that off, and place it in the move field, after selecting the only piece at the origin of all remaining moves to highlight its targets. These moves would also be fakes, as it is not really this piece that is going to move, as you would be preparing for the entry of a suicide of freedrop, which only require a destination. So the mentioned origin is just a dummy. The fake 'movetext move' cannot be added using setlegal, as the latter would test its arguments for being valid square names. But it can be added by assigning directly to $legalmoves.
BTW, there is no formal description of setlegal in the GAME-code manual.
when I use the Play function in the preset's menu, I get to see this:
This looks a bit disproportional.
Play mode is designed for two people at the same physical location to play on the same mobile device. You should not be using it with a laptop or desktop. Click on "Move" for the desktop solitaire mode.
Ah. The menu doesn't warn for that, though. It says: "[Play] someone at the same location, using the screen as a shared board.". Not "[Play] someone at the same location, using a phone as a shared board." I tried it on a phone now, and it isn't really a big improvement. I understand now why there is a small replica of the "Past moves", because at least that is visible directly under the board, on such a small screen. The message 'Enter next leg' is still presented in an extremely awkward way, though. I don't know how to make screenshots on that phone, but it is sharing the width of the screen with the CAPTURED PIECES header (which has a much larger typeface), so that it is squeezed into 5 lines above each other. The "Legal moves displayed. Might enforce rules." line, which at that stage has become completely useless, is still separating all the useful info from the board image. I understand that phones are awkward in general, and require economizing on almost everything, but it seems it should be possible to do (a lot) better than this...
The problem with the "[Move] pieces by yourself on a desktop PC" is that it is practically unusable, because it flips the position every move. I couldn't find any control in the menu to switch that off. This is why Play mode works much better, even on a desktop.
BTW, how about expanding this code to allow a GAME-code-specified text to appear in the move entry field, in the case it 'auto-selects'?
You can add additional legal moves to the $extralegal array, and these will show up in autocomplete.
One way to achieve this would be to allow the GAME code to do setlegal 0 " @-"; to append a fake move to the $legalmoves array, which would be passed to the JavaScript as [0, " @-"].
This is what the $extramoves array is for. So, there is no need to do it by modifying the setlegal command. Furthermore, "@-" is not a complete move, because it does not specify any coordinate.
It might be possible to come up with a way of allowing non-standard moves with the mouse, which would require more complexity in the movePiece() function and the legalMoves array. But this has to be thought through more, and I need to consider what I might do with JavaScript or HTML5. Let's think about what types of non-standard moves there are and how these could be entered by clicking the board with a mouse.
Sure, " @-" it is not a comlplete move. Like "L c3-" is not a complete move. That is the entire idea of moving by mouse clicks: you first get a partial move in the the movefield, and then you click on the destination square to complete it, and the script sends it to the server. By chosing twice from about 10 possibilities, you effectively make a one-in-a-hundred choice, without ever having to be presented all 100 alternatives at once. The problem is that there is no mouse click that puts " @-" in the movefield, unlike the "L c3-", which you get by clicking a Lion on c3. But the server could put it there when it knows that you will need it there, when it knows that you must enter a suicide as continuemove.
I am not sure what you mean by 'auto-complete', also because the Play function that I have been using doesn't seem to have it. But if you mean the drop-down menu of moves that appear when one clicks the movefield in Move mode... there doesn't seem to be anything 'auto' on that. It requires a click to open the menu, and then you have to read all the moves, match them to squares on the board mentally, and pick the move you need. 'Auto-complete' usually means that when you enter a partial move that can only be completed in a single way, the interface does that for you, without you having to do anything at all. This is what I do in the Sandbox test preset with the swap moves I gave to the Knights; when they make a friendly capture, the victim automatically appears on their square of origin, because the necessary freedrop needed to do that is the only continuation that could make the move legal. A pull-down menu presenting moves in text form is so much worse than just clicking the desired highlighted square that I would never consider using it. Having a button that forces " @-" in the movefield, similar to the Pass button, would be a better option; suicide side effects could then be entered (as continuemove) by feeding them to setlegal as moves of the just-moved piece to the victims, so that you could switch on the highlights by clicking that piece, overwrite the origin part of the move that appeared by this in the move field by pressing that Suicide button, and finally clicking the desired destination square to complete the move and send it.
The problem is that a similar solution is not available for freedrops, as this would require the piece type to be dropped to appear in the movefield, and we cannot have buttons for every participating piece type. This is why it needs guidance from the GAME code. One solution would be an (optional) argument of continuemove, for placement in the movefield as partial move, switching on the highlights of the highlights on the possible destination squares of a freedrop or suicide. An alternative would be to make setlegal accept a piece label or @ as origin, to indicate legal freedrops or suicides. This could be used by the JavaScript to trigger placing it as origin in the movefield, switching on the highlights for it. Or you could have a button for it, which on pressing would put " @-" in the move field, and switch on the highlights on the destinations on all moves with @ as origin. There could also be a Drop button, which would similarly enable all moves in legalMoves that have a piece label as origin (hoping that they all use the same piece label, or that their destination uniquely determines what the piece type should be).
A more elaborate alternative is to have the legalMoves array not just describe the upcoming leg of complex moves, but the entire move, as arrays of 2, 4, 6, ... squares. There wouldn't even be need for communication with the server through continuemove then; the JavaScript would handle it all up to the point where the move is known to be complete, and only then send it to the server. (You could still make an exception for promotion, which would need another screen anyway.) E.g. in a CV with a non-standard castling, where the Rook can be freely placed independent of the King (assumed to start on f1 on a 10-wide board in the example), you could have something like:
legalMoves = [["f1","e1"], ["f1","g1"],["f1","h1","j1","g1"],["h1","h1","j1","f1"],["f1","i1","j1","h1"],["f1","i1","j1","g1"],["f1","i1","j1","f1"], ...];
After clicking the King (e1, g1, h1 and i1 get highlighted), and the empty square i1, the JavaScript would see that this second square only occurs in longer moves, that all have "j1" as next square. It would therefore automatically select the Rook on j1, and highlight the possibilities for the following square, h1, g1 and f1. A click on one of those would finish the move, and cause it to be uploaded (e.g. as K f1-i1; R j1-f1). With 3 clicks you would have specified the move. If there is ambiguity w.r.t. the number of legs (e.g. K f1-g1 could be a normal move or a castling) the JavaScript could err on the safe side and refrain from automatic sending; the user could press Move to force sending, or continue clicking the Rook for castling. There would be no auto-selection of the Rook, because j1 would not be the 3rd square in all the moves that matchetd f1-g1 for the first two, as some of the moves did not have a 3rd square. Instead of square names the array could of course also contain piece labels or @, to indicate the corresponding leg of the move is a freedrop or suicide.
I tried to use an alias with my general code, but I ran into a problem. The algorithm I use is to merge the set of captured pieces with a set of pieces that are in infinite supply, and then take the intersection with the allowed choices on the destination rank. That set is displayed in the askpromote screen, and it is later tested whether the choice is actually in that set (because the user might have sneakily typed something else).
The problem now is that the set of captured pieces seems to be kept as the original labels, while the askpromote menu returns the alias. When I use the alias in the array of available choices for the rank, the choice will not be available, because it is not in the captured pieces. If I use the original label in the availability array, it does intersect with the captured pieces and shows the choice. But if you then make it, it considers the choice illegal, because the choice is returned as the alias, and that is not in the set.
What could be done about this? Is there a command like match to check whether a given value is an alias of one of the elements of an array? Or to convert an array of names to an array of aliases? Can I unalias the promotion choice? (In general that might not be unique...)
Sure, " @-" it is not a comlplete move. Like "L c3-" is not a complete move. That is the entire idea of moving by mouse clicks: you first get a partial move in the the movefield, and then you click on the destination square to complete it, and the script sends it to the server.
That's a different context. You were suggesting it be placed in the legalMoves array, which is an array of complete moves.
I am not sure what you mean by 'auto-complete', also because the Play function that I have been using doesn't seem to have it.
It does have it unless you are using an old browser with inadequate support for HTML5.
But if you mean the drop-down menu of moves that appear when one clicks the movefield in Move mode... there doesn't seem to be anything 'auto' on that.
As you type in a move, it narrows down the list of moves to those that might match it.
'Auto-complete' usually means that when you enter a partial move that can only be completed in a single way, the interface does that for you, without you having to do anything at all.
In the context of entering text into a text input field in an HTML form, which is the proper context to think of it in, autocomplete makes suggestions for you as you type. See HTML <datalist> Tag and HTML <input> autocomplete Attribute, where this term is used. By default, autocomplete draws its suggestions from what you have entered into the same field in the past. But for games that supply a list of legal moves, it now draws its suggestions solely from this list.
That's a different context. You were suggesting it be placed in the legalMoves array, which is an array of complete moves.
Well, I am just using legalMoves as a vehicle to transfer information from the GAME code to the JavaScript in the move-entry pages, because at this point it seems the only way to transfer information that way. I don't care much whether the information is a move or a poem. Indeed ["movetext"," @-"] is not the representation of a move like JavaScript uses in its legalMoves array, because neither "movetext" nor " @-" are valid square coordinates. But their presence in the legalMove list would not hurt the existing JavaScript, because neither of those would match the coordinates of a clicked square. And the code I proposed would remove it from the array before the existing code gets a chance to do anything with it.
I agree it is an ugly kludge; the other proposal I made, sending all the possible suicides @-dest as ["@",dest], and all possible freedrops as [piecelabel,dest] would be cleaner, as these actually are moves recognized by Game Courier. It is just that they are moves that cannot be described by square coordinates. So the existing setlegal system cannot handle these move types. And the current JavaScript would choke on them, as it would try to highlight a square with id '@' without first testing whether that actually exists.
It does have it unless you are using an old browser with inadequate support for HTML5.
Hmm, strange. I am using FireFox, which updates itself almost every other day, and until this morning there never was an auto-complete in Play mode. But suddenly it started to display "Type for legal moves" in the movefield, and now the pull-down menu appears. From the screenshot I made yesterday you can see it did not print that text then. And the strangest thing is that it started doing it without reloading the page: When I pressed Play and got the page for moving in the start position it initially did not print it, and did not show a pull-down menu on clicking. But then I selected a pawn, which made the first part of the move appear in the move field. When I clicked the move field then, I got a drop-down menu with the three possible moves this Pawn could make. But I am pretty sure I was still on the same page.
As you type in a move, it narrows down the list of moves to those that might match it.
OK, so HTML-5 abuses this term for drop-down menus. Anyway, no matter how it is called, as far as I am concerned it is a completely useless feature, always much more cumbersome even than the methods for entering a move by mouse clicks that already exist. E.g. to enter a suicide or a drop as a side effect of an already entered move (i.e. after continuemove), one can use setlegal to send a list of fake moves with the new location of the just-moved piece as origin. (Because I cannot pass '@' or a piece label as origin.) The user could then switch on the higlights by a (logically unnecessary) click on the piece he just moved to switch on the highlights on the destinations, and pick one of the destinations. That would then automatically send the fake move to the server. The GAME code will be aware that it has faked the origin of the move, though, and can use rewritemove to replace it by the piece label (if it was prompting the user for a freedrop) or by @ (if it was prompting for a suicide).
The point is that I want to get rid of that unnecessary mouse click. Not even so much because that reduces the amount of work you have to do to enter the move by another 50%, but because it is a counter-intuitive thing to do, as you don't really want to move that piece, but just want to switch on highlights for destination-only moves. Always automatically selecting the only piece that can move, by embedding the JavaScript code I gave before in the continuemove page, would achieve that. It seems the only method that would allow the entry of the continuation move with only a single mouse click.
I am just using legalMoves as a vehicle to transfer information from the GAME code to the JavaScript in the move-entry pages, because at this point it seems the only way to transfer information that way.
As I've mentioned to you a couple times already, it is no longer the only way. I have created an $extralegal variable for additional legal moves. Besides using this to help populate the datalist for the moves field, I am using it to populate an array currently called legalList to distinguish it from the legalMoves array. This is an array of legal moves as strings of text. I have begun working on modifying movePiece() to make use of it. I am currently working on the version for square table boards. It can handle standard moves without any problem right now, but I am working on getting it to work with non-standard moves, starting with fission moves in Fusion Chess. These moves involve moving a different piece than the one currently on the space it moves away from.
The way I currently have it testing the legality of a move is to make sure the currently entered move is the only match among the legal moves. When I have this working for fission moves, I'll work on offering multiple choices.
I have created an $extralegal variable for additional legal moves.
Well, very nice, but you did not mention it that it would be available in the JavaScript, as legalMoves is. You only mentioned the HTML drop-down. That there will be a JavaScript array legalList is (good) news. Provided it will be accompanied by the JavaScript code to do something useful with it.
In fact the only thing that is still missing in the Applet-generated preset automation is that the highlights in the continuemove screen do not switch on automatically, but that you have to click the piece you just moved for that. That you can switch those on at all is the advantage of presenting the freedrops and suicide to setlegal as fake moves of the piece moved in the previous leg: the standard highlighting code will then provide you a handle to switch on the highlights on all the mentioned destination square. That this finally submits the wrong move can be corrected in the GAME code.
Main remaining defect of the current code is that aliasing piece names breaks the promotion code, because capturedpieces does not contain aliases.
Some irregularities I noticed:
If the last statement in the Pre-Game code has a comment behind it, it totally confuses the GAME-code parser, which starts complaining that the scope goes negative. At least, I think that was the reason. When I removed the comment, the same code worked without problem.
And often I have to save changes twice before they are actually used in Play or Move mode, even though they are saved the first time.
For now, I've switched from working on the square table code to working on the square test code, and I've reverted the square table code to what it was before I began. This will give me more freedom to make mistakes until I get it working.
I suppose that the GAME code runs as part of the PHP script that delivers the Game Courier web pages. Perhaps it would be a good idea to make GAME code support a 'clientinclude' command similar to 'include' (which is a 'serverinclude'), where one could specify a URL? The generated page could then contain a <script src="..."> tag at the bottom of the page referring to that URL. This would offer a way to include JavaScript dedicated to a particular variant, that would not be of much general use.
BTW, if there is going to be a lot of JavaScript in these pages, it would save bandwidth to move it to a separate file (which could be cached, both on Cloudfare and in the user's browser cache), and have the page refer to that file, rather than including it in the (non-cacheable) page itself.
[Edit] Something I noticed: after using the won or lost command a message "<!-- has won -->" appears in the game record. But after the drawn command, it still prints "White/Black to move" there. It does apparently realize the game is finished, because it does stop highlighting moves.
Perhaps it would be a good idea to make GAME code support a 'clientinclude' command similar to 'include' (which is a 'serverinclude'), where one could specify a URL?
It's not a good time for this right now, because new JavaScript is under construction. Also, due to differences in how different rendering methods display boards, there are differences in the JavaScript depending on the rendering method used. I'll try to minimize and modularize those differences as I continue working on this.
I made some progress today. I am working on making the movePiece() function use legalList instead of LegalMoves. I got it to work with Shogi and with viewing games today, and I made a separate showLegal() function for showing legal moves. I'm still having some trouble with properly handling backwards entry of moves.
What would help me out is having access to a game with optional deletions or freedrops. This would help me make sure the code is working properly for those.
As a note to myself, I plan to test this on Go, which I forgot to do today.
What would help me out is having access to a game with optional deletions or freedrops. This would help me make sure the code is working properly for those.
I made two such games (also for testing purposes). Chu-Shogi Lions can optionally capture a piece they jump over, and I used one in Mighty Lion Chess. And in Sandbox I used a piece (incidentally also depicted as a Lion) that (next to being a range-3 Queen) can jump as an Alfil, and then optionally take the piece it jumps over. And the preset for Odin's Rune Chess I just made features a Knight that can optionally take out a piece adjacent to its destination (Forest Ox), and a Queen (Valkyrie) that causes a drop of a friendly piece it captures. (Not optional, but often on multiple possible locations).
These all highlight (pseudo-)legal moves. The executable code for all of those is in the included file betza.txt. I have changed it now to write moves with side effects in the $extralegal array, in the move generation before the move. (I didn't touch it for continuation moves.)
Something completely different:
What would you consider a reasonable execution time for the GAME code in a preset? I tried the stopwatch trick to measure that for my code, and the results were a bit discouraging. I tried full legality checking of highlighted moves, and in the Mighty Lion preset the execution time quickly went up to 4 sec! That seems prohibitively long. If I stick to highlighting pseudo-legal moves the typical time was about 0.4 sec.
One of the problems is that the Lion is a complex piece, which has 88 potential moves: 24 direct leaps, and 64 combinations of a capturing and continuation King step. Unrolling of the loops over directions backfires a bit here, because the 64 two-leg moves have 8 groups of 8 that start with the same capture, and only differ in the second leg. If there is nothing to capture on that square, it is still having to discover this 8 times. More typical multi-leg moves have just one or two continuations, and there unrolling the directional part is a big time saver over having to run some complex algorithm for determining which directions you can continue in. Perhaps I should encode multi-leg moves as a tree rather than a list. Or add some 'skip number' to the list for each leg, that can be used to tell the interpreter "if this leg fails, don't bother to try the next N moves in the list, because these use the same legs up to here". That would reduce attempting the 64 Lion locust captures to 8 tries for the first leg, if there is nothing to capture.
It would of course still all be a waste of time to generate these moves in order to test if they happen to capture a King when it was known beforehand that the King was outside the Lion's range, because the distance was more than 2. A preliminaty test on the footprint of the piece would in most cases relieve you of the task of trying any of the 88 Lion moves in the check test.
A more fundamental problem is that, with fully-legal highlighting, the check test is re-run on every move from scratch, generating exactly the same moves for almost all pieces every time, as the move they want to check the legality of did not have any consequences for them. A much more efficient algorithm would be to run the move generator once for the opponent, keeping track for each attempted move which squares it passed through or attempted to pass through, and for which it would have made a difference what was on that square. (If the leg of the move is both a hop and a non-riding non-capture, (un)occupying the square would not affect the possibility to make it.) To test the legality of a given move you would then only have to try the opponent moves listed for the squares the given move mutated. With only simple riding an leaping moves, this would amount to recording all slider hits (that still have range left) on opponent pieces (that then could potentially be pinned). And when there is a pre-existing attack on the King, recording all empty squares this attack passes through. Moves of pieces that were attacked by a slider would then require re-running of that single slider move that attacked them. And a pre-existing checking move would have to be re-run. (And if the move under test had not landed on one of the squares that checking move passed through, you would not even have to bother re-running it, because it will not be affected, and still check you.) If the re-run opponent move does not capture your King (or, even more frequently, if there is nothing to re-run) the move can be declared legal.
That would take care of all moves except those of the King itsef. To handle those the initial generation of opponent moves could be done without your own King present, and every capture-capable move to an empty square should mark that empty square as being under attack. King moves to a thus marked square are then illegal. Then the entire operation of legality testing all moves would require only a single run of the move generator, with an occasional re-run of a single slider move that hit upon a piece that moved away.
Request to an editor:
I uploaded a file /membergraphics/MSplay-test-applet-for-chess-variants/AppletGAMEcode.txt , and would like to have it renamed to .html (which is not an allowed extension for uploading). It contains a small tutorial on how to make rule-enforcing presets with the Play-Test Applet.
4 seconds does seem a bit long. It seems you have ideas for reducing that time.
Why not just copy your HTML to a member-created page?
Why not just copy your HTML to a member-created page?
I suppose I could do that. But I thought it would be pointless to have it as an independent article; no one would ever get there from the article index, they would not know which title to look for, or even that it existed. If they get there, it would be through a link from another article, e.g. from the Play-Test Applet. So I wanted to put a link to it from there. But you are right, I could of also do that if it was a member contribution. I will do that then.
It would be ideal if there could be a link to it from the GAME Courier page, next to the links to all the other tutorials in the developers section. I noticed your tutorial about the fairychess include file is also not mentioned there. And I couldn't find it through the index either.
4 seconds does seem a bit long. It seems you have ideas for reducing that time.
Indeed, I am working on that. I have been running some timing tests with the stopwatch command, to get a bit of feeling for what would be fast and what would be slow. The method one often uses in engines, to map a pair of squares to a number that uniquely represents the geometry of the leap between them, and then use that as an index in a table to see whether that leap matches what the piece can do, seems to be reasonably fast. Initializing the required table for a 20x20 board with Queen, Griffon and Aanca moves only took 0.08 sec. And calculating the mapping like
set i + 800 - file #origin + file #destination * 40 - rank #origin rank #destination;
needed to calculate the table index took only about 23 micro-seconds. You would only have to do that once for every piece, and a bitwise AND with the value retrieved from the table would for most pieces immediately tell you whether they checked or could not possibly check. Only for quite unusual pieces it would not be conclusive, and the slow method of generating all unusual moves of the pieces, and see if one of those happens to hit the King would have to be used as a fall-back.
For the time being I configured the presets to highlight all pseudo-legal moves.
I made some progress on the highlighting: the execution time of the legality test on all moves is now reduced by about an order of magnitude, typically 0.45 sec for Mighty Lion Chess. (Was 4 sec.) So I made fully-legal highlighting the default now. (Highlighting of all pseudo-legal moves can still be requested by putting set pseudo 1; in the Pre-Game code.)
What I did can best be described as 'incremental check testing'. The problem was that check-testing with potentially weird moves that turn corners and hop over pieces, the only reliable way to detect check is to generate all moves, and see if there is a king capture amongst them. Doing that after every pseudo-legal move, to decide whether it should be highlighted or not, was very expensive. All the more so because the move generator, because it has to be so general, is not very efficient; it is basically an extra interpreted level.
Now I only do such a check test once, in the position before the moves. But it is an 'augmented check test'; rather than just testing if a capture hits the king, it records potential captures (i.e. capture moves to an empty square) in a board-size table, so that you can easily test whether a king would move into check. And it records all rides that could not reach their full potential (i.e. were blocked by a piece before their range was exhausted) in a list for the square where they were blocked. And similarly, it records for each empty square what hopper moves have their pre-hop leg going over them. And if it does encounter a capture that hits the king, it records that move in a list of checks.
With the aid of that information the check test after a move becomes very simple. If a royal moves, a table-lookup tells you whether the destination square was under attack, and if it is, you reject the move immediately. Otherwise, you make the move, but instead of trying all opponent moves to see whether they hit the king, you only try the moves that were recorded for the origin and destination squares. On the origin square the list will contain all opponent moves that were blocked there in the augmented check test, and you re-run those to see how much farther they get now the square is evacuated, and if any of them manages to hit the king now. Most of the time the list is empty, because the moved piece was not attacked by an opponent slider, and in many other cases you just have to re-run one move of one piece (i.e. a ride starting in a given direction).
Similarly, the destination square will list which hopper moves would be activated by putting the piece there as a screen, and these then will also be tried in the reply. Obviously this would never be needed in a game without hoppers. If the move to test for legality is a locust capture, we also re-run the moves that were blocked by the victim (and thus discovered by its removal).
Finally, if the augmented check test finds an actual king capture, it will put that move in a list of checks. The legality test when you have to evade a check will always start with re-running those checks, to see if you have resolved them. Most moves usually won't, so it would be the only reply you have to try in order to conclude you remained in check, and reject the move as illegal.
The current code still takes significantly longer running time when the side to move is in check, but this is not due to the highlighting, but due to the mate test, which still used the old system, which does try all replies to a move. But that stops on the first legal move it finds, which is usually the first move it tries when you are not in check to begin with. But when you are in check it has to try many moves before it hits upon a legal evasion. (And when it is really mate, it would try them all to no avail.) So I think I will replace that test by the new method too, combining the highlighting and the mate test.
23 comments displayed
Permalink to the exact comments currently displayed.
This gave me an idea, which I just implemented. When there is a list of legal moves, it gets used to fill an HTML5 datalist for the text input field used for entering moves. In addition to this, it will include extra legal moves entered as text in the $extralegal system variable. This should include an array of legal moves written as you would enter them, and it may include multi-part moves with parts separated by semicolons. I have not actually tested the use of $extralegal yet, but I have tested that things still work when $extralegal is empty.
This replaces the usual autocomplete functionality with a drop down list of all legal moves. If someone partially enters a legal move, he can get its legal completions. I tried it on both Firefox and Vivaldi. In Vivaldi, it adds a down arrow to the field when you hover the mouse over it, and clicking on that arrow will show the legal moves. Firefox lacks this visual indicator, but if you double click on the field, it will display the list of legal moves.