Fruit 2.1 vs Strelka 2.0

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

Moderators: hgm, Rebel, chrisw

kranium
Posts: 2129
Joined: Thu May 29, 2008 10:43 am

Fruit 2.1 vs Strelka 2.0

Post by kranium »

FRUIT:
static void parse_setoption( char string [])
{
const char *name;
char* value;

name = strstr(string, "name ");
value = strstr(string, "value ");
if (name == NULL || value == NULL || name >= value)return;
value[-1] = '\0';
name += 5;
value += 6;

STRELKA:
void parse_setoption(char string[])
{
char *name, *value;
int size;

name = strstr(string,"name ");
value = strstr(string,"value ");
if (name == NULL || value == NULL || name >= value) return;
value[-1] = 0;
name += 5;
value += 6;

---------------------------------------------------------------
FRUIT:
bool input_available()
{
static bool init = false, is_pipe;
static HANDLE stdin_h;
DWORD val, error;

if (stdin->_cnt > 0) return true;

if (!init)
{
init = true;
stdin_h = GetStdHandle(STD_INPUT_HANDLE);
is_pipe = !GetConsoleMode(stdin_h, &val);

if (!is_pipe)
{
SetConsoleMode(stdin_h, val & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
FlushConsoleInputBuffer(stdin_h);
}
}

if (is_pipe)
{
if (!PeekNamedPipe(stdin_h, NULL, 0, NULL, &val, NULL))
return true;
return val > 0;
}
else
{
GetNumberOfConsoleInputEvents(stdin_h, &val);
return val > 1;
}
return false;
}

STRELKA:
int input_available()
{
static int init = 0, is_pipe;
static HANDLE stdin_h;
DWORD val;

if (stdin->_cnt > 0) return 1;

if (!init)
{
init = 1;
stdin_h = GetStdHandle(STD_INPUT_HANDLE);
is_pipe = !GetConsoleMode(stdin_h, &val);

if (!is_pipe)
{
SetConsoleMode(stdin_h, val & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
FlushConsoleInputBuffer(stdin_h);
}
}

if (is_pipe)
{
if (!PeekNamedPipe(stdin_h, NULL, 0, NULL, &val, NULL))
return 1;
return val > 0;
}
else
{
GetNumberOfConsoleInputEvents(stdin_h, &val);
return val > 1;
}
return 0;
}
---------------------------------------------------------------

FRUIT:
static void parse_position( char string [] )
{
const char *fen;
char* moves;
const char *ptr;
char move_string[256];
int move;
undo_t undo[1];
fen = strstr(string, "fen ");
moves = strstr(string, "moves ");
if (fen != NULL)
{
if (moves != NULL)
{
ASSERT(moves > fen);
moves[-1] = '\0'; // dirty, but so is UCI
}
board_from_fen(SearchInput->board, fen + 4);
}
else
{
board_from_fen(SearchInput->board, StartFen);
}
if (moves != NULL)
{
ptr = moves + 6;
while (*ptr != '\0')
{
move_string[0] = *ptr++;
move_string[1] = *ptr++;
move_string[2] = *ptr++;
move_string[3] = *ptr++;
if (*ptr == '\0' || *ptr == ' ')
{
move_string[4] = '\0';
}
else
{
move_string[4] = *ptr++;
move_string[5] = '\0';
}
move = move_from_string(move_string, SearchInput->board);
move_do(SearchInput->board, move, undo);

while (*ptr == ' ')
ptr++;
}
}
}

STRELKA:
void parse_position( char string [] )
{
const char *fen;
char *moves;
const char *ptr;
char move_string[256];
int move;
struct undo_t undo[1];

fen = strstr(string, "fen ");
moves = strstr(string, "moves ");

if (fen != NULL)
{
if (moves != NULL)
moves[-1] = 0; // Das ist UCI
board_from_fen(fen + 4);
}
else
board_from_fen(start_pos);

if (moves != NULL)
{
ptr = moves + 6;

while (*ptr != 0)
{
move_string[0] = *ptr++;
move_string[1] = *ptr++;
move_string[2] = *ptr++;
move_string[3] = *ptr++;

if (*ptr == 0 || *ptr == ' ')
move_string[4] = 0;
else
{
move_string[4] = *ptr++;
move_string[5] = 0;
}
move = move_from_string(move_string);
move_do(move, undo);

while (*ptr == ' ')
ptr++;
}
}
}
---------------------------------------------------------------

FRUIT:
static void parse_go( char string [] )
{
const char *ptr;
bool infinite, ponder;
int depth, mate, movestogo;
sint64 nodes;
double binc, btime, movetime, winc, wtime;
double time, inc;
double time_max, alloc;

infinite = false;
ponder = false;
depth = -1;
mate = -1;
movestogo = -1;
nodes = -1;
binc = -1.0;
btime = -1.0;
movetime = -1.0;
winc = -1.0;
wtime = -1.0;
ptr = strtok(string, " ");

for ( ptr = strtok(NULL, " "); ptr != NULL; ptr = strtok(NULL, " ") )
{
if (false)
{
}
else if (string_equal(ptr, "binc"))
{

ptr = strtok(NULL, " ");

if (ptr == NULL)
my_fatal("parse_go(): missing argument\n");

binc = double(atoi(ptr)) / 1000.0;
ASSERT(binc >= 0.0);
}
else if (string_equal(ptr, "btime"))
{

ptr = strtok(NULL, " ");

if (ptr == NULL)
my_fatal("parse_go(): missing argument\n");

btime = double(atoi(ptr)) / 1000.0;
ASSERT(btime >= 0.0);
}
else if (string_equal(ptr, "depth"))
{

ptr = strtok(NULL, " ");

if (ptr == NULL)
my_fatal("parse_go(): missing argument\n");

depth = atoi(ptr);
ASSERT(depth >= 0);
}
else if (string_equal(ptr, "infinite"))
{

infinite = true;
}
else if (string_equal(ptr, "mate"))
{

ptr = strtok(NULL, " ");

if (ptr == NULL)
my_fatal("parse_go(): missing argument\n");

mate = atoi(ptr);
ASSERT(mate >= 0);
}
else if (string_equal(ptr, "movestogo"))
{

ptr = strtok(NULL, " ");

if (ptr == NULL)
my_fatal("parse_go(): missing argument\n");

movestogo = atoi(ptr);
ASSERT(movestogo >= 0);
}
else if (string_equal(ptr, "movetime"))
{

ptr = strtok(NULL, " ");

if (ptr == NULL)
my_fatal("parse_go(): missing argument\n");

movetime = double(atoi(ptr)) / 1000.0;
ASSERT(movetime >= 0.0);
}
else if (string_equal(ptr, "nodes"))
{

ptr = strtok(NULL, " ");

if (ptr == NULL)
my_fatal("parse_go(): missing argument\n");

nodes = my_atoll(ptr);
ASSERT(nodes >= 0);
}
else if (string_equal(ptr, "ponder"))
{

ponder = true;
}
else if (string_equal(ptr, "searchmoves"))
{
}
else if (string_equal(ptr, "winc"))
{

ptr = strtok(NULL, " ");

if (ptr == NULL)
my_fatal("parse_go(): missing argument\n");

winc = double(atoi(ptr)) / 1000.0;
ASSERT(winc >= 0.0);
}
else if (string_equal(ptr, "wtime"))
{

ptr = strtok(NULL, " ");

if (ptr == NULL)
my_fatal("parse_go(): missing argument\n");

wtime = double(atoi(ptr)) / 1000.0;
ASSERT(wtime >= 0.0);
}
}
search_clear();

if (depth >= 0)
{
SearchInput->depth_is_limited = true;
SearchInput->depth_limit = depth;
}
else if (mate >= 0)
{
SearchInput->depth_is_limited = true;
SearchInput->depth_limit = mate * 2 - 1;
}

if (COLOUR_IS_WHITE(SearchInput->board->turn))
{
time = wtime;
inc = winc;
}
else
{
time = btime;
inc = binc;
}

if (movestogo <= 0 || movestogo > 30)
movestogo = 30;

if (inc < 0.0)
inc = 0.0;

if (movetime >= 0.0)
{
SearchInput->time_is_limited = true;
SearchInput->time_limit_1 = movetime * 5.0;
SearchInput->time_limit_2 = movetime;
}
else if (time >= 0.0)
{
time_max = time * 0.95 - 1.0;

if (time_max < 0.0)
time_max = 0.0;

SearchInput->time_is_limited = true;

alloc = (time_max + inc * double(movestogo - 1)) / double(movestogo);
alloc *= (option_get_bool("Ponder") ? PonderRatio : NormalRatio);

if (alloc > time_max)
alloc = time_max;
SearchInput->time_limit_1 = alloc;

alloc = (time_max + inc * double(movestogo - 1)) * 0.5;

if (alloc < SearchInput->time_limit_1)
alloc = SearchInput->time_limit_1;

if (alloc > time_max)
alloc = time_max;
SearchInput->time_limit_2 = alloc;
}

if (infinite || ponder)
SearchInput->infinite = true;

Searching = true;
Infinite = infinite || ponder;
Delay = false;
search();
search_update_current();
Searching = false;
Delay = Infinite;

if (!Delay)
send_best_move();
}

STRELKA:
void start_go( char string [] )
{
const char *ptr;
int infinite, ponder;
int depth, mate, movestogo, zapas;
__int64 nodes;
int binc, btime, movetime, winc, wtime;
int time, inc, alloc;
struct board_t BoardSave[1];

infinite = 0;
ponder = 0;
depth = -1;
mate = -1;
movestogo = -1;
nodes = -1;
binc = -1;
btime = -1;
movetime = -1;
winc = -1;
wtime = -1;
ptr = strtok(string, " ");

for ( ptr = strtok(NULL, " "); ptr != NULL; ptr = strtok(NULL, " ") )
{
if (!strcmp(ptr, "binc"))
{
ptr = strtok(NULL, " ");
binc = atoi(ptr);
}
else if (!strcmp(ptr, "btime"))
{
ptr = strtok(NULL, " ");
btime = atoi(ptr);
}
else if (!strcmp(ptr, "depth"))
{
ptr = strtok(NULL, " ");
depth = atoi(ptr);
}
else if (!strcmp(ptr, "infinite"))
{
infinite = 1;
}
else if (!strcmp(ptr, "mate"))
{
ptr = strtok(NULL, " ");
mate = atoi(ptr);
}
else if (!strcmp(ptr, "movestogo"))
{
ptr = strtok(NULL, " ");
movestogo = atoi(ptr);
}
else if (!strcmp(ptr, "movetime"))
{
ptr = strtok(NULL, " ");
movetime = atoi(ptr);
}
else if (!strcmp(ptr, "nodes"))
{
ptr = strtok(NULL, " ");
sscanf(ptr, "%I64d", &nodes);
}
else if (!strcmp(ptr, "ponder"))
{
ponder = 1;
}
else if (!strcmp(ptr, "winc"))
{
ptr = strtok(NULL, " ");
winc = atoi(ptr);
}
else if (!strcmp(ptr, "wtime"))
{
ptr = strtok(NULL, " ");
wtime = atoi(ptr);
}
}

NS ->(the following 10 lines of code essentially do the same thing as Fruit’s search_clear function, i.e. initialize search vars to 0 or false)
_______________________________________
best_move = 0;
best_score = 0;
depth_score = 0;
check_nb = 1024;
start_time = GetTickCount();
can_stop = 0;
bad_1 = bad_2 = change = easy = flag = 0;
* pv_str = 0;
stop_search = 0;
depth_is_limited = time_is_limited = 0;
________________________________________

if (depth >= 0)
{
depth_is_limited = 1;
depth_limit = depth;
}
else if (mate >= 0)
{
depth_is_limited = 1;
depth_limit = mate * 2 - 1;
}

if ((Board->turn) == 0)
{
time = wtime;
inc = winc;
}
else
{
time = btime;
inc = binc;
}
zapas = 0;

if (movestogo <= 0)
movestogo = 30;

if (movestogo > 30)
{
movestogo = 30;
zapas = 1;
}
time_max = 100000;

if (inc < 0)
inc = 0;

if (movetime >= 0)
{
time_is_limited = 1;
time_max = movetime;
time_limit_1 = movetime * 5;
time_limit_2 = movetime;
}
else if (time >= 0)
{
time_is_limited = 1;

if (zapas)
time_max = ((time / 10) * 9) - 5000;
else
time_max = time - 2000;

if (time_max < 0)
time_max = 0;
alloc = (time_max + inc * (movestogo - 1)) / movestogo;

if (alloc > time_max)
alloc = time_max;
time_limit_1 = alloc;
alloc = (time_max + inc * (movestogo - 1)) / 2;

if (alloc < time_limit_1)
alloc = time_limit_1;

if (alloc > time_max)
alloc = time_max;
time_limit_2 = alloc;

}
Infinite = 0;

if (infinite || ponder)
Infinite = 1;

Searching = 1;
Delay = 0;
memcpy(BoardSave, Board, sizeof(struct board_t));
start_search();
memcpy(Board, BoardSave, sizeof(struct board_t));
search_time = GetTickCount() - start_time;

if (search_time < 0)
search_time = 0;
Searching = 0;
Delay = Infinite;

if (!Delay)
send_best_move();
}
---------------------------------------------------------------

FRUIT:
void trans_alloc( trans_t *trans )
{
uint32 size, target;
target = option_get_int("Hash");

if (target < 4) target = 16;
target *= 1024 * 1024;

for ( size = 1; size != 0 && size <= target; size *= 2 );
size /= 2;
size /= sizeof(entry_t);
trans->size = size + (ClusterSize - 1);
trans->mask = size - 1;
trans->table = (entry_t *)my_malloc(trans->size * sizeof(entry_t));
trans_clear(trans);
}

STRELKA:
void trans_alloc( int target )
{
int size;
target *= 1024 * 1024;

for ( size = 1; size != 0 && size <= target; size *= 2 );
size /= 2;
size /= sizeof(struct entry_t);
trans_size = size + (ClusterSize - 1);
trans_mask = size - 2;
trans_entry = (struct entry_t *)malloc(trans_size * sizeof(struct entry_t) + 64);
trans_clear();
}
---------------------------------------------------------------

FRUIT:
void trans_store( trans_t *trans, uint64 key, int move, int depth, int min_value, int max_value )
{

entry_t* entry, * best_entry;
int score, best_score;
int i;

trans->write_nb++;
best_entry = NULL;
best_score = -32767;

entry = trans_entry(trans, key);

for ( i = 0; i < ClusterSize; i++, entry++ )
{
if (entry->lock == KEY_LOCK(key))
{
trans->write_hit++;

if (entry->date != trans->date)
trans->used++;

entry->date = trans->date;

if (depth > entry->depth)
entry->depth = depth;

if (move != MoveNone && depth >= entry->move_depth)
{
entry->move_depth = depth;
entry->move = move;
}

if (min_value > -ValueInf && depth >= entry->min_depth)
{
entry->min_depth = depth;
entry->min_value = min_value;
}

if (max_value < +ValueInf && depth >= entry->max_depth)
{
entry->max_depth = depth;
entry->max_value = max_value;
}

return;
}

score = trans->age[entry->date] * 256 - entry->depth;

if (score > best_score)
{
best_entry = entry;
best_score = score;
}
}

entry = best_entry;

if (entry->date == trans->date)
{
trans->write_collision++;
}
else
{
trans->used++;
}

entry->lock = KEY_LOCK(key);
entry->date = trans->date;
entry->depth = depth;
entry->move_depth = (move != MoveNone) ? depth : DepthNone;
entry->move = move;
entry->min_depth = (min_value > -ValueInf) ? depth : DepthNone;
entry->max_depth = (max_value < +ValueInf) ? depth : DepthNone;
entry->min_value = min_value;
entry->max_value = max_value;
}

STRELKA:
void trans_store(unsigned __int16 move, char depth, __int16 value)

{
int i, score, best_score;
struct entry_t *entry;
struct entry_t *best_entry;

best_entry = NULL;
best_score = 0;
entry = trans_entry + (KEY_INDEX &trans_mask);

for ( i = 0; i < ClusterSize; i++, entry++ )
{
if (entry->lock == KEY_LOCK)
{
entry->date = (unsigned char)trans_date;

if (depth > entry->depth)
entry->depth = depth;

if (depth >= entry->move_depth)
{
entry->move_depth = depth;
entry->move = move;
}

if (depth >= entry->min_depth)
{
entry->min_depth = depth;
entry->min_value = value;
}

if (depth >= entry->max_depth)
{
entry->max_depth = depth;
entry->max_value = value;
}
return;
}
score = trans_score[entry->date] - (entry->depth);

if (score > best_score)
{
best_entry = entry;
best_score = score;
}
}

best_entry->lock = KEY_LOCK;
best_entry->date = (unsigned char)trans_date;
best_entry->depth = depth;
best_entry->move_depth = depth;
best_entry->move = move;
best_entry->min_depth = depth;
best_entry->min_value = value;
best_entry->max_depth = depth;
best_entry->max_value = value;
}
---------------------------------------------------------------

FRUIT:
static void loop_step()
{
char string[65536];
get(string, 65536);

if (false)
{
}
else if (string_start_with(string, "debug "))
{
}
else if (string_start_with(string, "go "))
{
if (!Searching && !Delay)
{
init();
parse_go(string);
}
}
else if (string_equal(string, "isready"))
{
if (!Searching && !Delay)
{
init();
}
send("readyok");
}
else if (string_equal(string, "ponderhit"))
{
if (Searching)
{
SearchInput->infinite = false;
Infinite = false;
}
else if (Delay)
{
send_best_move();
Delay = false;
}
}
else if (string_start_with(string, "position "))
{
if (!Searching && !Delay)
{
init();
parse_position(string);
}
}
else if (string_equal(string, "quit"))
{
exit(EXIT_SUCCESS);
}
else if (string_start_with(string, "setoption "))
{
if (!Searching && !Delay)
{
parse_setoption(string);
}
}
else if (string_equal(string, "stop"))
{
if (Searching)
{
SearchInfo->stop = true;
Infinite = false;
}
else if (Delay)
{
send_best_move();
Delay = false;
}
}
else if (string_equal(string, "uci"))
{
send("id name Fruit " VERSION);
send("id author Fabien Letouzey");
option_list();
send("uciok");
}
else if (string_equal(string, "ucinewgame"))
{
if (!Searching && !Delay && Init)
{
trans_clear(Trans);
}
else
{
}
}
}

STRELKA:
void get_uci_command()
{
char string[65536];
char *ptr;

(void)fgets(string, 65536, stdin);

if (feof(stdin))
exit(0);
ptr = strchr(string, '\n');

if (ptr != NULL)
* ptr = 0;

if (!strcmp(string, "uci"))
{
fprintf(stdout, "id name Strelka 2.0 B\n");
fprintf(stdout, "id author Jury Osipov\n");
fprintf(stdout, "option name Hash type spin default 32 min 4 max 1024\n");
fprintf(stdout, "option name MultiPV type spin default 1 min 1 max 100\n");
fprintf(stdout, "uciok\n");
}
else if (!strcmp(string, "ucinewgame"))
{
if (!Searching && !Delay)
trans_clear();
}
else if (!strcmp(string, "isready"))
{
fprintf(stdout, "readyok\n");
}
else if (!strcmp(string, "ponderhit"))
{
if (Searching)
Infinite = 0;
else if (Delay)
{
send_best_move();
Delay = 0;
}
}
else if (!memcmp(string, "position", 8))
{
if (!Searching && !Delay)
parse_position(string);
}
else if (!memcmp(string, "setoption", 9))
{
if (!Searching && !Delay)
parse_setoption(string);
}
else if (!memcmp(string, "go", 2))
{
if (!Searching && !Delay)
start_go(string);
}
else if (!strcmp(string, "stop"))
{
if (Searching)
{
stop_search = 1;
Infinite = 0;
}
else if (Delay)
{
send_best_move();
Delay = 0;
}
}

else if (!strcmp(string, "quit"))
exit(0);
#ifdef TEST_VER

else if (!memcmp(string, "epd", 3))
run_epd_test(string);

else if (!memcmp(string, "pgn", 3))
run_pgn_test(string);

#endif
}

---------------------------------------------------------------

Please note:
both sets of code have been formatted with polystyle for regularity and clarity
ASSERTs have been removed
lines (and blank lines) have been aligned for easy content comparison
all comments removed except for the translation of Fabien's
// dirty, but so is UCI
to
// Das ist UCI
(which is really odd considering Jury is Russian?)

My sincere esitmate is that at least 40-50% of the codebase is extremely similar or exact, with the rest of Strelka's code being a well done bitboard implementation utilizing standard inlined assembly language routines (like first_one, last_one, etc.), various bitmasks, popcnt, etc.

It's clear that a very significant and major effort was required to create this bitboard backend, and integrate it with so much of what appears to be Fruit source code. It's would be no trivial task indeed.

This has nothing to do with it, but from my limited testing (100 games) it appears that Strelka 2.0 is very strong: probably ~+100 ELO better than toga14beta5c, but more games need to be played.

Norm
IWB
Posts: 1539
Joined: Thu Mar 09, 2006 2:02 pm

Re: Fruit 2.1 vs Strelka 2.0

Post by IWB »

Hello
kranium wrote:This has nothing to do with it, but from my limited testing (100 games) it appears that Strelka 2.0 is very strong: porbably ~+100 ELO better than toga14beta5c.

Norm
Just because you mentioned it:

Strelka 2.0 B x64 ___ : 2599 16 16 1000 52.8 % 2580 43.5 %
Toga II 1.4 beta5c BB : 2576 12 12 2000 46.5 % 2601 40.4 %

This is out of my single threaded "ponder on" list.

23 Elo while the error margin is overlapping. My best gues is, yes Strelka is slightly better overall.

Bye
Ingo
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Fruit 2.1 vs Strelka 2.0

Post by Uri Blass »

I disagree about the 40-50% and it may be something like 10-20%

No similiarity in the move generator that is a significant part of strelka.
No extremely similiar code in the evaluation function that is also important part(there may be similiar ideas about evaluation but not similiar code and strelka has special code for material imbalance tables).

I do not understand how do you get at least 40-50% similiarity.

The functions that you post are clearly less than half of the code of strelka.

Uri
kranium
Posts: 2129
Joined: Thu May 29, 2008 10:43 am

Re: Fruit 2.1 vs Strelka 2.0

Post by kranium »

IWB wrote:Hello
kranium wrote:This has nothing to do with it, but from my limited testing (100 games) it appears that Strelka 2.0 is very strong: porbably ~+100 ELO better than toga14beta5c.

Norm
Just because you mentioned it:

Strelka 2.0 B x64 ___ : 2599 16 16 1000 52.8 % 2580 43.5 %
Toga II 1.4 beta5c BB : 2576 12 12 2000 46.5 % 2601 40.4 %

This is out of my single threaded "ponder on" list.

23 Elo while the error margin is overlapping. My best gues is, yes Strelka is slightly better overall.

Bye
Ingo
you're probably right Ingo...those 100 games were played at a rather fast time control (40/4) and certainly may not be accurate. i was however impressed that it finished so far ahead of Toga, i think it ended +92. What time control were your tests run at?
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Fruit 2.1 vs Strelka 2.0

Post by Uri Blass »

IWB wrote:Hello
kranium wrote:This has nothing to do with it, but from my limited testing (100 games) it appears that Strelka 2.0 is very strong: porbably ~+100 ELO better than toga14beta5c.

Norm
Just because you mentioned it:

Strelka 2.0 B x64 ___ : 2599 16 16 1000 52.8 % 2580 43.5 %
Toga II 1.4 beta5c BB : 2576 12 12 2000 46.5 % 2601 40.4 %

This is out of my single threaded "ponder on" list.

23 Elo while the error margin is overlapping. My best gues is, yes Strelka is slightly better overall.

Bye
Ingo
I remember reading that strelka has ponder bug and the gap is bigger with ponder on.

Uri
Uri Blass
Posts: 10282
Joined: Thu Mar 09, 2006 12:37 am
Location: Tel-Aviv Israel

Re: Fruit 2.1 vs Strelka 2.0

Post by Uri Blass »

kranium wrote:
IWB wrote:Hello
kranium wrote:This has nothing to do with it, but from my limited testing (100 games) it appears that Strelka 2.0 is very strong: porbably ~+100 ELO better than toga14beta5c.

Norm
Just because you mentioned it:

Strelka 2.0 B x64 ___ : 2599 16 16 1000 52.8 % 2580 43.5 %
Toga II 1.4 beta5c BB : 2576 12 12 2000 46.5 % 2601 40.4 %

This is out of my single threaded "ponder on" list.

23 Elo while the error margin is overlapping. My best gues is, yes Strelka is slightly better overall.

Bye
Ingo
you're probably right Ingo...those 100 games were played at a rather fast time control (40/4) and certainly may not be accurate. i was however impressed that it finished so far ahead of Toga, i think it ended +92. What time control were your tests run at?
CCRL already tested 40/4 with ponder off

http://computerchess.org.uk/ccrl/404/ra ... t_all.html

Strelka 2.0 B 32-bit 2977 +43 &#8722;41 78.2% &#8722;215.7 22.6% 248
Strelka 2.0 B 64-bit 2960 +28 &#8722;28 53.6% &#8722;24.2 44.3% 384
Toga II 1.4 beta5c 2CPU 2939 +29 &#8722;29 45.4% +29.9 42.7% 370
Toga II 1.4 beta5c 2923 +21 &#8722;21 50.9% &#8722;6.7 38.4% 700
gerold
Posts: 10121
Joined: Thu Mar 09, 2006 12:57 am
Location: van buren,missouri

Re: Fruit 2.1 vs Strelka 2.0

Post by gerold »

Toga 4.5c-2cpu 87/151. 55-32-64
Strelka 2_0 64/151. 32-55-64

Ponder off.

Maybe 1000 games will show diff.results.

Gerold.
IWB
Posts: 1539
Joined: Thu Mar 09, 2006 2:02 pm

Re: Fruit 2.1 vs Strelka 2.0

Post by IWB »

kranium wrote:
IWB wrote:Hello
kranium wrote:This has nothing to do with it, but from my limited testing (100 games) it appears that Strelka 2.0 is very strong: porbably ~+100 ELO better than toga14beta5c.

Norm
Just because you mentioned it:

Strelka 2.0 B x64 ___ : 2599 16 16 1000 52.8 % 2580 43.5 %
Toga II 1.4 beta5c BB : 2576 12 12 2000 46.5 % 2601 40.4 %

This is out of my single threaded "ponder on" list.

23 Elo while the error margin is overlapping. My best gues is, yes Strelka is slightly better overall.

Bye
Ingo
you're probably right Ingo...those 100 games were played at a rather fast time control (40/4) and certainly may not be accurate. i was however impressed that it finished so far ahead of Toga, i think it ended +92. What time control were your tests run at?
Hi

6 + 3 Ponder on. That averages to 16min per game. If Uri is right and there is a ponder bug (I havent noticed anything) it is of course something different.

BYe
Ingo
IWB
Posts: 1539
Joined: Thu Mar 09, 2006 2:02 pm

Re: Fruit 2.1 vs Strelka 2.0

Post by IWB »

Uri Blass wrote:

Strelka 2.0 B x64 ___ : 2599 16 16 1000 52.8 % 2580 43.5 %
Toga II 1.4 beta5c BB : 2576 12 12 2000 46.5 % 2601 40.4 %


CCRL already tested 40/4 with ponder off

http://computerchess.org.uk/ccrl/404/ra ... t_all.html

Strelka 2.0 B 32-bit 2977 +43 &#8722;41 78.2% &#8722;215.7 22.6% 248
Strelka 2.0 B 64-bit 2960 +28 &#8722;28 53.6% &#8722;24.2 44.3% 384
Toga II 1.4 beta5c 2923 +21 &#8722;21 50.9% &#8722;6.7 38.4% 700
even here with ponder off it is just max 54 Elo. (With a way lower number of games and I guess less opponents and this inconsitancy of having the 64bit engine below the 32 bit version - which is ... unusual)

All I wanted to say originaly is that Toga 1.4 is not 100 Elo weaker than Strelka - no big debate needed from my side here!

Bye
Ingo
kranium
Posts: 2129
Joined: Thu May 29, 2008 10:43 am

Re: Fruit 2.1 vs Strelka 2.0

Post by kranium »

Uri Blass wrote:I disagree about the 40-50% and it may be something like 10-20%

No similiarity in the move generator that is a significant part of strelka.
No extremely similiar code in the evaluation function that is also important part(there may be similiar ideas about evaluation but not similiar code and strelka has special code for material imbalance tables).

I do not understand how do you get at least 40-50% similiarity.

The functions that you post are clearly less than half of the code of strelka.

Uri
Hi Uri-

you have a point, i have not scientifically measured the percentage in any way shape or form, it was just my estimate. at the same time, i did not post everything. there's quite a bit more...it's clear that the total is a large and substantial amount.

move generators exist in every chess program...i don't think it is any more important in Strelka than any other program.

as I said, many of the non-similar functions are a bitboard implementation, but truly, if you follow them closely, i believe there is a close resemblance to the flow and logic of Fruit.

Norm