Could someone please have a look at my Quiescence and let me know if you see any glaring mistakes. Mainly I am concerned with when I am supposed to flip the score for black (SideToMoveScore).
Anyone please have a look, I think I have a bug in there somewhere. My engine makes a stupid move in a test position when Quiescence is enabled. I can't seem to figure out what I am doing wrong. All of the code examples I found don't flip the score for black so I am not sure if what I am doing is correct.
2) I suppose the GenerateValidMoves generates valid moves for *both* sides, otherwise the code is most likely wrong as you didn't swap movingSide after executing the move, so moves for the wrong side would get generated. If that's not it, this call should probably go before EvaluateMoves for performance reasons anyway. (And possibly correctness, if it isn't called at the top level first before starting a search).
GenerateValidMoves() would not be able to generate moves for only one side without knowing for which, so I expect that the Board class contains the sideToMove information. But in this case it is confusing to have another sideToMove variable or parameter, and also it would be absolutely necessary to do the side switch explicitly when making a move, at the place where the new board copy is created.
If the Board class is not supposed to contain sideToMove information then GenerateValidMoves() is clearly missing that as parameter, or does some unknown magic to determine for which side it shall generate moves.
Moving the move generation code to a different place, as already proposed, would also be my proposal, but be aware that this may also be necessary in the search code "above" quiescence search.
2) I suppose the GenerateValidMoves generates valid moves for *both* sides, otherwise the code is most likely wrong as you didn't swap movingSide after executing the move, so moves for the wrong side would get generated. If that's not it, this call should probably go before EvaluateMoves for performance reasons anyway. (And possibly correctness, if it isn't called at the top level first before starting a search).
1) ChessPieceType.Queen tells the MovePiece Method to promote to Queen if promotion is available. I have to fix this in the future but for now my chess engine always promotes and assumes you will promote to queen.
2) I think you are correct, I don't actully need the MovingSide variable since it should always be equal to examineBoard's MovingSide variable. The GenerateValid moves always uses the chess boards Moving Side variable and the MovePiece method flips it.
aberent wrote:2) I think you are correct, I don't actully need the MovingSide variable since it should always be equal to examineBoard's MovingSide variable. The GenerateValid moves always uses the chess boards Moving Side variable and the MovePiece method flips it.
Which is what I expected. (EDIT: I think you actually answered on my previous post although it looks as if you replied to GCP.)
Does GenerateValidMoves() generate all moves, or just captures and promotions? In the former case, how do you select captures and promotions as the only moves to be made during qsearch?
aberent wrote:2) I think you are correct, I don't actully need the MovingSide variable since it should always be equal to examineBoard's MovingSide variable. The GenerateValid moves always uses the chess boards Moving Side variable and the MovePiece method flips it.
Which is what I expected. (EDIT: I think you actually answered on my previous post although it looks as if you replied to GCP.)
Does GenerateValidMoves() generate all moves, or just captures and promotions? In the former case, how do you select captures and promotions as the only moves to be made during qsearch?
Sven
Generate Valid Moves generates all valid moves including non captures.
Evaluate Moves (this method assings a pseudo score to all the moves for sorting) takes a boolean flag called capturesOnly (its always true in Quiescence). If true then Evaluate Moves returns only capture moves.
Is that wrong should I be filtering out captures in GenerateValidMoves(). This would be faster but will miss some data that I need in the Score Evaluation like what piece is protecting what piece.
aberent wrote:
Evaluate Moves (this method assings a pseudo score to all the moves for sorting) takes a boolean flag called capturesOnly (its always true in Quiescence). If true then Evaluate Moves returns only capture moves.
In this case the code posted looks correct to me.
I'd proceed with feeding it positions with known result, starting with a position with no (possible) captures, one winning capture, a capture sequence of 2 captures, etc, until it goes wrong.
aberent wrote:
Evaluate Moves (this method assings a pseudo score to all the moves for sorting) takes a boolean flag called capturesOnly (its always true in Quiescence). If true then Evaluate Moves returns only capture moves.
In this case the code posted looks correct to me.
I'd proceed with feeding it positions with known result, starting with a position with no (possible) captures, one winning capture, a capture sequence of 2 captures, etc, until it goes wrong.
That is a good idea, do you know any websites that post FENs for positions like that?