Ratings & Comments
With the current coloring scheme it is very hard to distinguish occupied squares from empty squares; the pieces blend in too easily with the bright square and arrow colors. I would recomment to decrease the saturation of all the board colors by at least 50%. E.g. by giving the image a 50% (or even 70%) transparency and have a whitish background shine through.
Maybe it is better if I explain what I want to do.
So there are these two pieces (in position 12 and 13):
lightcannon:X:mRcpR:cannon:a4,n4,,a11,n11
heavycannon:Y:pRpafcpR:warmachine:a2,n2,,a13,n13
The rule I want to implement is that heavy cannons cannot jump, be jumped, captured or be captured by other cannons. My captureMatrix looks like this:
captureMatrix=////////////11$$./11$$./
but probably I got it wrong.
Note the heavy cannon is a bit more than a korean cannon is as it can jump two platforms in order capture, but not move.
can you castle through attacked square if you still have another king
Rocket, which is square interpretation of Zip on cluster cell in Rocket Chess, which is mentioned earlier, moves as following:
In other words: forward Rook, forward sidemost Zip, backward narrow Electrician.
Otherwise it has a simpler version which is forward Rook, backward Bishop and forward sidemost Nightrider:
Zombie Pawn: Moves (with capture) one space directly or diagonally forward, or moves without capture one space directly behind. Any piece that captures it and stops on its square immediately becomes a Zombie Pawn (but doesn't change color).
I clarified this, essentially the same way but expanding a bit more.
I'd love to make the Reaper and Mummy also immune, and there's probably some way of doing that, but I'm not sure what. If there is, maybe H.G. can chime in to help.
I guess the Vulture's move description isn't too problematic, except that the ID move does not match up with it. It should be mHnFXnNY.
Well, that's definitely a "kink." I think I miscounted or something. I changed the ID move as indicated.
I think the piece is an invention of Lev's; if it's the description that should've been changed, hopefully he'll speak up.
Aand you've rederived these pieces as a back‐formation ;) These are the original (long‐ and short‐, respectively) non‐helical switchback rhinos as proposed by Gilman (and independently by KelvinFox).
Actually never mind, these are two of Gilman's four: Long‐switchback Rhino and Short‐switchback Mirror Rhino. The other two move the same but with the non‐alternating step first.
Note incidentally that Gilman's ‘rhino’ is this one (specifically the sliding version), not the (modified) GA one as popularised by Jean‐Louis (hence why both forms are referred to by that name). The fact that both begin W
‐then‐F
is coïncidence
Also (belated) Happy Birthday :)
Since this comment is for a page that has not been published yet, you must be signed in to read it.
The first position in each row is for the non-capture. So if the Cannons are number 12 and 13 in the table, the Cannon x Cannon indications would need to be in the 13th and 14th element of the row. So 12 'nothing special' positions in front of them.
There is no row for empty squares, as empty squares cannot be moved. So you would have to specify this in the 12th and 13th row of the matrix. But it seems you are doing it in the 13th and 14th.
I think the [vulture] is an invention of Lev's
I thought it was from Aurelian's Grand Apothecary Chesses?
This seems like a really cool idea from the late Problemist
As far as admin is concerned, I assume it desirable to have a link to this as Kazan Chess (the original name), and to credit Grolman as the inventor? Since it looks like you've done a bit of filling in the details, it's at your discretion whether you wish to take coïnvention credit.
Since it originates as a problem theme, two further questions arise:
- How does it actually play as a game? I imagine it's very different in flavour from Orthochess but I wonder whether it might tend to be a bit chaotic.
- Would it be worth including a problem or two on this page? I don't know if there would be copyright issues with including the original 1995 Problemist composition, but your Mate in 2 is pleasantly illustrative
I imagine there are more interesting ways to resolve the Castling issue than simply disallowing it outright (other pieces either have to fill both vacated squares where possible, or just the king's one as Castling seems to be a K
move by problem convention (see the discussion of Half‐Neutral pieces in the same Problemist issue), and we could consider a K
or R
unmoved if it has only moved involuntarily), but this solution works too
Since this comment is for a page that has not been published yet, you must be signed in to read it.
I thought it was from Aurelian's Grand Apothecary Chesses?
It could well be. My memory, as I've stated many times, is pretty wretched.
Also (belated) Happy Birthday :)
Thanks! :)
Since this comment is for a page that has not been published yet, you must be signed in to read it.
Since this comment is for a page that has not been published yet, you must be signed in to read it.
So I would suggest a compromise between your quick method and your reliable method. Flag pieces that can capture a piece without moving to its space, and use your reliable method on these while just checking if other pieces can move to the King's space.
I think I managed to even use some acceleration for the pieces that can perform 'locust capture', by avoiding you have to generate all their moves, and just limit it to moves that could potentially hit the King. This would be the move that already delivers check, and the moves that that mutate a square along the path in a way that would allow a slider leg of the locust capture to pass. Which is what was already done for direct captures too.
The issue was that the test for being already in check was done with the King taken off the board, by comparing the destination of capture-capable moves with the King square. But this was tested only on a final leg, and not for a non-final leg, where the capture would be a locust capture, and the piece would move on after it. I now compare the (temporary evacuated) locust square with the king position too, and if it matches make the move go over to the next leg to see if it can be completed. (For an Advancer that would always be possible, but a Long Leaper it might not be.) If the move can be completed, the locust square would be marked as attacked. This will then make the 'check' message appear.
But more importantly, squares on the second leg would also get marked as squares where a check could be discoved. This was a bug that did not yet express itself. A Checker diagonally adjacent to the enemy King would not deliver check if a friendly piece was immediately behind that King, blocking the landing square. But that blocking piece would then essentially be pinned, and its moves should not be highlighted. The accelerated test would only have noticed that if the second leg of the Checker capture would have added that Checker capture to the moves affected by mutation (= evacuation) of that landing square.
Oh, a silly trivial mistake on my part. Thanks!
The issue was that the test for being already in check was done with the King taken off the board
Why would you take the King off the board for this? Couldn't this cause false positives and false negatives from divergent pieces like Pawns or Cannons?
This was a bug that did not yet express itself. A Checker diagonally adjacent to the enemy King would not deliver check if a friendly piece was immediately behind that King, blocking the landing square. But that blocking piece would then essentially be pinned, and its moves should not be highlighted.
The code I use avoids this by trying each pseudo-legal move and checking whether any piece in the new position is checking the King.
Why would you take the King off the board for this?
The purpose of the accelerated check test is not only to determine whether the King is in check in the current position, but also to greatly facilitate testing whether the King would get exposed by any of the moves. One contribution to this is to mark every square where the King itself cannot go. The King is taken off to prevent it would block enemy slider moves (or lame leaps), creating the illusion that it would be safe to "step into his own shadow".
The test is NOT done by only processing all pseudo-legal moves. Because that would not reveal which pieces are protected (and thus cannot be captured by the King). For the purpose of knowing where the King could go the move generator should basically work under the fiction that all destinations contain the enemy King. That applies to empty squares as well friendly pieces; these will be marked as inaccessible to the King when the move hitting those is a move that can capture. Even when it cannot capture what is actually there.
The code I use avoids this by trying each pseudo-legal move and checking whether any piece in the new position is checking the King.
That would indeed be an alternative: do a full king-capture test after every King move. But it would be more expensive, as a King usually has several moves. So you would have to do enemy move generation several times. (And who knows how mobile a royal piece can be, in a chess variant?) Testing whether a destination contains the King is not any more expensive than marking the destination. And to do it, you only need to geenrate all enemy moves once. Then for each King moves only have to test whether the destination is marked. And to know whether you are in check it would just have to test whether the square the King is currently on is marked.
But the fiction that every square where you are allowed to capture contains a King should also be applied to locust captures. And this wasn't done.
The accelerated check test would not work in variants where there are multiple absolute royals. (Extinction royaly is no problem; there it just skips the check test completely if there still is more than one royal.)
That would indeed be an alternative: do a full king-capture test after every King move. But it would be more expensive, as a King usually has several moves.
It's more than that. I do a full king-capture test for every pseudo-legal move by every piece that can move. My code works like this.
- It goes through every piece from the side that can move.
- For each piece on the side that can move, it calculates the spaces within its range of movement. This is an optimization to keep it from checking for legal moves to every position on the board.
- For each space within a piece's range of movement, it checks whether the piece has a pseudo-legal move there.
- For each pseudo-legal move, it tries the position and checks whether it places the King in check.
- It checks whether the King is in check by checking whether any enemy piece can move to the King's space. As an optimization, it returns true as soon as it finds one check.
- It checks whether a piece may move to the King's space by calling its function for the move from its location to the King's space.
- Divergent pieces are handled by writing them to behave differently when the movetype variable is set to CHECK. In the following example, the function for the White_Pawn first checks some conditions any Pawn move must meet, then handles capturing, then continues to handle non-capturing and en passant moves only if movetype is not CHECK.
def White_Pawn
remove var ep
and < rankname #1 var bpr
and < rankname var ep rankname #1
and == filename var ep filename #1
and checkleap #0 #1 1 1
and var ep
or and checkride #0 #1 0 1 == rankname #0 var wpr
or checkleap #0 #1 0 1
and empty #1
and != var movetype CHECK
or and islower space #1 checkleap #0 #1 1 1
and any onboard where #1 0 1 == var movetype CHECK count var wprom
and <= distance #0 #1 var fps
and > rank #1 rank #0;
- Pieces with non-displacement captures are handled by writing two different functions for them and using the value of movetype to call the correct function.
So you would have to do enemy move generation several times.
Since my code uses piece functions, this is not a big problem. In tests I ran yesterday, my checked function ran 1000 times in under half a second, and the checked subroutine got called 1000 times in close to a second, and this was on a position in which the King was not in check, which meant it never broke out early. Since your code does not use piece functions, it may handle the evaluation of moves more slowly, which will also cause it to evaluate check more slowly.
Testing whether a destination contains the King is not any more expensive than marking the destination. And to do it, you only need to geenrate all enemy moves once.
This optimization might be helpful when not using piece functions, but one thing about it concerns me. While it might be helpful in determining whether a move by the King would be into check, I'm not sure it will work for revealed checks. It is because of the possibility of revealed checks that my code checks for check for the position resulting from every single pseudo-legal move it finds.
I suppose one optimization that could be made if it were needed would be to identify the pieces that might possibly check the King at its current location, then limit the test for whether a move by another piece places the King in check to those pieces. This could be done by making a short list of every enemy piece whose range of movement contains the King's location and having the checked function use it instead of onlyupper or onlylower. If this list were empty, it could even skip the step of trying out a pseudo-legal move and testing whether it places the King in check.
However, this might not work for non-displacement captures in which the capture occurs outside the piece's range of movement, such as the Coordinator capture in Ultima. So, I have to balance efficiency with the work a programmer has to make to use a piece in a game. The brute force method I use helps reduce the work the programmer has to do to make different kinds of pieces work with it.
Here is a link to Grolman Chess on Wikipedia (in Russian) https://ru.wikipedia.org/wiki/Сказочные_шахматы_Грольмана
As you can see there is only a meager description of Grolman's main idea.
To get a playable version of the game, I had to slightly expand the rules regarding check and checkmate. It would not be entirely correct on my part to take credit for co-authorship, because the rules that I described here and on chessdotcom follow from pure logic.
Regarding castling. It is not prohibited, but simply impossible. During the game there cannot be a situation where there are no pieces for castling between the king and the rook. The chess pieces are in a constant state of movement. Either the king or the rook will definitely make a move by the time the opportunity for castling arises.
You ask, "How does it actually play as a game?" The game is absolutely playable and is not chaotic at all. The fewer chess pieces left on the board, the more the game leans toward classic chess, while retaining a little of the magic from the chain reaction of chess pieces moving.
I don’t know whether it’s worth including Groman chess problems in the description of the rules. Perhaps just a link to The Problemist or to my blog on chessdotcom is enough.
5. It checks whether the King is in check by checking whether any enemy piece can move to the King's space. As an optimization, it returns true as soon as it finds one check.
The efficiency of your algorithm depends on whether there is a fast method to answer the question "does the piece at square A attack square B", which then can be combined to a function "IsSquareAttacked" by looping over all pieces A. But for complex multi-leg moves (pieces that turn corners, or jump over others, or do not end their move at the square they attack) it is hard to find a shortcut even if you are writing dedicated code for it. Often the best way is to just generate all moves of the piece at A, and for each of those test if it happens to hit B. For simple sliders and leapers it would be possible to immediately exclude they are attacking B based on the (x,y) coordinates of the leap from B to A (e.g. x*y!=0 for a Rook), or even tabulate in which direction you would have to move to arrive at B (and then test whether this path is unobstructed).
I could of course classify pieces (or even their individual moves) as simple or complex, and use a fast "does A attack B" function for leaps and straight slides, and only generate the complex moves of all enemy pieces to test whether these hit B. Typically only a small fraction of the pieces will have complex moves, and then this could be competitive.
This optimization might be helpful when not using piece functions, but one thing about it concerns me. While it might be helpful in determining whether a move by the King would be into check, I'm not sure it will work for revealed checks. It is because of the possibility of revealed checks that my code checks for check for the position resulting from every single pseudo-legal move it finds.
Marking of attacked squares to weed out illegal King moves is just one of the two things the accelerated check test does. The other thing is that it tabulates for each board square which (attempted) sliding moves visit it. If such a move did not hit B before, it cannot hit B after a move that would not mutate at least one of the squares that the move visited. E.g. if a Cannon is looking at the King directly it would not check, but during move generation the first leg of the move in the direction of the King would have been attempted, and perhaps even succeeded by capturing something that was behind the King. But whether it succeeded or not, all the squares between Cannon and King would get this Cannon move added to the list of moves that visit them.
If the move to be tested for legality would land on an empty square between Cannon and King, it would see in the constructed table that there was a Cannon that had a move that went over the destination square, and thus will be affected. It will then retry that move of that Cannon, to test whether it hits the King in the new position. Likewise, it would see whether (say) a Bishop had been attacking its origin, and then rerun that Bishop move to test whether it hits the King. This takes care of discovered slides and hopper activation. Moves of other pieces, as well as other moves of these same pieces would not have to be tried; these were not hitting the King before, none of the squares they visited was mutated, so they won't hit the King now.
This is actually the most robust part of the algorithm, which would even work in case of multiple absolute royals: moves that were not checking before cannot check after a move that did not mutate any squares in their path. (But if there are Immobilizers...)
In general the algoritm is very fast: for each move with a royal you test whether the destination is marked as attacked, and for moves with non-royal pieces you only have to rerun the opponent sliding moves that were tabulated as hitting origin or destination (and occasionally other squares that were mutated). And on average there are fewer than 1 enemy sliding moves (i.e. moves that could potentially have continued if the occupancy of the square had been different) to a square, in a typical variant. So in many cases a pseudo-legal move can be accepted as legal by just concluding that the mover was not royal, and the origin and destination of it were not visited by any opponent move. When already in check, it always reruns the move that was delivering that check, as the first test. (Most moves would not resolve the check, and these can then be discarded without further testing.)
Anyway, it is possible to configure the preset to not use the accelerated test, and for a not-too-lage variant (8x8 or 10x10) this will probably work fine.
24 comments displayed
Permalink to the exact comments currently displayed.
I think it would be good to have no background color at all for <tr> elements. I see no legitimate use for it. If it is desirable to see the background color of the page for <table>, <tr> or <td> elements, they could simply be transparent. Then the page background would shine through. If it is desirable to have a color for table cells that is different from the page background, then this should be specified for the <table> element, and the <tr> and <td> cells can be transparent to show that color in every cell. This way it is prevented that background colors of a foreground element would cover/hide non-default changes made in the elements behind it.
I guess that 'inherit' is not a sensible setting for elements like <td> and <tr>, which always have a <table> as (grand-)parent element. Because these would automatically get the color of the parent by being transparent. Inheriting the color just causes problems by eclipsing any background-image of the parenet element; it allows the background-color of the parent to sneak in front of its background-image.
In the I.D. I made the cells transparent by specifying an empty string for lightShade and darkShade. This worked, but I don't know if it is the official method (and thus whether it will always keep working). I now learned that in general (semi-)transparency can be set in HTML by using a notation
rgb(R G B / A%)
where A is the opacity (100 = opaque, 0 = fully transparant). Perhaps I should make the Diagram script recognize the empty string as a color spec for the square shades, and replace it by rgb(0 0 0 / 0%).