Simplifying code
Moderators: hgm, Rebel, chrisw
-
- Posts: 347
- Joined: Tue Nov 19, 2019 4:34 am
- Location: https://github.com/TerjeKir/weiss
- Full name: Terje Kirstihagen
Re: Simplifying code
Weiss excluding the Fathom code is 2.5k lines of code
-
- Posts: 893
- Joined: Mon Jan 15, 2007 11:23 am
- Location: Warsza
Re: Simplifying code
JohnWoe, either You are including comments in Your LOC count or my regular expression to count lines of code is broken. It tells me that Rodent IV is roughly 8500 lines of code, excluding comments.
Pawel Koziol
http://www.pkoziol.cal24.pl/rodent/rodent.htm
http://www.pkoziol.cal24.pl/rodent/rodent.htm
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Simplifying code
Functional programming is probably best. So every time you make an assignment you should 'apologize'.
Pity that copying a board position is already too costly.
Pity that copying a board position is already too costly.
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Simplifying code
Now I have this for alpha beta search. Don't like it. Too many if statements.
Code: Select all
ISearchResult SearchMoves(IChessPosition position, IMovePrioQ prioQ, IVariation initialVariation, int depth,
int plyCount, int lb, int ub)
{
if (!(TimeManagement.SearchExpired(Level))
&& (initialVariation == null || initialVariation.Value < ub)
&& prioQ.Count() > 0)
{
var mv = prioQ.Top();
var firstVariation = SearchMove(position, mv, initialVariation, depth, plyCount, lb, ub);
if (firstVariation == null)
{
return null;
}
else
{
var nextLb = Max(lb, firstVariation.Value);
var remPrioQ = prioQ.Pop();
var remResult = SearchMoves(position, remPrioQ, firstVariation, depth, plyCount, nextLb, ub);
if (firstVariation != initialVariation)
{
return ResultBuilder.BuildResult(firstVariation, remResult);
}
else
{
return remResult;
}
}
}
return null;
}
-
- Posts: 115
- Joined: Wed Feb 12, 2020 5:00 pm
- Full name: Morgan Houppin
Re: Simplifying code
What about reordering it like that:Henk wrote: ↑Fri Jun 12, 2020 2:01 pm Now I have this for alpha beta search. Don't like it. Too many if statements.Code: Select all
ISearchResult SearchMoves(IChessPosition position, IMovePrioQ prioQ, IVariation initialVariation, int depth, int plyCount, int lb, int ub) { if (!(TimeManagement.SearchExpired(Level)) && (initialVariation == null || initialVariation.Value < ub) && prioQ.Count() > 0) { var mv = prioQ.Top(); var firstVariation = SearchMove(position, mv, initialVariation, depth, plyCount, lb, ub); if (firstVariation == null) { return null; } else { var nextLb = Max(lb, firstVariation.Value); var remPrioQ = prioQ.Pop(); var remResult = SearchMoves(position, remPrioQ, firstVariation, depth, plyCount, nextLb, ub); if (firstVariation != initialVariation) { return ResultBuilder.BuildResult(firstVariation, remResult); } else { return remResult; } } } return null; }
Code: Select all
ISearchResult SearchMoves(IChessPosition position, IMovePrioQ prioQ, IVariation initialVariation, int depth, int plyCount, int lb, int ub)
{
if (TimeManagement.SearchExpired(Level)
|| (initialVariation && initialVariation.Value >= ub)
|| prioQ.Count() <= 0)
{
return null;
}
var mv = prioQ.Top();
var firstVariation = SearchMove(position, mv, initialVariation, depth, plyCount, lb, ub);
if (firstVariation == null)
{
return null;
}
var nextLb = Max(lb, firstVariation.Value);
var remPrioQ = prioQ.Pop();
var remResult = SearchMoves(position, remPrioQ, firstVariation, depth, plyCount, nextLb, ub);
if (firstVariation != initialVariation)
{
return ResultBuilder.BuildResult(firstVariation, remResult);
}
return remResult;
}
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Simplifying code
Yes looks better. But I saw a video about monads recently. Although i am not sure I understand it.
Don't know anything about category theory.
So maybe I could use something like a monad to hide some obvious recurring tests.
Monad is a functor plus a flatten operation I understood.
Already unfamiliar with functors.
Also read that null is forbidden.
Don't know anything about category theory.
So maybe I could use something like a monad to hide some obvious recurring tests.
Monad is a functor plus a flatten operation I understood.
Already unfamiliar with functors.
Also read that null is forbidden.
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Simplifying code
Good to hear that you think a lot about theory ... But what is your goal? To have a working chess engine that plays decent chess and has source code without bugs that can be maintained and changed quite easily (which is somehow related to "being simple" and "you like it"!)? Or to have an engine that matches common formal theories?Henk wrote: ↑Fri Jun 12, 2020 2:33 pm Yes looks better. But I saw a video about monads recently. Although i am not sure I understand it.
Don't know anything about category theory.
So maybe I could use something like a monad to hide some obvious recurring tests.
Monad is a functor plus a flatten operation I understood.
Already unfamiliar with functors.
Sven Schüle (engine author: Jumbo, KnockOut, Surprise)
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Simplifying code
I hate bugs and code i can't understand or change easily.Sven wrote: ↑Fri Jun 12, 2020 2:48 pmGood to hear that you think a lot about theory ... But what is your goal? To have a working chess engine that plays decent chess and has source code without bugs that can be maintained and changed quite easily (which is somehow related to "being simple" and "you like it"!)? Or to have an engine that matches common formal theories?Henk wrote: ↑Fri Jun 12, 2020 2:33 pm Yes looks better. But I saw a video about monads recently. Although i am not sure I understand it.
Don't know anything about category theory.
So maybe I could use something like a monad to hide some obvious recurring tests.
Monad is a functor plus a flatten operation I understood.
Already unfamiliar with functors.
Today and previous week I had to undo my changes after repairing 1000 compile time errors. Much misery.
Almost impossible to replace bitboards by something else in my source code.
So code should be written such that it is easy to make changes. That is most important.
Last edited by Henk on Fri Jun 12, 2020 3:06 pm, edited 1 time in total.
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Simplifying code
I would have proposed almost the same, for the same reasons. It would improve readability. However, it would not reduce the number of if's. Addressing that would require to know a bit more background.mhouppin wrote: ↑Fri Jun 12, 2020 2:17 pmWhat about reordering it like that:Henk wrote: ↑Fri Jun 12, 2020 2:01 pm Now I have this for alpha beta search. Don't like it. Too many if statements.Code: Select all
ISearchResult SearchMoves(IChessPosition position, IMovePrioQ prioQ, IVariation initialVariation, int depth, int plyCount, int lb, int ub) { if (!(TimeManagement.SearchExpired(Level)) && (initialVariation == null || initialVariation.Value < ub) && prioQ.Count() > 0) { var mv = prioQ.Top(); var firstVariation = SearchMove(position, mv, initialVariation, depth, plyCount, lb, ub); if (firstVariation == null) { return null; } else { var nextLb = Max(lb, firstVariation.Value); var remPrioQ = prioQ.Pop(); var remResult = SearchMoves(position, remPrioQ, firstVariation, depth, plyCount, nextLb, ub); if (firstVariation != initialVariation) { return ResultBuilder.BuildResult(firstVariation, remResult); } else { return remResult; } } } return null; }
Less indentations and if-else blocks by exploiting the "return" statements.Code: Select all
ISearchResult SearchMoves(IChessPosition position, IMovePrioQ prioQ, IVariation initialVariation, int depth, int plyCount, int lb, int ub) { if (TimeManagement.SearchExpired(Level) || (initialVariation && initialVariation.Value >= ub) || prioQ.Count() <= 0) { return null; } var mv = prioQ.Top(); var firstVariation = SearchMove(position, mv, initialVariation, depth, plyCount, lb, ub); if (firstVariation == null) { return null; } var nextLb = Max(lb, firstVariation.Value); var remPrioQ = prioQ.Pop(); var remResult = SearchMoves(position, remPrioQ, firstVariation, depth, plyCount, nextLb, ub); if (firstVariation != initialVariation) { return ResultBuilder.BuildResult(firstVariation, remResult); } return remResult; }
@Henk: What does "return null" mean in this context? Encountered an illegal move? A leaf node (e.g. mate/stalemate/other draw)? How and where do you differentiate between these?
There is another issue, even a major one I believe: SearchMoves() will be called recursively N times to process a move list ("move priority queue") of length N, unless there is some cutoff inbetween. That means: searching to depth D with an average move list size of N implies that D*N recursive calls are made. This will create really a huge overhead at runtime caused by a very huge runtime stack and a lot of temporary objects being created and destroyed on the fly, which I consider to be a bad design. E.g. for processing one node at one level in the search tree there will be up to N internal move priority queue objects of length N, N-1, N-2, ..., 1, caused by "var remPrioQ = prioQ.Pop();" in combination with the mentioned tail recursion strategy. I would recommend a classical loop instead ...
Finally I do not understand the alpha-beta algorithm in that implementation yet. Where is the code for the AB cutoff? The condition "initialVariation.Value >= ub" does not look like it to me since it causes a "return null" instead of returning a SearchResult carrying either "initialVariation.Value" or "ub" as its value.
Sven Schüle (engine author: Jumbo, KnockOut, Surprise)
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Simplifying code
Good ... then I'd suggest to forget about category theory, monads, and functors for a while ...Henk wrote: ↑Fri Jun 12, 2020 3:00 pmI hate bugs and code i can't understand or change easily.Sven wrote: ↑Fri Jun 12, 2020 2:48 pmGood to hear that you think a lot about theory ... But what is your goal? To have a working chess engine that plays decent chess and has source code without bugs that can be maintained and changed quite easily (which is somehow related to "being simple" and "you like it"!)? Or to have an engine that matches common formal theories?Henk wrote: ↑Fri Jun 12, 2020 2:33 pm Yes looks better. But I saw a video about monads recently. Although i am not sure I understand it.
Don't know anything about category theory.
So maybe I could use something like a monad to hide some obvious recurring tests.
Monad is a functor plus a flatten operation I understood.
Already unfamiliar with functors.
Today and previous week I had to undo my changes after repairing 1000 compile time errors. Much misery.
Almost impossible to replace bitboards by something else in my source code.
So code should be written such that it easy to make changes. That is most important.
Sven Schüle (engine author: Jumbo, KnockOut, Surprise)