setjmp() - another one

Discussion of anything and everything relating to chess playing software and machines.

Moderator: Ras

bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: setjmp() - another one

Post by bob »

chrisw wrote:Bob argued that the existence in the Rybka code of setjmp() was "interesting" because this also existed in Fruit and nowhere else.

Uri pointed out that Tom Kerrigan's public program TSCP also used setjmp() and that some other programs were likely/possibly developed, legally, off TSCP as basis.

I'm an engine programmer and always had user interface programmers working in support, so I got very lazy and understand very little about DOS, windows, C support functions and so on. setjmp() knowledge is no way a speciality of mine.

However, casting my mind back many years, I'm fairly sure that the Ren Wu Chess program which was also worked on by Ren at Oxford Softworks used setjmp() to unwind the search on a timeout. CSTal, by contrast, did a proper search unwind.

There are two ways to exit Search() on a timeout or user intervention. The 'correct' way, I suppose, is to unwind the Search back to the start using unmove simultaneously unstacking the variables.
The brutal and simple way is simply to jump straight out, reseting the stack pointer. I guess this is setjmp().

I'l be very surprised if numbers of programs, especially those designed years ago without SMP in mind, didn't use the brutal setjmp() technique to break the search.

Bottom line: setjmp() is not unique and its use doesn't imply anything, certainly it cannot imply copied code.
Again, "I think..." "if I remember"... I said it is rare. It appears to be so. So the presence is both programs is still "interesting". The problem is that longjmp() does not restore the board to the starting position, nor anything else other than whatever is on the stack. That's why it is considered a bad solution to any known problem, because you can get back to the starting point with contradictory state information.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: setjmp() - another one

Post by bob »

tiger wrote:
chrisw wrote:Bob argued that the existence in the Rybka code of setjmp() was "interesting" because this also existed in Fruit and nowhere else.

Uri pointed out that Tom Kerrigan's public program TSCP also used setjmp() and that some other programs were likely/possibly developed, legally, off TSCP as basis.

I'm an engine programmer and always had user interface programmers working in support, so I got very lazy and understand very little about DOS, windows, C support functions and so on. setjmp() knowledge is no way a speciality of mine.

However, casting my mind back many years, I'm fairly sure that the Ren Wu Chess program which was also worked on by Ren at Oxford Softworks used setjmp() to unwind the search on a timeout. CSTal, by contrast, did a proper search unwind.

There are two ways to exit Search() on a timeout or user intervention. The 'correct' way, I suppose, is to unwind the Search back to the start using unmove simultaneously unstacking the variables.
The brutal and simple way is simply to jump straight out, reseting the stack pointer. I guess this is setjmp().

I'l be very surprised if numbers of programs, especially those designed years ago without SMP in mind, didn't use the brutal setjmp() technique to break the search.

Bottom line: setjmp() is not unique and its use doesn't imply anything, certainly it cannot imply copied code.


It can if it is used in the context of a routine that has not only setjmp but also a number of other identical/equivalent code.

Here we have an example of source code comparison (thanks to Norman) in which you could say that the use of strtok is not unique to Fruit 2.1 or Rybka 1.0. However the way they are used shows troubling similarities:

http://pagesperso-orange.fr/ct_chess/Fr ... rt_go.html



// Christophe
It would not work in Crafty, for example, because I have a single global board that is not on any stack. Somebody has to undo each and every move or things are going to crash.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: setjmp() - another one

Post by bob »

chrisw wrote:
tiger wrote:
chrisw wrote:
tiger wrote:
chrisw wrote:Bob argued that the existence in the Rybka code of setjmp() was "interesting" because this also existed in Fruit and nowhere else.

Uri pointed out that Tom Kerrigan's public program TSCP also used setjmp() and that some other programs were likely/possibly developed, legally, off TSCP as basis.

I'm an engine programmer and always had user interface programmers working in support, so I got very lazy and understand very little about DOS, windows, C support functions and so on. setjmp() knowledge is no way a speciality of mine.

However, casting my mind back many years, I'm fairly sure that the Ren Wu Chess program which was also worked on by Ren at Oxford Softworks used setjmp() to unwind the search on a timeout. CSTal, by contrast, did a proper search unwind.

There are two ways to exit Search() on a timeout or user intervention. The 'correct' way, I suppose, is to unwind the Search back to the start using unmove simultaneously unstacking the variables.
The brutal and simple way is simply to jump straight out, reseting the stack pointer. I guess this is setjmp().

I'l be very surprised if numbers of programs, especially those designed years ago without SMP in mind, didn't use the brutal setjmp() technique to break the search.

Bottom line: setjmp() is not unique and its use doesn't imply anything, certainly it cannot imply copied code.


It can if it is used in the context of a routine that has not only setjmp but also a number of other identical/equivalent code.

Here we have an example of source code comparison (thanks to Norman) in which you could say that the use of strtok is not unique to Fruit 2.1 or Rybka 1.0. However the way they are used shows troubling similarities:

http://pagesperso-orange.fr/ct_chess/Fr ... rt_go.html

// Christophe
You're probably not going to like this Christophe, but I take no interest at all in the UCI parsing side of the programs.

a) I don't understand that stuff, always having used support programmers to do that kind of work. strtok() - what does that do? I have no idea, it's not engine code.

b) for me, Rybka is only going to be a Fruit derivative if there is engine code correspondence. What they each do and how they do it with parameters passed from the interface is of no concern at all.

Anyway, I asked Zach if he'll produce your best case of engine code correspondence for both sides to consider ......


setjmp() to break search .....
Fruit, Rybka, an old OS chess program, early Movei, TSCP, hardly a scientific but unlikely to be an exhaustive list.


I'm sorry to hear that you can't understand parts of the C code that has been shown. It's going to be hard for you to follow what will come next, but maybe you can take advice from someone who has some expertise.

I'm interested in GPL infringement and I can already see some in the code that has been posted.

Remember: the GPL does not say that it's fair game to copy some parts and not others. The GPL says that you are not welcome to use any part of this code for a non-GPL program.

// Christophe
I'm interested in the comment "Rybka is a derivative of Fruit", which, to me at least, implies that Vas didn't program substantial chunks of engine.

I'm interested in comments like "should be banned for life from icga tournaments"

The UCI side is quite irrevelent to that. A GPL 'infringement' of the UCI is of no interest at all to the icga tournament coming up and quite probably of no great interest to the mass of comp chess people, who want to know one thing and one thing only. Is the engine a copy containing chunks of other people's work? Are there examples of cut 'n paste in the engine code?

All this talk of UCI GPL infringement is just prissy prissy stuff. If there is any, in reality, it could just be whizzed out by support engineers tomorrow, if it hasn't already been, if it ever existed. Get real and find some engine correspondence if there is any.
Christophe raised the GPL issue. And what the GPL says is that if you copy GPL source, your program must conform to GPL requirements. If you rewrite _every_ line you copied, then, and only then, can you escape the GPL and no longer conform.

That is a pretty clear description of what you can do legally. Yes, I agree that much of a chess program has nothing to do with playing chess, and I don't care if those parts were copied or not. Such as when someone asks for permission to use part(s) of Crafty. But that is not what the GPL allows and what I don't object to has nothing to do with how the GPL is interpreted.
chrisw

Re: setjmp() - another one

Post by chrisw »

bob wrote:
chrisw wrote:Bob argued that the existence in the Rybka code of setjmp() was "interesting" because this also existed in Fruit and nowhere else.

Uri pointed out that Tom Kerrigan's public program TSCP also used setjmp() and that some other programs were likely/possibly developed, legally, off TSCP as basis.

I'm an engine programmer and always had user interface programmers working in support, so I got very lazy and understand very little about DOS, windows, C support functions and so on. setjmp() knowledge is no way a speciality of mine.

However, casting my mind back many years, I'm fairly sure that the Ren Wu Chess program which was also worked on by Ren at Oxford Softworks used setjmp() to unwind the search on a timeout. CSTal, by contrast, did a proper search unwind.

There are two ways to exit Search() on a timeout or user intervention. The 'correct' way, I suppose, is to unwind the Search back to the start using unmove simultaneously unstacking the variables.
The brutal and simple way is simply to jump straight out, reseting the stack pointer. I guess this is setjmp().

I'l be very surprised if numbers of programs, especially those designed years ago without SMP in mind, didn't use the brutal setjmp() technique to break the search.

Bottom line: setjmp() is not unique and its use doesn't imply anything, certainly it cannot imply copied code.
Again, "I think..." "if I remember"... I said it is rare. It appears to be so. So the presence is both programs is still "interesting". The problem is that longjmp() does not restore the board to the starting position, nor anything else other than whatever is on the stack. That's why it is considered a bad solution to any known problem, because you can get back to the starting point with contradictory state information.
Entirely agreed its no good solution, but that's not the point. You said it was rare/unique whatever. It isn't. And therefore it's another nail in the probably used the same code coffin. It isn't.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: setjmp() - another one

Post by bob »

Uri Blass wrote:
Guetti wrote:
chrisw wrote:Bob argued that the existence in the Rybka code of setjmp() was "interesting" because this also existed in Fruit and nowhere else.

Uri pointed out that Tom Kerrigan's public program TSCP also used setjmp() and that some other programs were likely/possibly developed, legally, off TSCP as basis.

I'm an engine programmer and always had user interface programmers working in support, so I got very lazy and understand very little about DOS, windows, C support functions and so on. setjmp() knowledge is no way a speciality of mine.

However, casting my mind back many years, I'm fairly sure that the Ren Wu Chess program which was also worked on by Ren at Oxford Softworks used setjmp() to unwind the search on a timeout. CSTal, by contrast, did a proper search unwind.

There are two ways to exit Search() on a timeout or user intervention. The 'correct' way, I suppose, is to unwind the Search back to the start using unmove simultaneously unstacking the variables.
The brutal and simple way is simply to jump straight out, reseting the stack pointer. I guess this is setjmp().

I'l be very surprised if numbers of programs, especially those designed years ago without SMP in mind, didn't use the brutal setjmp() technique to break the search.

Bottom line: setjmp() is not unique and its use doesn't imply anything, certainly it cannot imply copied code.
Leaving the setjmp() relevant or not argument aside for a moment, come on, you state that you believe that an engine used setjmp()? Isn't that a bit vague? You demand always hard facts and source and pretty aligned code from Zach and Christoph, so were are the facts of Ren Wu chess?
Would you believe Zach if he would write he believes that the eval of Rybka is identical to Fruit without further comment?
You always want to see facts, so please before you do a conclusion, gives us some facts.

When I look at the (far from complete) list of chess engines released in recent years at http://wbec-ridderkerk.nl/html/enginesindex.htm, I wonder how many of these engines use setjmp()? 10 of 200? More?
I think it is still a good indication, not a prove.
I do not know but movei used setjmp() at the beginning like tscp
and I simply learned from the code of tscp.

I got rid of setjmp later because I read people said it is not good
so it is not clear how many engines use setjmp.
old movei use it
new movei does not use it and you can download both old movei and new movei from wbec site.

Uri
So, you copied TSCP, which uses setjmp(). And then discovered it is a bad programming solution and removed it. Good. But notice where you got it from. That is the point of this minor side-issue. It is just another indication that perhaps something was copied, because good programmers do not use it for _many_ reasons. Perhaps Fruit started life as TSCP as well, who knows? But if programs that are suspected of being connected by common source, share a particular feature that is known to be bad programming, it is just another hint that things might have been copied...

I never claimed it to be the ultimate proof. I simply said it was another suspicious detail because it is such a lousy way of writing a program.
chrisw

Re: setjmp() - another one

Post by chrisw »

bob wrote:
Uri Blass wrote:
Guetti wrote:
chrisw wrote:Bob argued that the existence in the Rybka code of setjmp() was "interesting" because this also existed in Fruit and nowhere else.

Uri pointed out that Tom Kerrigan's public program TSCP also used setjmp() and that some other programs were likely/possibly developed, legally, off TSCP as basis.

I'm an engine programmer and always had user interface programmers working in support, so I got very lazy and understand very little about DOS, windows, C support functions and so on. setjmp() knowledge is no way a speciality of mine.

However, casting my mind back many years, I'm fairly sure that the Ren Wu Chess program which was also worked on by Ren at Oxford Softworks used setjmp() to unwind the search on a timeout. CSTal, by contrast, did a proper search unwind.

There are two ways to exit Search() on a timeout or user intervention. The 'correct' way, I suppose, is to unwind the Search back to the start using unmove simultaneously unstacking the variables.
The brutal and simple way is simply to jump straight out, reseting the stack pointer. I guess this is setjmp().

I'l be very surprised if numbers of programs, especially those designed years ago without SMP in mind, didn't use the brutal setjmp() technique to break the search.

Bottom line: setjmp() is not unique and its use doesn't imply anything, certainly it cannot imply copied code.
Leaving the setjmp() relevant or not argument aside for a moment, come on, you state that you believe that an engine used setjmp()? Isn't that a bit vague? You demand always hard facts and source and pretty aligned code from Zach and Christoph, so were are the facts of Ren Wu chess?
Would you believe Zach if he would write he believes that the eval of Rybka is identical to Fruit without further comment?
You always want to see facts, so please before you do a conclusion, gives us some facts.

When I look at the (far from complete) list of chess engines released in recent years at http://wbec-ridderkerk.nl/html/enginesindex.htm, I wonder how many of these engines use setjmp()? 10 of 200? More?
I think it is still a good indication, not a prove.
I do not know but movei used setjmp() at the beginning like tscp
and I simply learned from the code of tscp.

I got rid of setjmp later because I read people said it is not good
so it is not clear how many engines use setjmp.
old movei use it
new movei does not use it and you can download both old movei and new movei from wbec site.

Uri
So, you copied TSCP, which uses setjmp(). And then discovered it is a bad programming solution and removed it. Good. But notice where you got it from. That is the point of this minor side-issue. It is just another indication that perhaps something was copied, because good programmers do not use it for _many_ reasons. Perhaps Fruit started life as TSCP as well, who knows? But if programs that are suspected of being connected by common source, share a particular feature that is known to be bad programming, it is just another hint that things might have been copied...

I never claimed it to be the ultimate proof. I simply said it was another suspicious detail because it is such a lousy way of writing a program.
Ahem. Copied? I would prefer "used the idea". And if it's one line of code, there's not much else he can do, is there?

What if someone reads Crafty use of null move? The call is one line

value = -Search(ply-2); basically

how are we going to get a suitable value back from Search() without telling it to take 2 of the search depth?

Some things just are as they are.
User avatar
Zach Wegner
Posts: 1922
Joined: Thu Mar 09, 2006 12:51 am
Location: Earth

Re: setjmp() - another one

Post by Zach Wegner »

chrisw wrote:Entirely agreed its no good solution, but that's not the point. You said it was rare/unique whatever. It isn't. And therefore it's another nail in the probably used the same code coffin. It isn't.
You don't think it is rare? What, five total engines, one which has since been removed, out of how many hundreds??

Bob sums it up perfectly: "I never claimed it to be the ultimate proof. I simply said it was another suspicious detail because it is such a lousy way of writing a program."

Some people will always refuse to accept evidence when it is presented.
chrisw

Re: setjmp() - another one

Post by chrisw »

Zach Wegner wrote:
chrisw wrote:Entirely agreed its no good solution, but that's not the point. You said it was rare/unique whatever. It isn't. And therefore it's another nail in the probably used the same code coffin. It isn't.
You don't think it is rare? What, five total engines, one which has since been removed, out of how many hundreds??

Bob sums it up perfectly: "I never claimed it to be the ultimate proof. I simply said it was another suspicious detail because it is such a lousy way of writing a program."

Some people will always refuse to accept evidence when it is presented.
And some people don't like their evidence being challenged ;-)

It's spurious to say 5 out of 500 because no exhaustive search has been done on the 500. It's 5 only for the unscientific reason that two programmers happened to remember some past detail.

As to how many in total? Difficult. Some by random because they were old engines, SMP wasn't a problem and jumping out of the Search is a lazy but effective method, if politically incorrect. Some because they read TSCP. Some not because they read Crafty. What does Gnu do?

To pillory a programmer and his work it is necessary to produce evidence that stands beyond all reasonable doubt. This use of setjmp() is no longer in the beyond all reasonable doubt camp. Sorry about that, but that's the way it can go in adversarial investigation processes like this one.

Each point you bring will be challenged. Some will fall and some will stand, presumably. Do you want it any other way? Just blind acceptance because you're getting frustrated otherwise? If it were you, Zach, you'ld expect a vigorous defence and counter to each and every allegation and piece of evidence. Would you not?

setjmp() is not even a suspicious detail. It's history. Sorry.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: setjmp() - another one

Post by bob »

chrisw wrote:
bob wrote:
Uri Blass wrote:
Guetti wrote:
chrisw wrote:Bob argued that the existence in the Rybka code of setjmp() was "interesting" because this also existed in Fruit and nowhere else.

Uri pointed out that Tom Kerrigan's public program TSCP also used setjmp() and that some other programs were likely/possibly developed, legally, off TSCP as basis.

I'm an engine programmer and always had user interface programmers working in support, so I got very lazy and understand very little about DOS, windows, C support functions and so on. setjmp() knowledge is no way a speciality of mine.

However, casting my mind back many years, I'm fairly sure that the Ren Wu Chess program which was also worked on by Ren at Oxford Softworks used setjmp() to unwind the search on a timeout. CSTal, by contrast, did a proper search unwind.

There are two ways to exit Search() on a timeout or user intervention. The 'correct' way, I suppose, is to unwind the Search back to the start using unmove simultaneously unstacking the variables.
The brutal and simple way is simply to jump straight out, reseting the stack pointer. I guess this is setjmp().

I'l be very surprised if numbers of programs, especially those designed years ago without SMP in mind, didn't use the brutal setjmp() technique to break the search.

Bottom line: setjmp() is not unique and its use doesn't imply anything, certainly it cannot imply copied code.
Leaving the setjmp() relevant or not argument aside for a moment, come on, you state that you believe that an engine used setjmp()? Isn't that a bit vague? You demand always hard facts and source and pretty aligned code from Zach and Christoph, so were are the facts of Ren Wu chess?
Would you believe Zach if he would write he believes that the eval of Rybka is identical to Fruit without further comment?
You always want to see facts, so please before you do a conclusion, gives us some facts.

When I look at the (far from complete) list of chess engines released in recent years at http://wbec-ridderkerk.nl/html/enginesindex.htm, I wonder how many of these engines use setjmp()? 10 of 200? More?
I think it is still a good indication, not a prove.
I do not know but movei used setjmp() at the beginning like tscp
and I simply learned from the code of tscp.

I got rid of setjmp later because I read people said it is not good
so it is not clear how many engines use setjmp.
old movei use it
new movei does not use it and you can download both old movei and new movei from wbec site.

Uri
So, you copied TSCP, which uses setjmp(). And then discovered it is a bad programming solution and removed it. Good. But notice where you got it from. That is the point of this minor side-issue. It is just another indication that perhaps something was copied, because good programmers do not use it for _many_ reasons. Perhaps Fruit started life as TSCP as well, who knows? But if programs that are suspected of being connected by common source, share a particular feature that is known to be bad programming, it is just another hint that things might have been copied...

I never claimed it to be the ultimate proof. I simply said it was another suspicious detail because it is such a lousy way of writing a program.
Ahem. Copied? I would prefer "used the idea". And if it's one line of code, there's not much else he can do, is there?
It is not "one line of code" it is an approach to unwind the search that requires actions in other parts of the program in order for it to work properly. Also he said "I don't understand how it works" so how can one copy an idea they don't understand? :)


What if someone reads Crafty use of null move? The call is one line

value = -Search(ply-2); basically
Basically? here's real code:

Code: Select all

 pieces = (wtm) ? TotalPieces(white, occupied) : TotalPieces(black, occupied);
  if (do_null && !tree->inchk[ply] && pieces && (pieces > 9 || depth < 7 * PLY)) {
    register BITBOARD save_hash_key;
    int null_depth;

    tree->curmv[ply] = 0;
    tree->phase[ply] = NULL_MOVE;
#if defined(TRACE)
    if (ply <= trace_level)
      Trace(tree, ply, depth, wtm, beta - 1, beta, "Search1", 0);
#endif
    null_depth = (depth > 6 * PLY && pieces > 9) ? null_max : null_min;
    tree->position[ply + 1] = tree->position[ply];
    Rule50Moves(ply + 1) = 0;
    save_hash_key = HashKey;
    if (EnPassant(ply)) {
      HashEP(EnPassant(ply + 1), HashKey);
      EnPassant(ply + 1) = 0;
    }
    if (depth - null_depth >= PLY)
      value =
          -Search(tree, -beta, 1 - beta, Flip(wtm), depth - null_depth, ply + 1,
          NO_NULL);
    else
      value = -QuiesceChecks(tree, -beta, 1 - beta, Flip(wtm), ply + 1);
    HashKey = save_hash_key;
    if (abort_search || tree->stop)
      return (0);
    if (value >= beta) {
      HashStore(tree, ply, depth, wtm, LOWER, value, mate_threat);
      return (value);
    }
    if (value == -MATE + ply + 2)
      mate_threat = 1;
  }
If your code matches that, you copied it. There are hundreds of ways to express the above idea using different implementation details... Again, we are not talking single lines, but single blocks.


how are we going to get a suitable value back from Search() without telling it to take 2 of the search depth?
not all of us take 2 off. And in fact, most take 3 which is 2 plies less deep than a normal search which uses depth-1. So many details makes duplicate code _highly_ improbable.


Some things just are as they are.[/quote]

yes. now if we can just agree on what they are, and are not. And simple is what they are not.
chrisw

Re: setjmp() - another one

Post by chrisw »

bob wrote:
chrisw wrote:
bob wrote:
Uri Blass wrote:
Guetti wrote:
chrisw wrote:Bob argued that the existence in the Rybka code of setjmp() was "interesting" because this also existed in Fruit and nowhere else.

Uri pointed out that Tom Kerrigan's public program TSCP also used setjmp() and that some other programs were likely/possibly developed, legally, off TSCP as basis.

I'm an engine programmer and always had user interface programmers working in support, so I got very lazy and understand very little about DOS, windows, C support functions and so on. setjmp() knowledge is no way a speciality of mine.

However, casting my mind back many years, I'm fairly sure that the Ren Wu Chess program which was also worked on by Ren at Oxford Softworks used setjmp() to unwind the search on a timeout. CSTal, by contrast, did a proper search unwind.

There are two ways to exit Search() on a timeout or user intervention. The 'correct' way, I suppose, is to unwind the Search back to the start using unmove simultaneously unstacking the variables.
The brutal and simple way is simply to jump straight out, reseting the stack pointer. I guess this is setjmp().

I'l be very surprised if numbers of programs, especially those designed years ago without SMP in mind, didn't use the brutal setjmp() technique to break the search.

Bottom line: setjmp() is not unique and its use doesn't imply anything, certainly it cannot imply copied code.
Leaving the setjmp() relevant or not argument aside for a moment, come on, you state that you believe that an engine used setjmp()? Isn't that a bit vague? You demand always hard facts and source and pretty aligned code from Zach and Christoph, so were are the facts of Ren Wu chess?
Would you believe Zach if he would write he believes that the eval of Rybka is identical to Fruit without further comment?
You always want to see facts, so please before you do a conclusion, gives us some facts.

When I look at the (far from complete) list of chess engines released in recent years at http://wbec-ridderkerk.nl/html/enginesindex.htm, I wonder how many of these engines use setjmp()? 10 of 200? More?
I think it is still a good indication, not a prove.
I do not know but movei used setjmp() at the beginning like tscp
and I simply learned from the code of tscp.

I got rid of setjmp later because I read people said it is not good
so it is not clear how many engines use setjmp.
old movei use it
new movei does not use it and you can download both old movei and new movei from wbec site.

Uri
So, you copied TSCP, which uses setjmp(). And then discovered it is a bad programming solution and removed it. Good. But notice where you got it from. That is the point of this minor side-issue. It is just another indication that perhaps something was copied, because good programmers do not use it for _many_ reasons. Perhaps Fruit started life as TSCP as well, who knows? But if programs that are suspected of being connected by common source, share a particular feature that is known to be bad programming, it is just another hint that things might have been copied...

I never claimed it to be the ultimate proof. I simply said it was another suspicious detail because it is such a lousy way of writing a program.
Ahem. Copied? I would prefer "used the idea". And if it's one line of code, there's not much else he can do, is there?
It is not "one line of code" it is an approach to unwind the search that requires actions in other parts of the program in order for it to work properly. Also he said "I don't understand how it works" so how can one copy an idea they don't understand? :)


What if someone reads Crafty use of null move? The call is one line

value = -Search(ply-2); basically
Basically? here's real code:

Code: Select all

 pieces = (wtm) ? TotalPieces(white, occupied) : TotalPieces(black, occupied);
  if (do_null && !tree->inchk[ply] && pieces && (pieces > 9 || depth < 7 * PLY)) {
    register BITBOARD save_hash_key;
    int null_depth;

    tree->curmv[ply] = 0;
    tree->phase[ply] = NULL_MOVE;
#if defined(TRACE)
    if (ply <= trace_level)
      Trace(tree, ply, depth, wtm, beta - 1, beta, "Search1", 0);
#endif
    null_depth = (depth > 6 * PLY && pieces > 9) ? null_max : null_min;
    tree->position[ply + 1] = tree->position[ply];
    Rule50Moves(ply + 1) = 0;
    save_hash_key = HashKey;
    if (EnPassant(ply)) {
      HashEP(EnPassant(ply + 1), HashKey);
      EnPassant(ply + 1) = 0;
    }
    if (depth - null_depth >= PLY)
      value =
          -Search(tree, -beta, 1 - beta, Flip(wtm), depth - null_depth, ply + 1,
          NO_NULL);
    else
      value = -QuiesceChecks(tree, -beta, 1 - beta, Flip(wtm), ply + 1);
    HashKey = save_hash_key;
    if (abort_search || tree->stop)
      return (0);
    if (value >= beta) {
      HashStore(tree, ply, depth, wtm, LOWER, value, mate_threat);
      return (value);
    }
    if (value == -MATE + ply + 2)
      mate_threat = 1;
  }
If your code matches that, you copied it. There are hundreds of ways to express the above idea using different implementation details... Again, we are not talking single lines, but single blocks.


how are we going to get a suitable value back from Search() without telling it to take 2 of the search depth?
not all of us take 2 off. And in fact, most take 3 which is 2 plies less deep than a normal search which uses depth-1. So many details makes duplicate code _highly_ improbable.


Some things just are as they are.
yes. now if we can just agree on what they are, and are not. And simple is what they are not.[/quote]

Most of the code is housekeeping. The key bit is:

if (depth - null_depth >= PLY)
value =
-Search(tree, -beta, 1 - beta, Flip(wtm), depth - null_depth, ply + 1,
NO_NULL);
else
value = -QuiesceChecks(tree, -beta, 1 - beta, Flip(wtm), ply + 1);

There's not many ways to encode

"If we're not at the leaf nodes, do a null move search else quiesce"

I'ld do something like this

if (depth - nulldepth >= PLY)
{
value = -Search(ply-2, blah blah other parameters);
}
else
{
value = -Quiesce(blah blah parameters);
}

It looks suspiciciously like your code, but what choice do I have?

I guess if I wanted to hide things badly, I could fiddle with the if expression, swap the braced stuff round by negation and so on. But, basically, that's how it gets done.