Comments/Ratings for a Single Item
In modifying the form for customizing the appearance of the board for an ongoing game, all form elements were disabled, and it took me a while to figure out what to do. That clued me in that it wasn't working in an intuitive manner. So I changed how it works. Instead of expecting you to choose the Custom theme before you can change the appearance of the game, any change to a form element for changing the appearance automatically changes the theme to Custom. As long as your theme remains set to Custom, the changes you make will be accepted. If you change your theme after starting to make custom changes, it will go with the theme and ignore the other values you set for changing the appearance. I added fields for choosing the color of Black and White pieces. However, I have not integrated these into themes.
But the anti-aliasing causes pixels on the boundary of the black outline and the colored interior to be darker versions of the interior color, by mixing in the black. So simply looking for an exact match of the original color fails to replace the boundary pixels.
I already took that into consideration.
This problem can be solved, though: you could test every pixel for the value of the brightest RGB component, and deduce from that by which factor it is darkened compared to the interior color. And then darken the replacement color by the same factor.
Here's what I'm doing. I collect all the color indexes. For each color index with a non-zero alpha value, I make a determination of whether it belongs to the outline of a piece or to its coloring. I do that with this conditional:
if (color_diff(array($cv["red"], $cv["green"], $cv["blue"]), $original)
<= color_diff(array($cv["red"], $cv["green"], $cv["blue"]), "black")*2) {
The color_diff function returns the greatest difference between one color's minimum component value and the other one's maximum component value. I added the *2 to prevent some errors, and that part now seems to be working well. If it belongs to its coloring, I recolor each RGB component with this function:
function recolor_component_as ($originalvalue, $currentvalue, $newvalue) {
if ($originalvalue == 0)
return $newvalue;
return min(255,round($newvalue*($currentvalue/$originalvalue)));
}
One remaining problem is that when I try to color the Black pieces white, I get an aquamarine fringe around the Black Motif pieces. In this case, $originalvalue will be 255 for the red component and 0 for the green and blue components, and $newvalue will be 255 for all three components. So, it recolors some edge pixels with positive values for green and blue but with 0 for red, resulting in aquamarine. So, I might have to factor in the value of each component when deciding how to recolor each component. But when I tried that earlier, I got some undesirable results.
But the anti-aliasing causes pixels on the boundary of the black outline and the colored interior to be darker versions of the interior color, by mixing in the black. So simply looking for an exact match of the original color fails to replace the boundary pixels.
I already took that into consideration.
This problem can be solved, though: you could test every pixel for the value of the brightest RGB component, and deduce from that by which factor it is darkened compared to the interior color. And then darken the replacement color by the same factor.
Here's what I'm doing. I collect all the color indexes. For each color index with a non-zero alpha value, I make a determination of whether it belongs to the outline of a piece or to its coloring. I do that with this conditional:
if (color_diff(array($cv["red"], $cv["green"], $cv["blue"]), $original)
<= color_diff(array($cv["red"], $cv["green"], $cv["blue"]), "black")*2) {
The color_diff function returns the greatest difference between one color's minimum component value and the other one's maximum component value. I added the *2 to prevent some errors, and that part now seems to be working well. If it belongs to its coloring, I recolor each RGB component with this function:
function recolor_component_as ($originalvalue, $currentvalue, $newvalue) {
if ($originalvalue == 0)
return $newvalue;
return min(255,round($newvalue*($currentvalue/$originalvalue)));
}
One remaining problem is that when I try to color the Black pieces white, I get an aquamarine fringe around the Black Motif pieces. In this case, $originalvalue will be 255 for the red component and 0 for the green and blue components, and $newvalue will be 255 for all three components. So, it recolors some edge pixels with positive values for green and blue but with 0 for red, resulting in aquamarine. So, I might have to factor in the value of each component when deciding how to recolor each component. But when I tried that earlier, I got some undesirable results.
The original alfaerie set should be considered obsolete now that we have alfaeriePNG, and its use should be discouraged. The anti-aliased version looks so much better. But the anti-aliasing causes pixels on the boundary of the black outline and the colored interior to be darker versions of the interior color, by mixing in the black. So simply looking for an exact match of the original color fails to replace the boundary pixels. This problem can be solved, though: you could test every pixel for the value of the briggtest RGB component, and deduce from that by which factor it is darkened compared to the interior color. And then darken the replacement color by the same factor. (This assumes the outline is pure black.) To make it resistant to multi-color originals you could even check whether the other two RGB components of the original are indeed similarly darkened (within some tolerance for rounding.)
It works with the Alfaerie set. To work, it has to know the primary color of the piece. This is stored in the variable $originalwhite or $originalblack, and the value of each variable must match a color actually used in the image. I have set their values in the main body of the code for Abstract, Alfaerie, Magnetic, and Motif pieces, and I have set their values in individual set files for some other sets. I have thought about adding code that would identify the most common foreground color in each piece image, as it already goes through each image pixel by pixel to get the color indexes, but I'm not sure if this would be appropriate for some pieces, such as pieces with textured coloring from photographs.
Does it also work for the anti-aliased piece sets?
I modified the showpiece.php script to change the color of the piece. This may later be used with the Table and CSS rendering methods to recolor the pieces, and I may modify the pc shortcode to include a color option. Here's a violet King.
I turned the code for recoloring pieces into a function, and I added the ability to recolor pieces to the circular and spherical boards and to the Diagram Designer. But I still need to do some work on the forms.
The recoloring of pieces is working very well now. Even with the Alfaerie pieces, it looks like they were originally the color they were recolored to. For some sets, there are some glitches when trying to recolor the black pieces as white, but that's usually something no one will want to do.
Today I've been working on allowing players to change piece colors when the board is displayed as an image. Recoloring is not available for boards rendered as tables or with CSS. It works best for the Abstract pieces, because they are the simplest in design. It also works for Alfaerie, Magnetic, and Motif pieces, but the greater detail of these pieces makes a perfect recoloring job more difficult. For the new Alfaerie pieces, there is one more issue. It has to convert them into 256 color palette images before recoloring them. So, they don't look quite as good as the unrecolored images. As long as you don't change the color, the pieces will not be recolored, and they will look as they normally do. I plan to work on this more tomorrow, but for now, I have copied my work to the main server to keep it from being overwritten by the backup at midnight.
This is now fixed.
Speaking of 404's, I also get those from the What's New page, specifically the two newest links (Cubic Chess and 3D Chess 4 Cubed). Though they also have the External Link icon next to the name, so perhaps that's related.
I speak of the link with the name of the game which is written just below the diagram in the GC page.
Okay, I changed that to use the $rulesurl variable calculated in the header, which can be different than the value stored in $rules. So, it should work now.
Yangsi, Xiangqi, Glinski's, Gross Chess…
Everything I try doesn't work.
I tried Fantastic XIII, and also Shako and Expanded Chess and the link doesn't work, it always goes to 404. Maybe we don't speak of the same thing.
I speak of the link with the name of the game which is written just below the diagram in the GC page.
It seems like the Rules URL is broken for every game.
I tried multiple presets, including Shako and Expanded Chess, and the Rules URL worked fine every time. Instead of saying every game, which obviously you can't confirm without exhaustive work, tell me which particular presets you are seeing this problem in.
Same observation than Daniel from my side
It seems like the Rules URL is broken for every game. The / at the beginning is removed. I tried fixing it for one of my games and nothing changed.
I managed to solve the King's move display issue by using sub checked cond == #from #king #to #king in the relevant places in the stalemated subroutine. Afterwards it gave a weird error where the King was in check after moving both Kings, but after adding a few lines to force update the k and K variables in the Post-Move sections, the preset is now working perfectly. Thank you for your help.
The problem appears to be that you are not updating the value of k or K when the King moves. This gives inaccurate data to both the checked and stalemated subroutines, which results in inaccurate return values. So, it is an instance of garbage in, garbage out.
In my tests of how intersection works, it will return an associative array when the first array is associative and the second is sequential. It will also treat a variable name as a constant name if there is no variable by that name and there is a constant by that name. So, what I thought were problems with the code might not be.
If the purpose of these intersections is to weed out empty spaces, the same thing can be accomplished more easily with diff noupper @ or diff nolower @.
I notice that your calls to stalemated include two arguments, but only one parameter is defined for the subroutine.
Also, Daniel Zacharias found that if you enter King moves manually, it works fine.
The King's legal moves were highlighted for the first player, but they were not for the second player. After I moved the King manually, it declared check. Considering how your pieces move, this seems inaccurate. All I did was move each King forward to file 6.
He thinks the problem may be in the stalemated subroutine. When I coded this preset, I removed the checkmated subroutine used in my other presets to simplify the code a bit. so that would make sense.
After the two King moves I mentioned, the only highlighted legal moves are to 5j, the space vacated by the King. After each one of these moves, it declared "Checkmate! Black has won!" When I tried other moves I expected to be legal, I could make them, but then it would declare Checkmate again.
Looking at your Post-Game code, I see lines for enforcing the rule against checkmating with a Pawn drop. Code for this should be handled by the stalemated subroutine, because it has to apply to potential moves, not just to actual moves. However, I don't think that code is responsible for the inaccurate estimates of check and stalemate.
Since it declares checkmate only when checked and stalemated both return true, there may be bugs in both, or there may be a bug in a function called by both, such as the definition of a piece move, or there may be a bug in checked, which is also called by stalemated.
Since the checked subroutine shows problems by itself, and it is also called by the stalemated subroutine, it could well be the problem. It works differently than the checked subroutine I have in the fairychess include file. It sets enemies to an intersection between noupper and #bpieces or nolower and #wpieces. However, there are no variables called bpieces or wpieces. There are only constants by these names, and these two constants are sequential arrays. However, noupper and nolower return associative arrays. So, an intersection would not give you the desired result.
I see the same error in your stalemated subroutine. You are trying to find an intersection between an associative array and a variable that does not exist, and the constant with its name is a sequential array anyway.
Sorry about that. Here it is.
Cannon Shosu Shogi on the Chess Variants Game Courier
Also, Daniel Zacharias found that if you enter King moves manually, it works fine. He thinks the problem may be in the stalemated subroutine. When I coded this preset, I removed the checkmated subroutine used in my other presets to simplify the code a bit. so that would make sense.
Posting a link would help.
25 comments displayed
Permalink to the exact comments currently displayed.
I found some functions for converting between the RGB and HSL color spaces, and using them got rid of the problems I was having with making the Black Motif or Magnetic pieces white. However, using them to make the Black Alfaerie pieces white would turn them grey, and trying to make White pieces grey would leave them white. To avoid these problems, I had the function choose between the old RGB recoloring method and the new RGB->HSL->RGB recoloring method based on the relative luminosity of the two colors and on whether it was converted from a true color image. If the new color has a higher luminosity, and it was not converted from true color, it will use the new method. Otherwise, it will use the old method. In my tests, this seems to be working out for the Abstract, Alfaerie, Magnetic, and Motif pieces.