Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

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

Moderators: hgm, Rebel, chrisw

Milos
Posts: 4190
Joined: Wed Nov 25, 2009 1:47 am

Re: Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

Post by Milos »

F. Bluemers wrote: Ah,yes the Ipp "Programmer" didn't understand his "own" code.
Makes sense
:lol:
No you didn't understand it. And you are bragging with your ignorance. How pathetic...
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

Post by bob »

michiguel wrote:
bob wrote:
Milos wrote:
bob wrote:Since you keep jumping in, you can't use ignorance as an excuse for making these kinds of mistakes. You do know the difference between "variable names" and "language". In any language, the variable name "pawn_score_1" would be considered odd because it is a long name with no implied semantic as to what it represents. This has been discussed at length. Vas commented on this very issue a couple of years back. There are lots of examples in the code.
There is no pawn_score_1 in Ippo code, you just made that up, probably intentionally citing something wrongly so that it can't be checked in the code.
What is missing in the code are names for the constants. But this is for the obvious preprocessing reason. But again this has absolutely nothing to do with "unreasonable variable names".
So, I am still waiting for you to show some of the verifiable (and not invented by you) "unreasonable variable names".
I thought most would "get the idea" from "pawn_score_1". But since you are a bit thick, this from the sources of ippolit, file name IPP_ENG.c

how about "murderer_1, murderer_2,

In other places, nonsense like this:

score -= (((0) << 16) + (3));

or this:

white_king_distance = (((((white_king_square > b) ? 3 : 6) * (((((b) >> 3) - ((white_king_square) >> 3)) >= 0) ? (((b) >> 3) - ((white_king_square) >> 3)) : -(((b) >> 3) - ((white_king_square) >> 3)))) >= (6 * (((((b) & 7) - ((white_king_square) & 7)) >= 0) ? (((b) & 7) - ((white_king_square) & 7)) : -(((b) & 7) - ((white_king_square) & 7))))) ? (((white_king_square > b) ? 3 : 6) * (((((b) >> 3) - ((white_king_square) >> 3)) >= 0) ? (((b) >> 3) - ((white_king_square) >> 3)) : -(((b) >> 3) - ((white_king_square) >> 3)))) : (6 * (((((b) & 7) - ((white_king_square) & 7)) >= 0) ? (((b) & 7) - ((white_king_square) & 7)) : -(((b) & 7) - ((white_king_square) & 7)))));

which is what happens when several consecutive assignments get collapsed by the optimizer to eliminate the unneeded temp variables we often use to make the code readable.

or this:

score += ((((((black_king_square > b + 8) ? 3 : 6) * (((((b + 8) >> 3) - ((black_king_square) >> 3)) >= 0) ? (((b + 8) >> 3) - ((black_king_square) >> 3)) : -(((b + 8) >> 3) - ((black_king_square) >> 3)))) >= (6 * (((((b + 8) & 7) - ((black_king_square) & 7)) >= 0) ? (((b + 8) & 7) - ((black_king_square) & 7)) : -(((b + 8) & 7) - ((black_king_square) & 7))))) ? (((black_king_square > b + 8) ? 3 : 6) * (((((b + 8) >> 3) - ((black_king_square) >> 3)) >= 0) ? (((b + 8) >> 3) - ((black_king_square) >> 3)) : -(((b + 8) >> 3) - ((black_king_square) >> 3)))) : (6 * (((((b + 8) & 7) - ((black_king_square) & 7)) >= 0) ? (((b + 8) & 7) - ((black_king_square) & 7)) : -(((b + 8) & 7) - ((black_king_square) & 7))))) * opponent_king_pawn_distancing[((b) >> 3)]);
score -= ((((((white_king_square > b + 8) ? 3 : 6) * (((((b + 8) >> 3) - ((white_king_square) >> 3)) >= 0) ? (((b + 8) >> 3) - ((white_king_square) >> 3)) : -(((b + 8) >> 3) - ((white_king_square) >> 3)))) >= (6 * (((((b + 8) & 7) - ((white_king_square) & 7)) >= 0) ? (((b + 8) & 7) - ((white_king_square) & 7)) : -(((b + 8) & 7) - ((white_king_square) & 7))))) ? (((white_king_square > b + 8) ? 3 : 6) * (((((b + 8) >> 3) - ((white_king_square) >> 3)) >= 0) ? (((b + 8) >> 3) - ((white_king_square) >> 3)) : -(((b + 8) >> 3) - ((white_king_square) >> 3)))) : (6 * (((((b + 8) & 7) - ((white_king_square) & 7)) >= 0) ? (((b + 8) & 7) - ((white_king_square) & 7)) : -(((b + 8) & 7) - ((white_king_square) & 7))))) * myself_king_pawn_distancing[((b) >> 3)]);

Does that look like something _ANY_ human would write? Almost looks like lisp from a distance...
These were the expansion of nested macros, as we discussed with Zach before (a non-recommended coding practice, BTW).
As I said, not something a human would write. A human might nest macros, but the original code won't look like that.

Miguel

In this version, I do not see the pawn_score_1, _2 and such that Vas pointed out. Perhaps that was in Robo rather than the original IP source with names translated to English. But there is a lot of this kind of stuff:

score += (((6) << 16) + (10));

Where 6 and 10 are middlegame/endgame score values. Most don't put the numeric constants in evaluation code, most use either #defines, or something similar, or else use regular variables so that the values can be changed by the user if he chooses.

The overall structure of this program bears resemblance to Crafty, in that everywhere in my code you see local variables accessed as tree->variable. In ip* (did it even have SMP to start with?) it has tower_dynamic->variable. Since Rybka started as Crafty, it is likely this overall structure was kept into Rybka 1 and 2. In fact, there are quite a few Craftyisms that lend more credibility to IP* coming from Rybka...

One thing is for sure, a programmer that writes a non-threaded program is not going to pass around a pointer to the local data, when it can be referenced as global data more efficiently. Crafty through version 14.x certainly did that, and the tree-> stuff was added in 15.0 to make the SMP code work.

Anyone that thinks this piece of trash is an original program written by a human has their head so far up their a$$ all they can see are esophagus and tonsils.

Of course, don't let any of those small facts interfere with your nonsensical discussion. Robo is a derivative. It isn't a perfect clone, because the SMP code from Rybka/Crafty was not copied. But the basic engine tells the story, if one is willing to read...

IP* was _not_ 50 elo stronger than Rybka. In fact, it crashed often enough that it was weaker. As the bugs were fixed, it gained. But it had more bugs than Carter has little pills. I quickly gave up trying to use it on the cluster because it was crashing and losing enough games on time that it skewed the results... and left hundreds of core files lying around on top of that...
Ippo was (and still is) 50 Elo stronger than Rybka 3. I am very well aware of all the code changes from original Ippo version all the way to early Ivanhoe versions. As a matter of fact I know the Ippo code way better than you and probably 90% of the programmers on this forum.
I doubt you know _anything_ better than 90% of the programmers on this forum. Certainly not ip*. Or you would know it for what it is.
The number of show-stopper bugs in Ippo was really small. Less than 5, to be precise. Having such a strong code with so few show-stopper bugs is simply impossible by only decompilation.
Ah, the voice of experience _again_??? First there were more than 5. Second, if you use a decompiler, the number of bugs would be expected to be _zero_. If you decompile, then try to edit the source to make it look _somewhat_ natural looking, then you introduce bugs... But the code is not naturally written, and nobody on the planet that has worked with assembly language, and compilers, will tell you differently...
However, you are as always free to believe what you want even though you have no support at all in facts.
I actually have far more facts supporting my opinion than you have supporting yours. you have none, in fact. Or at least you have offered none to date...
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

Post by bob »

Milos wrote:
bob wrote:I thought most would "get the idea" from "pawn_score_1".
The only idea that they can get that you are not able to express yourself in a precise and concise manner (or in the worst case that you are lying).
how about "murderer_1, murderer_2,
You call this KILLER_MOVE_1, KILLER_MOVE_2 in Crafty, you really think your name is more reasonable when translated to Russian?
Eh? I use killers[2] in Crafty.

In other places, nonsense like this:

score -= (((0) << 16) + (3));

or this:

white_king_distance = (((((white_king_square > b) ? 3 : 6) * (((((b) >> 3) - ((white_king_square) >> 3)) >= 0) ? (((b) >> 3) - ((white_king_square) >> 3)) : -(((b) >> 3) - ((white_king_square) >> 3)))) >= (6 * (((((b) & 7) - ((white_king_square) & 7)) >= 0) ? (((b) & 7) - ((white_king_square) & 7)) : -(((b) & 7) - ((white_king_square) & 7))))) ? (((white_king_square > b) ? 3 : 6) * (((((b) >> 3) - ((white_king_square) >> 3)) >= 0) ? (((b) >> 3) - ((white_king_square) >> 3)) : -(((b) >> 3) - ((white_king_square) >> 3)))) : (6 * (((((b) & 7) - ((white_king_square) & 7)) >= 0) ? (((b) & 7) - ((white_king_square) & 7)) : -(((b) & 7) - ((white_king_square) & 7)))));

which is what happens when several consecutive assignments get collapsed by the optimizer to eliminate the unneeded temp variables we often use to make the code readable.

or this:

score += ((((((black_king_square > b + 8) ? 3 : 6) * (((((b + 8) >> 3) - ((black_king_square) >> 3)) >= 0) ? (((b + 8) >> 3) - ((black_king_square) >> 3)) : -(((b + 8) >> 3) - ((black_king_square) >> 3)))) >= (6 * (((((b + 8) & 7) - ((black_king_square) & 7)) >= 0) ? (((b + 8) & 7) - ((black_king_square) & 7)) : -(((b + 8) & 7) - ((black_king_square) & 7))))) ? (((black_king_square > b + 8) ? 3 : 6) * (((((b + 8) >> 3) - ((black_king_square) >> 3)) >= 0) ? (((b + 8) >> 3) - ((black_king_square) >> 3)) : -(((b + 8) >> 3) - ((black_king_square) >> 3)))) : (6 * (((((b + 8) & 7) - ((black_king_square) & 7)) >= 0) ? (((b + 8) & 7) - ((black_king_square) & 7)) : -(((b + 8) & 7) - ((black_king_square) & 7))))) * opponent_king_pawn_distancing[((b) >> 3)]);
score -= ((((((white_king_square > b + 8) ? 3 : 6) * (((((b + 8) >> 3) - ((white_king_square) >> 3)) >= 0) ? (((b + 8) >> 3) - ((white_king_square) >> 3)) : -(((b + 8) >> 3) - ((white_king_square) >> 3)))) >= (6 * (((((b + 8) & 7) - ((white_king_square) & 7)) >= 0) ? (((b + 8) & 7) - ((white_king_square) & 7)) : -(((b + 8) & 7) - ((white_king_square) & 7))))) ? (((white_king_square > b + 8) ? 3 : 6) * (((((b + 8) >> 3) - ((white_king_square) >> 3)) >= 0) ? (((b + 8) >> 3) - ((white_king_square) >> 3)) : -(((b + 8) >> 3) - ((white_king_square) >> 3)))) : (6 * (((((b + 8) & 7) - ((white_king_square) & 7)) >= 0) ? (((b + 8) & 7) - ((white_king_square) & 7)) : -(((b + 8) & 7) - ((white_king_square) & 7))))) * myself_king_pawn_distancing[((b) >> 3)]);

Does that look like something _ANY_ human would write? Almost looks like lisp from a distance...
Again just and exclusively bunch of preprocessor expansions of macros which proves nothing except that the code is obfuscated. Not a single example of "unreasonable variable names".
So again you didn't provide any facts.
The overall structure of this program bears resemblance to Crafty, in that everywhere in my code you see local variables accessed as tree->variable. In ip* (did it even have SMP to start with?) it has tower_dynamic->variable. Since Rybka started as Crafty, it is likely this overall structure was kept into Rybka 1 and 2. In fact, there are quite a few Craftyisms that lend more credibility to IP* coming from Rybka...
Even more BS. Everything is Crafty. You ego is really larger than a Moon. If you even bothered to read Mark's paper you would not write so much crap.
How about a rational explanation of why one would pass a pointer around to a single copy of local data, rather than using simple global data? In a program that doesn't have a parallel search?

I have read Mark's paper. And soon enough, you will be able to read a lot more about what was copied from Crafty and used in even the earliest of the Rybka versions. And this was part of that code, btw...

One thing is for sure, a programmer that writes a non-threaded program is not going to pass around a pointer to the local data, when it can be referenced as global data more efficiently. Crafty through version 14.x certainly did that, and the tree-> stuff was added in 15.0 to make the SMP code work.
Passing out a pointer gives 3-5% slower code in case of Robbo. There was an extensive discussion about that multiple times in this forum and different ppl measured this. Don't believing it, doesn't make it less true.
I would believe 3-5% slower. Why do it when the program has no parallel search that needs that pointer? This is all crap. The program is a derived work. You only dig a deeper hole trying to wriggle out of that simple statement of fact...

Robo is a derivative. It isn't a perfect clone, because the SMP code from Rybka/Crafty was not copied. But the basic engine tells the story, if one is willing to read...
The first version of Robbo is functionally identical to Ippo (so technically it is a real clone). Only variable names are translated, code is divided into files and macros are not expanded as in Ippo. Again you have wrong facts...
No, just a typo. I meant IP*, although robo* is just as good. But you are still off your rocker. IP* and Robo* appear to come from Rybka. With some Craftyisms included that _are_ in Rybka, by the way...

Ah, the voice of experience _again_??? First there were more than 5.
No there were not. And it's simple to prove me wrong, just list more than 5 show-stopper bugs (that would make it crash in your tests) in Ippo.
I'm waiting...
I didn't take the time to debug a derivative program. Several different people sent me fixes to try on my cluster. Not a one produced a program that could play a few thousand games without crashing a hundred times or more.

I actually have far more facts supporting my opinion than you have supporting yours. you have none, in fact. Or at least you have offered none to date...
All your "facts" are wrong or refuted. I'm still waiting for a single correct one. And seams to me I'll wait forever...
Since you refuse to understand any, I suppose you will...

But if you think ip*/robo* are original programs, you are a sad example of any sort of computer person.
Milos
Posts: 4190
Joined: Wed Nov 25, 2009 1:47 am

Re: Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

Post by Milos »

bob wrote:
Milos wrote:
how about "murderer_1, murderer_2,
You call this KILLER_MOVE_1, KILLER_MOVE_2 in Crafty, you really think your name is more reasonable when translated to Russian?
Eh? I use killers[2] in Crafty.
Yup in this one you are right, murderer_1, murderer_2 is a struct member equivalent to your killers.move_1, killers.move_2 while murdrings_1 and murderings_2 are phase enums equivalent to yours KILLER_MOVE_1 and KILLER_MOVE_2 :).
Anyway a real direct translate from Russian to English.
How about a rational explanation of why one would pass a pointer around to a single copy of local data, rather than using simple global data? In a program that doesn't have a parallel search?
There was no pointer passing tree structure before Robbo 0.085f1a. All previous versions use no pointer at all. The tree structure is represented with position_fixed structure not "tower_dynamics". tower_dynamics represent just the local ply structure, not global tree. You do not have anything remotely close to this kind of structure in Crafty. So stop making it up.
I have read Mark's paper. And soon enough, you will be able to read a lot more about what was copied from Crafty and used in even the earliest of the Rybka versions. And this was part of that code, btw...
I was talking about Mark's paper regarding Ippo/Rybka similarities/differences not Rybka(Crafty)/Fruit differences. Mark does stress some of the Fruit like things in Ippo, and there are certainly a lot of them, but only in the sense that these remind him to Fruit or that these ideas existed in Fruit never anything even remotely close to "code from Fruit".
I would believe 3-5% slower. Why do it when the program has no parallel search that needs that pointer? This is all crap. The program is a derived work. You only dig a deeper hole trying to wriggle out of that simple statement of fact...
I'll repeat since you seams to not understand very well the Ippo structures. There is no pointer to global structure such as tree (which is represented with "position_fixed", so don't get confused, it is not only position data it is a global tree structure). There is only a global array (that's why global pointer) where each member contains a local ply data for each searched ply. This is what is represented with "tower_dynamics". This you have included into your tree structure. Here is totally separated. That's why claiming Ippo structure are even remotely close to Crafty's is just ridiculous.

But if you think ip*/robo* are original programs, you are a sad example of any sort of computer person.
No I do not think they are original at least not in a sense you define originality.
However, I do think they are original enough to pass in court for any kind of copyright claim about code copying from Rybka (or any other engine). Rybka was certainly reverse-engineered and every good idea is taken (plus a lot of other ideas from other places) but there is certainly no direct code copying and Ippo is not even remotely close to direct decompile of Rybka.
Roger Brown
Posts: 782
Joined: Wed Mar 08, 2006 9:22 pm

Re: Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

Post by Roger Brown »

Milos wrote:
No I do not think they are original at least not in a sense you define originality.
However, I do think they are original enough to pass in court for any kind of copyright claim about code copying from Rybka (or any other engine). Rybka was certainly reverse-engineered and every good idea is taken (plus a lot of other ideas from other places) but there is certainly no direct code copying and Ippo is not even remotely close to direct decompile of Rybka.


Hello Milos,

I am a bit at a loss for words.

You are asserting that Rybka was reverse engineered and every good idea taken.

Would you mind outlining what these were to a non-programmer such as myself?

I had thought that the defence was that reverse-engineering had not taken place. Your statements about what a court might or might not decide is another issue entirely.

So if Rybka was reverse-engineered and studied to the max, how exactly did they avoid using code from Rybka? I am asking as a lay person as Vas had asserted something similar in the case of Fruit (that it was only studied) only for it now to be revealed that perhaps more than ideas were taken.

Somewhat confused.....

Later.
Osipov Jury
Posts: 186
Joined: Mon Jan 21, 2008 2:07 pm
Location: Russia

Re: Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

Post by Osipov Jury »

Rybka = Crafty + Fruit + a lot of new ideas.
Ippolit = Fruit + Rybka + a lot of new ideas.
Stockfish = Glaurung + Ippolit + a lot of new ideas.
Houdini = Ippolit + Stockfish + a lot of new ideas.

For me, in these equations new ideas are more important than the origin.
I went through the Rybka code forwards and backwards and took many things.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

Post by Sven »

Osipov Jury wrote:Rybka = Crafty + Fruit + a lot of new ideas.
Ippolit = Fruit + Rybka + a lot of new ideas.
Stockfish = Glaurung + Ippolit + a lot of new ideas.
Houdini = Ippolit + Stockfish + a lot of new ideas.

For me, in these equations new ideas are more important than the origin.
So by expanding we get:

Code: Select all

Houdini   = 4*Fruit + 2*Crafty + 1*Glaurung + 6* a lot of new ideas
Stockfish = 2*Fruit + 1*Crafty + 1*Glaurung + 3* a lot of new ideas
That would somehow explain the current top of some rating lists :lol:

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

Re: Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

Post by bob »

Milos wrote:
bob wrote:
Milos wrote:
how about "murderer_1, murderer_2,
You call this KILLER_MOVE_1, KILLER_MOVE_2 in Crafty, you really think your name is more reasonable when translated to Russian?
Eh? I use killers[2] in Crafty.
Yup in this one you are right, murderer_1, murderer_2 is a struct member equivalent to your killers.move_1, killers.move_2 while murdrings_1 and murderings_2 are phase enums equivalent to yours KILLER_MOVE_1 and KILLER_MOVE_2 :).
Anyway a real direct translate from Russian to English.
How about a rational explanation of why one would pass a pointer around to a single copy of local data, rather than using simple global data? In a program that doesn't have a parallel search?
There was no pointer passing tree structure before Robbo 0.085f1a. All previous versions use no pointer at all. The tree structure is represented with position_fixed structure not "tower_dynamics". tower_dynamics represent just the local ply structure, not global tree. You do not have anything remotely close to this kind of structure in Crafty. So stop making it up.
I have read Mark's paper. And soon enough, you will be able to read a lot more about what was copied from Crafty and used in even the earliest of the Rybka versions. And this was part of that code, btw...
I was talking about Mark's paper regarding Ippo/Rybka similarities/differences not Rybka(Crafty)/Fruit differences. Mark does stress some of the Fruit like things in Ippo, and there are certainly a lot of them, but only in the sense that these remind him to Fruit or that these ideas existed in Fruit never anything even remotely close to "code from Fruit".
I would believe 3-5% slower. Why do it when the program has no parallel search that needs that pointer? This is all crap. The program is a derived work. You only dig a deeper hole trying to wriggle out of that simple statement of fact...
I'll repeat since you seams to not understand very well the Ippo structures. There is no pointer to global structure such as tree (which is represented with "position_fixed", so don't get confused, it is not only position data it is a global tree structure). There is only a global array (that's why global pointer) where each member contains a local ply data for each searched ply. This is what is represented with "tower_dynamics". This you have included into your tree structure. Here is totally separated. That's why claiming Ippo structure are even remotely close to Crafty's is just ridiculous.

But if you think ip*/robo* are original programs, you are a sad example of any sort of computer person.
No I do not think they are original at least not in a sense you define originality.
However, I do think they are original enough to pass in court for any kind of copyright claim about code copying from Rybka (or any other engine). Rybka was certainly reverse-engineered and every good idea is taken (plus a lot of other ideas from other places) but there is certainly no direct code copying and Ippo is not even remotely close to direct decompile of Rybka.
Two notes.

(1) you are correct on tower_dynamics. Point to your side.

(2) you might want to compare some of the code in Crafty version 19.0, init.c, to code in ippolit. We know that code was in early Rybkas. You might be surprised to see what is in ippolit. It _might_ not be as original as you think.

Or, you might not want to look...

Just checking simple things like rotated bitboard mask initializations, the "square of the king" passed pawn race masks, etc. Just to get you started.
Dayffd
Posts: 424
Joined: Wed Sep 30, 2009 5:30 am

Re: Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

Post by Dayffd »

I believe it was Milos who wrote, "...Ippo was (and still is) 50 Elo stronger than Rybka 3. ...". Just going from my tournaments, Rybka 3 is close to being 200 stronger than Ip* at 2847, Rybka 3 at 3037. Of course these ratings are subject to change. I do not like having Ip* participate too often since it crashes at least once, sometimes twice in every tournament, where each engine plays 14 games (2 games vs 7 opponents) with a time control of each engine having 30 minutes for each game.
David S.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Houdini, Fire, IvanHoe, (and Rybka?) are 'clones'...?

Post by bob »

Dayffd wrote:I believe it was Milos who wrote, "...Ippo was (and still is) 50 Elo stronger than Rybka 3. ...". Just going from my tournaments, Rybka 3 is close to being 200 stronger than Ip* at 2847, Rybka 3 at 3037. Of course these ratings are subject to change. I do not like having Ip* participate too often since it crashes at least once, sometimes twice in every tournament, where each engine plays 14 games (2 games vs 7 opponents) with a time control of each engine having 30 minutes for each game.
That was my finding as well, except that on my cluster I was playing thousands of games and was seeing hundreds of crashes. It was still very strong, even with those lost games (it flags when it crashes)...