Comments/Ratings for a Single Item
I have just added a new section on breaking logic. It goes over the White_Pawn function in detail.
Fergus,
It seems I need your guidance again.
I had made an working King function for apothecary chess:
def King
or and and checkaleap #0 #1 -2 -1 var K1stmove isupper space #1
or and and checkaleap #0 #1 -2 1 var k1stmove islower space #1
or and and checkaleap #0 #1 -3 1 var k1stmove islower space #1
or and and checkaleap #0 #1 -3 -1 var K1stmove isupper space #1
or and and checkaleap #0 #1 2 -1 var K1stmove isupper space #1
or and and checkaleap #0 #1 2 1 var k1stmove islower space #1
or and and checkaleap #0 #1 3 1 var k1stmove islower space #1
or and and checkaleap #0 #1 3 -1 var K1stmove isupper space #1
or checkleap #0 #1 1 0
or checkleap #0 #1 1 1;
def King-Range merge merge leaps #0 1 0 leaps #0 1 1 merge leaps #0 1 2 leaps #0 1 3;
But this does not display the initial powers of the king, only the regular moves, so I still have work to do. Also it is not optimized, for know it is good that it works. You had suggested a while ago:
def Apothecary_King blah blah blah;
def Apothecary_King-Range blah blah blah;
alias King Apothecary_King;
set k King;
set K King;
This does not work as it gives an "King may not move there "error. That is probably because I did not insert alias in every needed place, but I'm not sure.
Thanks for your time!
You have a bunch of lines beginning with or and and. Each of these lines is checking for islower space #1 or for isupper space #1, and that's where your problem lies. In potential moves, space #1 will contain what is on the space prior to making the move, which won't be the King, but for actual moves, it will contain the piece that has moved there. I gather you mean to be making sure that only the King whose first move is contained in the variable on that line gets to move. This works for actual moves, but it is not working for potential moves, because in potential moves, space #1 contains the value of the piece on the space prior to making the move.
In Chess, the King is allowed to castle on the first move, and keeping track of whether the King has already moved is handled by flagging the space the King begins on, then unsetting the flag with every subsequent King move. This easily works for both Kings, because each King begins on a different space. So, I recommend flagging the King's initial spaces rather than keeping separate K1stmove and k1stmove variables.
I have added a new section called "Actual vs Potential Moves".
Initially you had proposed for the king first move that is found in my 2 apothecary games this :
def Apothecary_King blah blah blah;
def Apothecary_King-Range blah blah blah;
alias King Apothecary_King;
set k King;
set K King;
but this alone gave an error saying that king cannot move there when moving the first time like a camel or knight. But if I don't use this unpredictable things happen like having false positives in checkmate or the special moves apearing after the first move. Below are the links to the game courier presets in question. They are definetly not optimized or finished in any way yet but I think this particular problem should be done first. Thanks for your help!
https://www.chessvariants.com/play/pbm/play.php?game=Apothecary+Chess+1&settings=Apothecary1working&submit=Edit
Sorry, I made a couple typos. The last two lines should be:
setconst k King;
setconst K King;
Also, you still haven't followed my advice about keeping track of the King's first move the same way this is already done for Chess. If you did, your Apothecary_King function would be much simpler to write.
I'm changing the function to include flags, but for now I'm glad it works as far as it does. Trouble is that even with setconst I get that error. I had always written it correctly. I should double check though, maybe something else is wrong.
I think your problem stems from the overly complicated way you are writing your Apothecary_King function due to keeping track of whether the King has moved in a more complicated manner. It should clear up once you change how you keep track of whether the King has already moved and write a simpler function that uses flagged spaces.
While the simplest way of writing your Apothecary_King function will use flagged spaces, this should work using the method you're using now:
def Apothecary_King checkleap #0 #1 1 3 or checkleap #0 #1 1 2 and match rankname #1 1 10 and or var K1stmove == #0 f2 or var k1stmove == #0 f9 or checkleap #0 #1 1 0 or checkleap #0 #1 1 1;
Although the piece being moved will be found on a different space for actual moves and potential moves, the location of the original space remains the same whether the move is actual or potential. So, if the King is moving from its original space, and its 1st move variable is set, then it is on it's first move. Since the available Knight and Camel moves only allow the King to go to the back rank, this function also checks whether the move is to the back rank. This allows it to use checkleap instead of checkaleap, and that avoids the need to test which King is moving on each line.
Unfortuneatly the code you proposed does not work either. It gives false pozitives when displaying (shows all camel and knight moves) but on the other hand, the special 1st time moves are considered wrong when applied. My guess is that then it is a deeper problem as the king is not a ordinary piece and changing it's properties could impact other subroutines in less predictable ways.
I have not changed the code to use flags because yesterday I was a little busy with other things, but I doubt this impacted the overall result, althought a slower speed was to be expected. Thanks for your help Fergus, but it seems that apothecary chess is to difficult for me to program at this time, so I'm considerring taking a break from programming presets.
I was wondering about one line during the night. This should correct it. Note that if you had switched to flags earlier, this line wouldn't even be needed. Keeping things simple makes programming easier.
def Apothecary_King checkleap #0 #1 1 3 or checkleap #0 #1 1 2 and match rankname #1 1 10 and or and var K1stmove == #0 f2 and var k1stmove == #0 f9 or checkleap #0 #1 1 0 or checkleap #0 #1 1 1;
I see from you commenting it out that you've identified this line as the problem that's causing premature checkmate:
set Kpos space moved;
It should be changed to
set Kpos $dest;
The space operator returns the piece on the coordinate given to it, but you want to set Kpos to a coordinate, and $moved is a piece, not a coordinate.
Finally I tried to replace the code that was using a boolean variable with one using flags. I'm not sure how this will change what you provdeded earlier and worked fine while kpos and Kpos were used correctly.
The line "and or f2 f9" should be "and flag #0".
All right. Things are great! Thanks!...
The only thing is that the definition of king is used rather than an apothecary king and then an alias with king. Could this have any problems. Anyway big help for your Help!
Since King is an alias for Apothecary_King, it converts King to Apothecary_King before it searches for a function, subroutine, or description. If it can't find an Apothecary_King subroutine, for example, that's the end of the line, and it will not search for a King subroutine.
Except that your code is based on some earlier code with a bug in it. Compare your code for displaying descriptions with the code in the Chess preset, which is up-to-date and corrected.
I don't understand what you are trying to say.
But I verified checkmates and they work in both apothecary chess modern and apothecary chess classic as I copied the functions to the other game.
I don't understand what you are trying to say.
You said:
The only thing is that the definition of king is used rather than an apothecary king and then an alias with king.
That's a bug. It should show the description for the Apothecary_King. This bug is due to you using older code that is not bug-free. This buggy code is in your Post-Move sections. The Chess preset has up-to-date bugfree code in its Post-Move sections. The bug is in this line:
set desc join #name "-Desc";
This should be:
set desc join realname #name "-Desc";
Is not that post move section?
It is, I misread sorry!...
I have made tests for the all moves and then check and checkmate and things seem ok if we redefine (by overwritting) the king subroutine. These don't work properly if an Apothecary_king function is defined and then use of aliases is made. Is there a reason against leaving things as is, Fergus?
I see in your code that you started using the name King directly instead of as an alias for Apothecary_King. When you do it this way, it calls the King subroutine. This is working out for you, because the King subroutine calls the King function. The subroutine also includes some code for handling castling, but since you have not set wcastle and bcastle, it will recognize any attempt at castling as illegal without needing to call the castle subroutine. So, it basically just uses the function to check the move's legality, and it updates the value of kpos or Kpos to the space the King moved to. What the King subroutine is doing that your code was not doing before is updating kpos or Kpos BEFORE your code checks whether your King has moved into check. Presently, you have the code for updating kpos and Kpos at the very end of your Post-Move sections, but these variables need to be updated before checking whether you have moved into check. So, if you just changed the position of this part of your code, you could use King as an alias for Apothecary_King without any problem.
I had done that and the moves were displayed but I was not able to do them due to the error saying that a king cannot move there.
I have change the code in the setconst area to:
setconst k Apothecary_King;
setconst K Apothecary_King;
and now things work properly as far as I can see.
I don't see why that would make a difference. What move couldn't you make using King as an alias for Apothecary_King?
25 comments displayed
Permalink to the exact comments currently displayed.
In your code, K1stmove just appears by itself, and it gets interpreted as a string literal that has no meaning. I expect it will always evaluate to true. So, your code should be logically equivalent to this:
def Apothecary_King or or checkleap #0 #1 2 1 checkleap #0 #1 1 0 checkleap #0 #1 1 1;
That should work for displaying Knight moves. So, I don't know why your code is not displaying Knight moves. But other things about it need to be fixed anyway.
Also, your logical operators are all at the beginning, which is wasteful. Learn to use them with single arguments so that you can break out of the function early when it already has the correct result, like this example does:
def Apothecary_King checkleap #0 #1 2 1 or checkleap #0 #1 1 0 or checkleap #0 #1 1 1;
Take a look at the Pawn functions for more complex examples of how to do this.