Comments by HGMuller
The way I had in mind for indicating illegality of pseudo-legal moves in the NewClick highlighting routine was to make each move, and then generate all replies, and determine their scores. A king-capture score (15000) amongst these replies would mean the original move was illegal. This would then cause the grey cross to be used to highlight it.
It would be nice if we could add a gray highlight for the illegal Lion trading moves for the Chu diagram on this page, but I am not sure how to go about doing that.
If it was easy I would already have done it...
The AI already pays attention to the Lion-capture rules and other legality issues, so the easiest way is to reuse the AI components. When using the NewClick() move entry routine the entered moves are already performed by the same routine NewMakeMove() as that the AI uses.
The AI uses a recursive routine Search(), which uses the move generator GenAll() to create a move list for the side that is on move. It then loops through the moves in that list to find the best/a satifactory one. To do that it first evaluates the direct gain of the move, through a routine ScoreMove(). This calculates the value of what the moves captures, checks if it destroys opponent or own royalty, and adds some info to the move that was not in the 'raw' moves coming from the move generator. (Such as identifying pieces that have to be burned, and remembering the original occupants of mutated squares, identifying the pieces that are made temporary royal or iron by the move and adapt the score for moves that capture those.) After 'cooking' the move with ScoreMove() it can be applied to the current position by NewMakeMove(), and later taken back with UnMake();
Both GenAll() and ScoreMove() make use of the preceding ply, e.g. to generate e.p. captures, and applying trading restrictions.
Currently NewClick() uses GenAll() to create the list of pseudo-legal moves, and then uses mouse clicks to eliminate those from the list that would not be indicated by those, until a single move is left. This raw move is then cooked by ScoreMove(), and performed by NewMakeMove(). As long as there are still multiple moves in the list, the squares corresponding to the next click these need to be selected will be highlighted.
To do fully legal highlighting we would have to make every move, and then judge the position based on the possible replies in the resulting position. Not just the one that is finally selected. That means that ScoreMove() will have to be applied to each of the moves. So the call to it should be moved to within the loop that selects the moves to be highlighted. And then there should be a NewMakeMove(), GenAll(), {judge}, UnMake() sequence in that loop as well, where the 'judge' part would apply ScoreMove() to all replies, to see if there is an instant win amongst those (which then would make the move to be highlighted illegal). If there is the grey cross should be chosen as highlight marker.
Since this comment is for a page that has not been published yet, you must be signed in to read it.
I think I managed it! There were all kinds of problems, because ScoreMove() only work if the AI tables (such as piece values) are initialized. Which only happened when you actually started playing against it. Otherwise it returns undefined results when pieces get captured. And it was not only that the tables needed to be defined; they actually had to contain the correct values. Otherwise the bridge-capture rule could not be correctly applied.
But I think it works now: pseudo-legal moves that the AI would consider illegal are now highlighted with a grey cross. This applies to intrinsically illegal moves (blowing up your own royal, capturing an iron piece or making a counter-strike) as well as to moves that can be punished in the reply (exposing your royal to capture, or capturing a protected Lion).
In the Chu-Shogi Diagram there are no restrictions on royal exposure, as it specifies royal=100, but as far as I tested the Lion-capture rules are now correctly indicated with the highlights.
Note that you declared the Pawn royal in your Diagram. (Holes are not counted; they do not appear in the table.)
Ummm... I intentionally implemented the counterStrike ban to declare a particular type 'temporary iron', rather than just any type that has the counterStrike property. This to allow multiple types to have it. This appears to backfire in case Ln and +Kn are defined as different types. The other cases I will examine tomorrow.
We should see here what the AI does, so we are now debugging the AI...
There are several ways to cure this. The simplest would be to switch to making all types with the counterStrike property temporary iron after one of those is captured by a piece without this property. A more subtle (and more versatile) approach would be to assign piece types to 'groups', and make all types in the group that was captured temporary iron. This could be done by introducing a parameter group=N, which would then put pieces of that type in group N. (With as default every type being in a group of its own, so that in Chu Shogi only the +Kn would have to be assigned the type number of the Lion.)
I could also use the counterStrike parameter itself for this, giving it a different meaning when used after pieces have been defined: currently counterStrike=N would endow type N with the property, but after a piece definition it could assign the preceding type to group N. This method is already used for antiTrade (which defines relative ironhood), so it might be the best solution.
All problems you pointed out should be solved now. (Thanks for finding those!)
The problem with promotable pieces was caused by promotion scoring to take place after royalty checking in ScoreMove; because of that the 'immediate loss' score of -15000 was increased by the promotion gain, and no longer recognized as such. It should have returned the losing score immediately when it was found. (This should not have hurt the AI very much, as the score would still be extremely low, so that it would only count on the forbidden move in positions where getting checkmated was the only alternative.)
I implemented type groups for counter-striking, assigned by counterStike=N behind a piece type that should be added to another group N than its own type number (and added that behind the Kirin to map it to the Lion's type, N = 20).
The problem that the final victim of a double capture was not noticed as having to be declared temporary iron, is solved in a fragile way: ScoreMove was adding the anti-trade codes of all victims, and (if one of those was subject to a counter-strike rule) would then check the type group of the last-handled victim (the locust victim) to see if it belongs to the temporary iron type group. I now added code to test whether this victim actually has the counter-strike property; if not, the other victim must have been responsible, and it substitutes the replacement victim for it before doing the type-group test. This solves the Chu-Shogi case, but could fail if there are more than two victims, if there are two locust victims, or if both victims have the counter-strike property, but belong to a different type group. (And there is currently no method for declaring more than one type-group temporary iron.)
I also fixed the moving into check highlighting; I had forgotten to call CountRoyals() in the betzaNew.js here on CVP.
I must admit that it appears to work, but it should count as heavy abuse of XBetza notation. (Which is used to define all moves with detours to measure the location of the piece.) But it is true that the more conventional solution, of morphing th epiece to a type that has the proper moves on the square where it lands, is also no joy, because of the large variety of squares, and the huge number of types this would require. There must be more convenient methods of handling variants of this type...
OK, I solved the 'promoting Kirin' bug. This was due to the AI comparing the capture square with the origin of the previous move, rather than the destination.
The adjacent case is partially due to a 'calculated risk': the exemption of adjacent Lions from the protection rule is motivated by the fact that you would never want to capture a protected Lion by replacement if you could capture it throug hit & run. Making the same exception for a piece not capable of locust capture makes no sense. To make the rule also useful for such pieces, I dropped the adjacency condition from the implementation of the rule in the Interactive Diagram. The AI might erroneously believe it was illegal, but it would virtually never want to play it anyway. And when the highlights were still only pseudo-legal, it would not make any difference there either.
The other part of the problem might be solvable in the highlighting: even though it thinks the replacement capture is illegal, it thinks locust capture is allowed, so there also is a cyan start highlight on that square. (Which overrules the red triangle for the direct capture because of the order of these in the XBetza spec.) I guess I should in any case refrain from overruling the star marker by a cross. The cross then would still appear in the highlights for the second leg, for the click that would select termination after the first leg, though. But that is the move you would almost never want to play, so this might be excusable. After all, moving the King in check is also highlighted by a cross now, and that is not strictly forbidden in Chu Shogi either. So the meaning of the cross should be taken a bit liberally, as 'not recommended', rather than strictly forbidden.
The third case was due to forgetting to strip off the color bit when looking up the anti-trade properties when testing whether the replacement victim had to be replaced by the locust victim when setting the temp-iron type.
Well, move sets are 1-on-1 associated with piece types. So if a square must somehow affect the move, it must affect the type. I suppose that it could be called a property of a square how it would change one piece type into another, and such a property can be assigned by the 'morph' parameters for each piece type, which for each (type, square) combination defines the type that would result from a piece arriving there.
The way how piece types (repeatedly) change into each other defines a network, and this network can consist of a number of disjoint sub-nets. Such a sub-net could then be considered a 'meta-type'. If the sub-net has the property that every closed path that brings you back to the same square results in the same type, the meta-type could be considered the same piece moving differently depending on where it stands. In other cases it would be considered a promotion. E.g. a Pawn can reach last rank, promote to Queen, and then return to its starting square as Queen.
A trivial case for a meta-type always manifesting itself as the same type on a given square occurs when all types that belong to the meta-type morph to the same type on arriving on that square. This is the case we have here. Currently it would have to be defined in the I.D. by explicitly defining all the types, one for every possible move set, and then for each specify the same morph parameter to indicate how they change into each other. This is a bit repetitive, and you might easily run out of letters to designate the types.
Perhaps it should be possible to define meta-types directly, by allowing a piece definition (which now consists of name, ID, image, move and starting squares) to contain not one, but a list of moves. For each move a type would then be created, but all these types would have the same name, ID and image. Such a meta-type definition could then be followed by a morph parameter to indicate which move from the list should be used on which square. E.g. by designating the moves in the list by a single letter a, b, c, ..., and using these letters in a FEN-like string for associating squares with the moves of the preceding meta-type definition.
Well, what's in a name? Whether you call the entire set of possible piece incarnations the piece type, and the sub-set of those incarnations on squares with identical 'properties' a sub-type, or call them meta-type and type, respectively, as I did below, doesn't change what they are and how they behave. We could also have called them macro-types and micro-types, which is pehaps even a better terminology. Normally every macro-type consists of just a single micro-type, so we don't have to make the distinction, and call them both 'the type'.
The Xiangqi Pawn can both be considered a single type, with a move dependent on which side of the River it stands, or a piece that promotes to a new type when crossing the River. These are fully equivalent descriptions, because the network of (type, square) transitions trivially satisfiies the condition that no closed loop alters the type, as the move confines closed loops to a rank. I would't say any of those descriptions is not in strict alignment with the rules.
I admit that having to define a huge set of micro-types with the same image in a Diagram definition is cumbersome and looks kludgy, leading to an ugly and bulky piece table. This is why I suggested to make it possible to define a macro-type in a single piece line, using a list of move descriptors (e.g. comma-separated) rather than a single one. But one would then still have to specify which move applies where (i.e. the micro-type taken on by the macro-type on each square). If they all use the same piece ID this cannot be done through a (board-size) array of piece IDs, as the currently implemented morph parameter does. But this can be solved by introducing a new parameter microTypes, which refers to the moves in the macro-types move list, e.g. through single-letter codes a-z.
The same shorthand notation could be used for the value of this parameter as is now used for morph: incomplete ranks could be completed by repetitions of the given part, and a special symbol for 'same as previous rank' or even as previous two ranks could be defined, while entirely missing ranks could default to the first move in the macro-type's list. That would reduce the definition of the Xiangqi Pawn macro-type to a move list fW,fsW and a following microTypes=b/b/b/b/b for the furthest 5 ranks entirely filled with b = fsW.
For a board as irregular as Storm the Ivory Tower there would probably be no shorthand, and all 90 squares would have to be specified. All macro-types are likely to require the same microTypes array (if you properly order their move lists), though. So it might be useful to also have a shorthand symbol for 'same value as for previous piece'.
True, a special 'inherit directions from square' modifier (say '?' as 'a' is already taken) would allow a very elegant move description in Smess-like games. But that is really a very specific case. In Elk Chess the Elk moves as a Rook or as a Knight, depending on the color of the square it is on, and the square property would have to encode more than just a direction. A Querquisite moves as the piece that started in the rank it is in, so it can move like many different pieces. Gerd Degens has recently submitted many variants that have location-dependent moving: Avatar, (where there is only one type of piece next to the royal King, which can move like any orthodox Chess piece in a pattern that is scattered over the board), Bull's Eye (where pieces in the 4 central squares move as Amazon). He also had a variant (I forgot the name) where on some squares pieces keep the move of the square they came from. This is an awful lot like promotion, as on the same square a piece could now have different moves. So the move the pieces have on a square can no longer be a square property.
In Kyoto Shogi the piece type toggles on every move, with as a result that you often reach the same square in either of the two forms, or return to the same square flipped. So the move depends on history rather than on a square property. But the move change does not have the permanence we associate with promotion. A mapping (micro-type, square) -> new micro-type can still perfectly describe all the mentioned behaviors. In micro-Shogi the pieces only flip when they capture, so there a mapping (mover micro-type, destination square, occupant thereoff) -> new micro-type is needed. But that is a very poweful way of describing things. For a given square that mapping of (mover micro-type, destination occupant) -> new micro-type could be considered a (rather complex) 'property' of that square.
I don't think that 'conceptually' really means much. As far as I am concerned game rules are an abstract mathematical concept: a set of game states acting as nodes of a directed graph that indicate the legal transistions between one game state and another. Where the game states imply the player who is going to decide which of the legal transitions out of the state will be taken, and game states without any exits are labeled with a game result. Any verbal description that unambiguously defines this graph is as good as any other, and concepts like turn, piece, move, cell, type are not more than personal preferences of the person or machine learning the game, to help him remember and apply the rules. Often different concepts are just rewording the same thing. One could for instance call micro-type also 'current move set of the piece', and it might sound much less abstract to some.
Haru's Diagram doesn't implement this game by change of piece type. It gives the pieces the same move set everywhere. But with moves that are making such complex detours that the unwanted moves will not be possible because they stray off board at the wrong step along their trajectory. This makes the move descriptions in the piece table totally uninterpretable for humans, and the I.D. thus a failure as an aid for explaning the rules. One can say that the program here uses the concept of pieces with a fixed set of very complex detour moves. For this game this seems a very cumbersome way to think about it, and it is hard to imagine that a human would be able to understand it, let alone prefer it.
But that is not the case for all games that can have different conceptual interpretations; for Xiangqi it makes very little difference in conceptual complexity whether you consider the Pawn to have a location-dependent move set, or that it promotes to another type on crossing the River. It probably depends on the player's background; Chess players are used to promoting Pawns, Smess players will be used to location dependence. Shogi players will be used to the concept of pieces having an 'internal state', and are more likely to see even promotion as merely a different micro-type of the same piece, which is the physical tile that can get flipped.
I only entered this dscussion to investigate whether it wold be possible to base an I.D. on a concept that is more useful for humans than the detour moves, so that it could not only play by the rules, but actualy present those in a helpful way. At least the concept of type change on arrival on each square would cause a more intellegible presentation of the moves (which would become the usual leaps and rides, rather than detour trajectories that stray over the board edge). The disadvantage in this case would be that it involves so many different types.
I think you are mainly turned off on this conceptual interpretation of the rules by that I happened to call these 'types'. But it is really not different from what you describe, that the same piece acquires a different set of moves when it lands on a square. The only difference is that what I called micro-types you call move set. But that is not a conceptual difference, it is just different terminology. Smess (as well as Xiangqi, Elk Chess, Avatar and Bull'sEye) happens to be a game where the current move set of a piece is completely determined by the square it last landed on. Chess promotions do not have that, and we tend to think of the pawn becoming of another type. (Even though in over-the-board Bughouse rules it retains the physical shape of a pawn, and players just have to remember how it moves.) In Shogi it is most clear that the same piece can have two different micro-types/move sets.
The I.D. currently only understands piece types as move sets/micro-types, and lists every micro-type as a different entry in the piece table, with its own fixed move set. For a Smess implementation using the micro-type concept that would give a very lengthy table. (But with simple moves.) It gives little indication which of these micro-types are just different move sets for the same macro-type. So I think it would already be an improvement if it would represent the macro-types as single entries in the table, and allow those to be defined as a macro-type (with multiple move sets) in the Diagram definition. E.g. for Elk Chess we could define
elk:E:R,N:pegasus:a1,h1 microTypes=ab/ba/"/"/"
(where ab expands to abababab to fill the rank, and the double quotes repeat the previous two ranks). That is simple enough, but the problem with Smess is that you still would need a quite long list to describe how, say, a Numskull could move on all the different squares. The number of move sets could be reduced by realizing that many are merely different orientations of others, but that would be hard to exploit, as you still would have to specify somewhere what orientation applies where. And it is very specific to Smess, where the location affects only the allowed directions of the move. So it would be something you would do in a dedicated Smess (or StIT) program, but not be generally useful enough to make it worth implementing in general-purpose chess-variant software.
The issue is that Smess is really a game with very complex rules (which only becomes a problem if you want to express those in a simple way). The way you programmed it also requires an array of 90 8-bit numbers describing the square properties. For humans these properties are given through a picture of the board (so they won't even have to memorize those), and as we know a picture paints a thousand words. Computer programs cannot read pictures, though, so there we have to supply the thousand words...
Your solution can be so convenient, because it is a dedicated program for Smess, and thus can exploit some properties that are peculiar to Smess. Namely that the piece location only affects the directions you can move in. That would not hold for, say, Avatar, where the range and the move step are determined by the location, rather than the direction. Of course you could make a dedicated solution there too, where the square properties specify whether the move is N, K, R, B or Q.
In general what one would have to supply is a move set for every square, and that for every piece type, as not in every variant we will be so lucky that Numskulls and Ninnies on the same square must also move in the same directions. Specifying an array of 90 'direction sets' will be hardly less effort than giving 90 full Betza specifications of the move sets; exploiting that only the direction set is determined by the location allows you to omit the atom from the Betza descriptor, but that is just a single letter, while specifying the direction set will usually require several letters.
If one includes the specification of the board properties your GC solution is not so convenient at all, because each of the 90 properties requires a multi-character definition, hardly shorter than a full Betza move specification. For humans this complexity is hidden by painting this information in graphical form on the board.
It would be easy enough to allow specification of a location-dependent move in the I.D. by supplying a comma-and-slash-separated list of Betza move descriptors in a FEN-like organization, one move descriptor for every cell of the board. One could even use the short-hands discussed earlier, so the move of the Elk could be written as R,N/N,R/"/"/" instead of supplying moves for all 64 squares, but for Smess that would offer no relieve.
Space attributes are supported in the I.D. through the morph parameters that can be defined for each piece. These can specify all properties a piece type can have in a square-dependent manner. But it specifies these properties by a single letter, namely the piece ID, referring to a type-definition line that assigned this ID. This is in general more efficient, because usually many board squares would have the same properties, and repeating the full description of those properties for all of those would make the Diagram definition needlessly verbose.
One might argue that the Diagram's type definitions also specify image and name, and that these should remain the same on all squares, and thus are now needlessly repeated. But this is debatable. E.g. in Elk Chess you could specify piece names in the two required Elk types (with N and R move, respectively) as 'Elk (on dark)' and 'Elk (on light)'. This would be of significant benefit to the user, as he can now consciously summon move diagrams for either case. Having only a single entry for the Elk would raise the problem which move Diagram you would have to show, and would not make the user aware that the Elk would move completely differently elsewhere. And I definitely see some benefit to have a piece table with the Smess Diagram that would have a number of Ninnies, called 'Ninny (on e1,e4,e5,e8)', 'Ninny (on c4,c5,g4,g5)' etc., so he could summon all possible move diagrams for a Ninny. The only disadvantage I see is that the existing morph parameter could only specify which Ninny version is needed on a given square if all these versions had different piece ID, which then reflects on game notation.
[Edit] The latter can be solved by introduction of a new parameter localVersion, which does for the preceding group of piece types with the same ID what morph does for the single preceding type. Except that the type you would change to on each square would not be specified by the piece ID (which would be the same for each type in the group), but by letters a-z implicitly assigned to contiguous types with the same ID in table order. That would only allow changes to types within the group. Which is exactly what you need to implement location-dependent moving; in fact the localVersion parameter can be considered the definition of the square properties. If a promotion to a type outside the group is required, a normal morph parameter (indicating the types by piece ID) can still follow, overruling the type change specified in localVersion for all members of the group, while the localVersion of the group to which the piece changes would determine what (micro-)type with that ID we should change to.
It appears that betzaNew.js never passed the last game move to the AI. The code I had added to pass a dummy move in case no game move was played yet erroneously always passed the dummy move (because the moves are JavaScript objects rather than arrays, and I tested for the latter). So the AI would also not have been able to perform e.p. capture.
Should be fixed now.
Actually every move should be marked as illegal for a player that has no royal in a game where royals are defined. It is just that the absence of royalty is only tested when a piece with special (royalty, baring, anti-trading) properties is captured, as the AI assumes royalty still exists before the move, or the search branch would already have been terminated earlier. So it only tests it when it could have changed.
I guess the current AI would choke on tsume positions without King.
[Edit] For the purpose of highlighting the legality test now assumes a royaltyCount of 1 in the current position when in reality royaltyCount <= 0. In terms of scoring this fakes a single royal for the side that has none.
For the specification of a number of squares (e.g. the starting squares of the pawns) I support a shorthand I.D. where you only have to specify the lower left and upper right corner of a rectangular board area, separated by a dash. That doesn't help much in Smess, but for Xiangqi a0-i4 would give you the entire area below the River, and d0-f2 the white Palace.
Still, having to fully write down the list of coordinates for nearly all board squares is probably more cumbersome than using a FEN-like notation for the entire board. That would require the property of the square to be encoded by a single character, though. But that character could encode an index in a table of the properties. Like
a: R; b: BvR; c: BsR; d: fRrRfrB; ...
acabcbaca/bdbcacbdb/...
(Just a move assignment I made up on the spot.) For irregular patterns like Smess there is no way to avoid specifying all squares explicitly, but regular cases one often encounters are homogeneous ranks, alternating squares on a rank, identical ranks or pairs of ranks. This is acually a problem that is very similar to coloring of the board, so the solution you use in the Diagram Designer for that should be applicable here.
The current code supports the format for indicating starting squares of the pieces, which it currently the only place where it interprets square coordinates. But if it was needed to process case labels referring to board squares, it could use the same shortcut.
I am not yet convinced enumerating the squares as case labels is the most convenient solution for the reader, though. To know how a piece moves he would have to search it amongst the case labels. Even if we adopt the convention to order these alphabetically, if there are many different square properties, he still would have to examine all the lines. But if the board is represented as a FEN he would know exactly where to find the square, as a FEN is basically an image.
Another problem with the case labels is that it is hard to find a shortcut for checkered patterns, which can be expected to be a common case. For Elk Chess it would be annoying if you have to write 32 case labels of the dark squares for the N move, and the other 32 case labels for the R move. The shorthand rules already used by the I.D. for the morph FENs make it easy to represent such patterns in a compact way.
But I guess that in the context of the I.D. we should above all ask ourselves the question "where will it be displayed, and what is the intended audience. The Diagram definition would normally be invisible to viewers of the page. And if this info would be displayed at all, it would not have to be displayed in the same format as in the Diagram definition.
I think the most convenient way to present this info to the reader is put the list of squares in parentheses behind the piece name in the piece table. Each move would have da different entry in this table. In the simplest implementation it would be the responsibility to write this list himself as part of the name. But it could also be added automatically, based on the square-property FEN. In principle it would be a comma-separated list of squares, but some regular patterns could be recognized (rectangles, which includes files and ranks, or chrckering), an special verbal descriptions could be shown for those (such as "on dark squares").
Of course the reverse could also be possible: the person creating the Diagram could write the list of squares, or the special phrases behind the piece names, and the Diagram script could recognize those, and apply the indicated moves accordingly.
It is not explained wel how the barrier works. It stops sliding moves from crossing it?
Why put the same image there three times?
Which image three times?
That of the initial position.
Well, if the first diagram shows the same setup as the second, but without the 'Play it' option, I would say the first diagram is superfluous. Which information exactly would not be conveyed to the reader if it was omitted?
There might be contexts where this proverb applies, but articles explaing game rules are not amongst those. In principle every added sentence or image make those worse, and have to justify their presence by providing essential new information.
The setup section is intended for presenting an image of the initial position. So the 'Play it' Diagram can go there. As it does in the large majority of articles we have here. Then there is no need for having a second, redundant image.
Like there is no need to repeat a number of times that there is no morphing on the f-file...
The I.D. handles z and q moves through a special mechanism, and for no real reason the routine detrmining the trajectory also strips the n and j flags from the mode. I think otherwise these would be obeyed.
I will fix it when I return from Berlin. (No ftp access now...)
25 comments displayed
Permalink to the exact comments currently displayed.
I think it is by far the best to use it as the main diagram in the setup section. That is where you would put a static diagram, and I don't see any reason to place it elsewhere just because it is interactive. Before the availability of Interactive Diagrams the 'gold standard' for articles here was to have an image of the setup accompanied with the names and coordinates of the pieces, either in list or paragraph form.
I see no reason for showing the initial position twice; that is just presenting redundant information.
IMO using a different section for playing is a bad thing; people visiting this website would expect they can play against the main diagram, as this is how most articles have it, and might not look further down if the main diagram is static.
BTW, it is pretty annoying that tables suddenly have a different background color than the page as a whole. It seems the standard style sheets are messed up.